Ejemplo n.º 1
0
        /// <summary>
        /// <para>
        /// Ensures that <b>helm</b> tool whose version is at least as great as the requested
        /// cluster version is installed to the <b>neonKUBE</b> programs folder by copying the
        /// tool from the cache if necessary.
        /// </para>
        /// <note>
        /// This will probably require elevated privileges.
        /// </note>
        /// <note>
        /// This assumes that <b>Helm</b> has already been downloaded and cached and also that
        /// more recent <b>Helm</b> releases are backwards compatible with older deployed versions
        /// of Tiller.
        /// </note>
        /// </summary>
        /// <param name="setupInfo">The KUbernetes setup information.</param>
        public static void InstallHelm(KubeSetupInfo setupInfo)
        {
            Covenant.Requires <ArgumentNullException>(setupInfo != null);

            var hostPlatform   = KubeHelper.HostPlatform;
            var cachedHelmPath = KubeHelper.GetCachedComponentPath(hostPlatform, "helm", setupInfo.Versions.Helm);
            var targetPath     = Path.Combine(KubeHelper.ProgramFolder);

            switch (hostPlatform)
            {
            case KubeHostPlatform.Windows:

                targetPath = Path.Combine(targetPath, "helm.exe");

                if (!File.Exists(targetPath))
                {
                    File.Copy(cachedHelmPath, targetPath);
                }
                else
                {
                    // Execute the existing target to obtain its version and update it
                    // to the cached copy if the cluster installed a more recent version
                    // of Kubernetes.

                    // $hack(jeff.lill): Simple client version extraction

                    var pattern  = "SemVer:\"v";
                    var response = NeonHelper.ExecuteCapture(targetPath, "version");
                    var pStart   = response.OutputText.IndexOf(pattern);
                    var error    = "Cannot identify existing [helm] version.";

                    if (pStart == -1)
                    {
                        throw new KubeException(error);
                    }

                    pStart += pattern.Length;

                    var pEnd = response.OutputText.IndexOf("\"", pStart);

                    if (pEnd == -1)
                    {
                        throw new KubeException(error);
                    }

                    var currentVersionString = response.OutputText.Substring(pStart, pEnd - pStart);

                    if (!Version.TryParse(currentVersionString, out var currentVersion))
                    {
                        throw new KubeException(error);
                    }

                    if (Version.Parse(setupInfo.Versions.Helm) > currentVersion)
                    {
                        // We need to copy the latest version.

                        File.Copy(cachedHelmPath, targetPath);
                    }
                }
                break;

            case KubeHostPlatform.Linux:
            case KubeHostPlatform.Osx:
            default:

                throw new NotImplementedException($"[{hostPlatform}] support is not implemented.");
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// <para>
        /// Ensures that <b>kubectl</b> tool whose version is at least as great as the Kubernetes
        /// cluster version is installed to the <b>neonKUBE</b> programs folder by copying the
        /// tool from the cache if necessary.
        /// </para>
        /// <note>
        /// This will probably require elevated privileges.
        /// </note>
        /// <note>
        /// This assumes that <b>kubectl</b> has already been downloaded and cached and also that
        /// more recent <b>kubectl</b> releases are backwards compatible with older deployed versions
        /// of Kubernetes.
        /// </note>
        /// </summary>
        /// <param name="setupInfo">The KUbernetes setup information.</param>
        public static void InstallKubeCtl(KubeSetupInfo setupInfo)
        {
            Covenant.Requires <ArgumentNullException>(setupInfo != null);

            var hostPlatform      = KubeHelper.HostPlatform;
            var cachedKubeCtlPath = KubeHelper.GetCachedComponentPath(hostPlatform, "kubectl", setupInfo.Versions.Kubernetes);
            var targetPath        = Path.Combine(KubeHelper.ProgramFolder);

            switch (hostPlatform)
            {
            case KubeHostPlatform.Windows:

                targetPath = Path.Combine(targetPath, "kubectl.exe");

                // Ensure that the KUBECONFIG environment variable exists and includes
                // the path to the user's [.neonkube] configuration.

                var kubeConfigVar = Environment.GetEnvironmentVariable("KUBECONFIG");

                if (string.IsNullOrEmpty(kubeConfigVar))
                {
                    // The [KUBECONFIG] environment variable doesn't exist so we'll set it.

                    Registry.SetValue(@"HKEY_CURRENT_USER\Environment", "KUBECONFIG", KubeConfigPath, RegistryValueKind.ExpandString);
                    Environment.SetEnvironmentVariable("KUBECONFIG", KubeConfigPath);
                }
                else
                {
                    // The [KUBECONFIG] environment variable exists but we still need to
                    // ensure that the path to our [USER/.neonkube] config is present.

                    var sb    = new StringBuilder();
                    var found = false;

                    foreach (var path in kubeConfigVar.Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries))
                    {
                        if (path == KubeConfigPath)
                        {
                            found = true;
                        }

                        sb.AppendWithSeparator(path, ";");
                    }

                    if (!found)
                    {
                        sb.AppendWithSeparator(KubeConfigPath, ";");
                    }

                    var newKubeConfigVar = sb.ToString();

                    if (newKubeConfigVar != kubeConfigVar)
                    {
                        Registry.SetValue(@"HKEY_CURRENT_USER\Environment", "KUBECONFIG", newKubeConfigVar, RegistryValueKind.ExpandString);
                        Environment.SetEnvironmentVariable("KUBECONFIG", newKubeConfigVar);
                    }
                }

                if (!File.Exists(targetPath))
                {
                    File.Copy(cachedKubeCtlPath, targetPath);
                }
                else
                {
                    // Execute the existing target to obtain its version and update it
                    // to the cached copy if the cluster installed a more recent version
                    // of Kubernetes.

                    // $hack(jeff.lill): Simple client version extraction

                    var pattern  = "GitVersion:\"v";
                    var response = NeonHelper.ExecuteCapture(targetPath, "version");
                    var pStart   = response.OutputText.IndexOf(pattern);
                    var error    = "Cannot identify existing [kubectl] version.";

                    if (pStart == -1)
                    {
                        throw new KubeException(error);
                    }

                    pStart += pattern.Length;

                    var pEnd = response.OutputText.IndexOf("\"", pStart);

                    if (pEnd == -1)
                    {
                        throw new KubeException(error);
                    }

                    var currentVersionString = response.OutputText.Substring(pStart, pEnd - pStart);

                    if (!Version.TryParse(currentVersionString, out var currentVersion))
                    {
                        throw new KubeException(error);
                    }

                    if (Version.Parse(setupInfo.Versions.Kubernetes) > currentVersion)
                    {
                        // We need to copy the latest version.

                        if (File.Exists(targetPath))
                        {
                            File.Delete(targetPath);
                        }

                        File.Copy(cachedKubeCtlPath, targetPath);
                    }
                }
                break;

            case KubeHostPlatform.Linux:
            case KubeHostPlatform.Osx:
            default:

                throw new NotImplementedException($"[{hostPlatform}] support is not implemented.");
            }
        }