/// <inheritdoc/> public override void Run(CommandLine commandLine) { var hiveLogin = Program.HiveLogin; Console.WriteLine(""); // Close all VPN connections even if we're not officially logged in. // // We're passing NULL to close all hive VPN connections to ensure that // we're only connected to one at a time. It's very possible for a operator // to have to manage multiple disconnnected hives that share the same // IP address space. HiveHelper.VpnClose(null); // Actually logout. if (hiveLogin == null) { return; // Not logged in. } Console.WriteLine($"Logging out of [{hiveLogin.HiveName}]."); Console.WriteLine(""); CurrentHiveLogin.Delete(); }
/// <inheritdoc/> public override void Run(CommandLine commandLine) { var current = CurrentHiveLogin.Load(); var logins = new List <LoginInfo>(); foreach (var file in Directory.EnumerateFiles(Program.HiveLoginFolder, "*.login.json", SearchOption.TopDirectoryOnly)) { try { var login = NeonHelper.JsonDeserialize <HiveLogin>(File.ReadAllText(file)); var useVpn = false; if (current != null && string.Equals(current.Login, login.LoginName, StringComparison.OrdinalIgnoreCase)) { useVpn = current.ViaVpn; } logins.Add(new LoginInfo(login, useVpn)); } catch (Exception e) { Console.Error.WriteLine($"*** ERROR: Cannot read [{file}]. Details: {NeonHelper.ExceptionError(e)}"); Program.Exit(1); } } Console.WriteLine(); if (logins.Count == 0) { Console.Error.WriteLine("*** No hive logins"); } else { var maxLoginNameWidth = logins.Max(l => l.Name.Length); foreach (var login in logins .OrderBy(c => c.Name.Split('@')[1].ToLowerInvariant()) .ThenBy(c => c.Name.Split('@')[0].ToLowerInvariant())) { if (current != null && string.Equals(current.Login, login.Name, StringComparison.OrdinalIgnoreCase)) { Console.Write(" --> "); } else { Console.Write(" "); } var padding = new string(' ', maxLoginNameWidth - login.Name.Length); Console.Write($"{login.Name}{padding} {login.Info}"); Console.WriteLine(); } } }
/// <inheritdoc/> public override void Run(CommandLine commandLine) { HiveProxy hiveProxy; if (commandLine.HasHelpOption || commandLine.Arguments.Length == 0) { Console.WriteLine(usage); Program.Exit(0); } Console.Error.WriteLine(); var hiveLogin = Program.HiveLogin; var login = HiveHelper.SplitLogin(commandLine.Arguments[0]); if (!login.IsOK) { Console.Error.WriteLine($"*** ERROR: Invalid username/hive [{commandLine.Arguments[0]}]. Expected something like: USER@HIVE"); Program.Exit(1); } // Check whether we're already logged into the hive. var username = login.Username; var hiveName = login.HiveName; if (hiveLogin != null && string.Equals(hiveLogin.HiveName, hiveName, StringComparison.OrdinalIgnoreCase) && string.Equals(hiveLogin.Username, username, StringComparison.OrdinalIgnoreCase)) { // Ensure that the client is compatible with the hive. try { HiveHelper.ValidateClientVersion(hiveLogin, Program.Version); } catch (VersionException e) { HiveHelper.VpnClose(null); CurrentHiveLogin.Delete(); Console.Error.WriteLine($"*** ERROR: {e.Message}"); Program.Exit(0); } // Ensure that the hive's certificates, hostnames,... are properly initialized. HiveHelper.OpenHive(hiveLogin); Console.Error.WriteLine($"*** You are already logged into [{Program.HiveLogin.Username}@{Program.HiveLogin.HiveName}]."); Program.Exit(0); } // Logout of the current hive. if (hiveLogin != null) { Console.Error.WriteLine($"Logging out of [{Program.HiveLogin.Username}@{Program.HiveLogin.HiveName}]."); CurrentHiveLogin.Delete(); } // We're passing NULL to close all hive VPN connections to ensure that // we're only connected to one at a time. It's very possible for a operator // to have to manage multiple disconnnected hives that share the same // IP address space. HiveHelper.VpnClose(null); // Fetch the new hive login. var hiveLoginPath = Program.GetHiveLoginPath(username, hiveName); if (!File.Exists(hiveLoginPath)) { Console.Error.WriteLine($"*** ERROR: Cannot find login [{username}@{hiveName}]."); Program.Exit(1); } hiveLogin = NeonHelper.JsonDeserialize <HiveLogin>(File.ReadAllText(hiveLoginPath)); // Determine whether we're going to use the VPN. var useVpn = false; var showVpn = commandLine.HasOption("--show-vpn"); if (hiveLogin.Definition.Hosting.IsOnPremiseProvider) { if (hiveLogin.Definition.Vpn.Enabled) { if (!commandLine.HasOption("--no-vpn")) { if (!hiveLogin.Definition.Vpn.Enabled) { Console.Error.WriteLine($"*** ERROR: Hive [{hiveLogin.HiveName}] was not provisioned with a VPN."); Program.Exit(1); } useVpn = true; } else { useVpn = false; Console.Error.WriteLine("Using the local network (not the VPN)"); } } else { useVpn = false; } } else { useVpn = true; // Always TRUE for cloud environments. } // Connect the VPN if enabled. if (useVpn) { HiveHelper.VpnOpen(hiveLogin, onStatus: message => Console.Error.WriteLine($"{message}"), onError: message => Console.Error.WriteLine($"*** ERROR {message}"), show: showVpn); } // Verify the credentials by logging into a manager node. Console.Error.WriteLine("Authenticating..."); hiveProxy = new HiveProxy(hiveLogin, (nodeName, publicAddress, privateAddress, append) => { return(new SshProxy <NodeDefinition>(nodeName, publicAddress, privateAddress, hiveLogin.GetSshCredentials(), TextWriter.Null)); }); var viaVpn = useVpn ? $" (via VPN)" : string.Empty; try { hiveProxy.GetReachableManager().Connect(); var currentLogin = new CurrentHiveLogin() { Login = hiveLogin.LoginName, ViaVpn = useVpn }; currentLogin.Save(); // Call GetLogin() with the client version so that the current hive // definition will be downloaded and so we'll also verify that the // current client is capable of managing the hive. try { HiveHelper.GetLogin(clientVersion: Program.Version); } catch (VersionException e) { HiveHelper.VpnClose(null); CurrentHiveLogin.Delete(); Console.Error.WriteLine($"*** ERROR: {e.Message}"); Program.Exit(1); } // Ensure that the hive's certificates, hostnames,... are properly initialized. HiveHelper.OpenHive(hiveLogin); Console.Error.WriteLine($"Logged into [{hiveLogin.LoginName}]{viaVpn}."); Console.Error.WriteLine(""); } catch (Exception e) { Console.Error.WriteLine($"*** ERROR: Hive login failed{viaVpn}: {NeonHelper.ExceptionError(e)}"); Console.Error.WriteLine(""); // Delete the current login because it failed. CurrentHiveLogin.Delete(); Program.Exit(1); } }
/// <inheritdoc/> public override void Run(CommandLine commandLine) { if (commandLine.Arguments.Length < 1) { Console.Error.WriteLine("*** ERROR: USER@HIVE is required."); Program.Exit(1); } var login = HiveHelper.SplitLogin(commandLine.Arguments[0]); if (!login.IsOK) { Console.Error.WriteLine($"*** ERROR: Invalid username/hive [{commandLine.Arguments[0]}]. Expected something like: USER@HIVE"); Program.Exit(1); } var username = login.Username; var hiveName = login.HiveName; var hiveLoginPath = Program.GetHiveLoginPath(username, hiveName); if (File.Exists(hiveLoginPath)) { if (!commandLine.HasOption("--force") && !Program.PromptYesNo($"*** Are you sure you want to remove the [{username}@{hiveName}] login?")) { return; } File.Delete(hiveLoginPath); // Delete the backup and cached hive definition files if present. var backupPath = hiveLoginPath + ".bak"; var definitionPath = HiveHelper.GetCachedDefinitionPath(username, hiveName); if (File.Exists(backupPath)) { File.Delete(backupPath); } if (File.Exists(definitionPath)) { File.Delete(definitionPath); } // Remove the [.current] file if this is the logged-in hive. if (Program.HiveLogin != null && string.Equals(Program.HiveLogin.Username, username, StringComparison.OrdinalIgnoreCase) && string.Equals(Program.HiveLogin.HiveName, hiveName, StringComparison.OrdinalIgnoreCase)) { CurrentHiveLogin.Delete(); HiveHelper.VpnClose(hiveName); } Console.WriteLine($"Removed [{username}@{hiveName}]"); } else { Console.Error.WriteLine($"*** ERROR: Login [{username}@{hiveName}] does not exist."); return; } }