Exemple #1
0
        /// <inheritdoc/>
        public override async Task RunAsync(CommandLine commandLine)
        {
            if (commandLine.Arguments.Length < 1)
            {
                Console.Error.WriteLine("*** ERROR: [root@CLUSTER-NAME] argument is required.");
                Program.Exit(1);
            }

            Console.WriteLine();

            // Cluster prepare/setup uses the [ProfileClient] to retrieve secrets and profile values.
            // We need to inject an implementation for [PreprocessReader] so it will be able to
            // perform the lookups.

            NeonHelper.ServiceContainer.AddSingleton <IProfileClient>(new ProfileClient());

            var contextName       = KubeContextName.Parse(commandLine.Arguments[0]);
            var kubeCluster       = KubeHelper.Config.GetCluster(contextName.Cluster);
            var unredacted        = commandLine.HasOption("--unredacted");
            var debug             = commandLine.HasOption("--debug");
            var check             = commandLine.HasOption("--check");
            var uploadCharts      = commandLine.HasOption("--upload-charts") || debug;
            var clusterspace      = commandLine.GetOption("--clusterspace");
            var maxParallelOption = commandLine.GetOption("--max-parallel", "6");
            var disablePending    = commandLine.HasOption("--disable-pending");

            if (!int.TryParse(maxParallelOption, out var maxParallel) || maxParallel <= 0)
            {
                Console.Error.WriteLine($"*** ERROR: [--max-parallel={maxParallelOption}] is not valid.");
                Program.Exit(1);
            }

            clusterLogin = KubeHelper.GetClusterLogin(contextName);

            if (clusterLogin == null)
            {
                Console.Error.WriteLine($"*** ERROR: Be sure to prepare the cluster first via: neon cluster prepare...");
                Program.Exit(1);
            }

            if (string.IsNullOrEmpty(clusterLogin.SshPassword))
            {
                Console.Error.WriteLine($"*** ERROR: No cluster node SSH password found.");
                Program.Exit(1);
            }

            if (kubeCluster != null && !clusterLogin.SetupDetails.SetupPending)
            {
                if (commandLine.GetOption("--force") == null && !Program.PromptYesNo($"One or more logins reference [{kubeCluster.Name}].  Do you wish to delete these?"))
                {
                    Program.Exit(0);
                }

                // Remove the cluster from the kubeconfig and remove any
                // contexts that reference it.

                KubeHelper.Config.Clusters.Remove(kubeCluster);

                var delList = new List <KubeConfigContext>();

                foreach (var context in KubeHelper.Config.Contexts)
                {
                    if (context.Properties.Cluster == kubeCluster.Name)
                    {
                        delList.Add(context);
                    }
                }

                foreach (var context in delList)
                {
                    KubeHelper.Config.Contexts.Remove(context);
                }

                if (KubeHelper.CurrentContext != null && KubeHelper.CurrentContext.Properties.Cluster == kubeCluster.Name)
                {
                    KubeHelper.Config.CurrentContext = null;
                }

                KubeHelper.Config.Save();
            }

            kubeContext = new KubeConfigContext(contextName);

            KubeHelper.InitContext(kubeContext);

            // Create and run the cluster setup controller.

            var clusterDefinition = clusterLogin.ClusterDefinition;

            var controller = KubeSetup.CreateClusterSetupController(
                clusterDefinition,
                maxParallel:    maxParallel,
                unredacted:     unredacted,
                debugMode:      debug,
                uploadCharts:   uploadCharts,
                clusterspace:   clusterspace);

            controller.DisablePendingTasks = disablePending;

            controller.StatusChangedEvent +=
                status =>
            {
                status.WriteToConsole();
            };

            switch (await controller.RunAsync())
            {
            case SetupDisposition.Succeeded:

                var pendingGroups = controller.GetPendingGroups();

                if (pendingGroups.Count > 0)
                {
                    Console.WriteLine($"*** ERROR: [{pendingGroups.Count}] pending task groups have not been awaited:");
                    Console.WriteLine();

                    foreach (var groupName in pendingGroups)
                    {
                        Console.WriteLine($"   {groupName}");
                    }

                    Program.Exit(1);
                }

                Console.WriteLine();
                Console.WriteLine($" [{clusterDefinition.Name}] cluster is ready.");
                Console.WriteLine();

                if (check && !debug)
                {
                    var k8s = new Kubernetes(KubernetesClientConfiguration.BuildConfigFromConfigFile(KubeHelper.KubeConfigPath));

                    if (!await ClusterChecker.CheckAsync(clusterLogin, k8s))
                    {
                        Program.Exit(1);
                    }
                }

                Program.Exit(0);
                break;

            case SetupDisposition.Cancelled:

                Console.WriteLine(" *** CANCELLED: Cluster setup was cancelled.");
                Console.WriteLine();
                Console.WriteLine();
                Program.Exit(1);
                break;

            case SetupDisposition.Failed:

                Console.WriteLine();
                Console.WriteLine(" *** ERROR: Cluster setup failed.  Examine the logs here:");
                Console.WriteLine();
                Console.WriteLine($" {KubeHelper.LogFolder}");
                Console.WriteLine();
                Program.Exit(1);
                break;

            default:

                throw new NotImplementedException();
            }

            await Task.CompletedTask;
        }
Exemple #2
0
        /// <inheritdoc/>
        public override async Task RunAsync(CommandLine commandLine)
        {
            if (commandLine.Arguments.Length > 0)
            {
                Console.Error.WriteLine("*** ERROR: Unexpected argument.");
                Program.Exit(1);
            }

            Console.WriteLine();

            var contextName = KubernetesClientConfiguration.BuildDefaultConfig().CurrentContext;

            if (string.IsNullOrEmpty(contextName))
            {
                Console.Error.WriteLine($"*** ERROR: There is no current cluster.");
                Program.Exit(1);
            }

            var clusterLogin = KubeHelper.GetClusterLogin(KubeContextName.Parse(contextName));

            if (clusterLogin == null)
            {
                Console.Error.WriteLine($"*** ERROR: There is no current cluster or the current cluster is not a neonKUBE cluster.");
                Program.Exit(1);
            }

            // Handle the command line options.

            var all             = commandLine.HasOption("--all");
            var containerImages = commandLine.HasOption("--container-images");
            var priorityClass   = commandLine.HasOption("--priority-class");
            var resources       = commandLine.HasOption("--resources");
            var details         = commandLine.HasOption("--details");

            if (all || (!containerImages && !priorityClass && !resources))
            {
                containerImages = true;
                priorityClass   = true;
                resources       = true;
            }

            // Perform the requested checks.

            var k8s   = new Kubernetes(KubernetesClientConfiguration.BuildConfigFromConfigFile(KubeHelper.KubeConfigPath));
            var error = false;

            if (containerImages && !await ClusterChecker.CheckNodeContainerImagesAsync(clusterLogin, k8s, details: details))
            {
                error = true;
            }

            if (priorityClass && !await ClusterChecker.CheckPodPrioritiesAsync(clusterLogin, k8s, details: details))
            {
                error = true;
            }

            if (resources && !await ClusterChecker.CheckResourcesAsync(clusterLogin, k8s, details: details))
            {
                error = true;
            }

            if (error)
            {
                Console.Error.WriteLine();
                Console.Error.WriteLine("*** ERROR: Cluster check failed with one or more errors.");
                Program.Exit(1);
            }

            await Task.CompletedTask;
        }