Ejemplo n.º 1
0
 /// <summary>
 /// Returns the environment variables to use to invoke kubectl safely. This environemnt is necessary
 /// to ensure that the right credentials are used should the access token need to be refreshed.
 /// </summary>
 private static Dictionary <string, string> GetEnvironmentForContext(KubectlContext context)
 {
     return(new Dictionary <string, string>
     {
         [CommonEnvironmentVariables.GCloudContainerUseApplicationDefaultCredentialsVariable] = CommonEnvironmentVariables.TrueValue,
         [CommonEnvironmentVariables.GoogleApplicationCredentialsVariable] = context.CredentialsPath
     });
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Creates a deployment for the given image and with the given name. The deployment is created with pods that
 /// contain a single container running <paramref name="imageTag"/>.
 /// </summary>
 /// <param name="name">The name of the deployemnt to be created.</param>
 /// <param name="imageTag">The Docker image tag to use for the deployment.</param>
 /// <param name="outputAction">The output callback to be called with output from the command.</param>
 /// <param name="context">The context for invoking kubectl.</param>
 /// <returns>True if the operation succeeded false otherwise.</returns>
 public static Task <bool> CreateDeploymentAsync(
     string name,
     string imageTag,
     int replicas,
     Action <string> outputAction,
     KubectlContext context)
 {
     return(RunCommandAsync($"run {name} --image={imageTag} --replicas={replicas} --port=8080 --record", outputAction, context));
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Changes the number of replicas for the given <paramref name="name"/>.
 /// </summary>
 /// <param name="name">The name of the deployment to update.</param>
 /// <param name="replicas">The new number of replicas.</param>
 /// <param name="outputAction">The output callback to be called with output from the command.</param>
 /// <param name="context">The context for invoking kubectl.</param>
 /// <returns>True if the operation succeeded false otherwise.</returns>
 public static Task <bool> ScaleDeploymentAsync(
     string name,
     int replicas,
     Action <string> outputAction,
     KubectlContext context)
 {
     return(RunCommandAsync(
                $"scale deployment {name} --replicas={replicas}",
                outputAction,
                context));
 }
Ejemplo n.º 4
0
 /// <summary>
 /// Updates an existing deployemnt given by <paramref name="name"/> with <paramref name="imageTag"/>.
 /// </summary>
 /// <param name="name">The name of the deployment to update.</param>
 /// <param name="imageTag">The Docker image tag to update to.</param>
 /// <param name="outputAction">The output callback to be called with output from the command.</param>
 /// <param name="context">The context for invoking kubectl.</param>
 /// <returns>True if the operation succeeded false otherwise.</returns>
 public static Task <bool> UpdateDeploymentImageAsync(
     string name,
     string imageTag,
     Action <string> outputAction,
     KubectlContext context)
 {
     return(RunCommandAsync(
                $"set image deployment/{name} {name}={imageTag} --record",
                outputAction,
                context));
 }
        /// <summary>
        /// Returns the <seealso cref="KubectlContext"/> instance to use for the given <paramref name="cluster"/> when
        /// performing Kubernetes operations.
        /// </summary>
        /// <param name="cluster">The cluster to create credentials for.</param>
        /// <returns>The <seealso cref="KubectlContext"/> for the given <paramref name="cluster"/>.</returns>
        public async Task <IKubectlContext> GetKubectlContextForClusterAsync(Cluster cluster)
        {
            var kubectlContext = new KubectlContext(FileSystem, _processService, CredentialsStore);

            if (!await kubectlContext.InitClusterCredentialsAsync(cluster))
            {
                throw new GCloudException($"Failed to get credentials for cluster {cluster.Name}");
            }

            return(kubectlContext);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Returns the <seealso cref="KubectlContext"/> instance to use for the given <paramref name="cluster"/> when
        /// performing Kubernetes operations.
        /// </summary>
        /// <param name="cluster">The name of the cluster for which to create credentials.</param>
        /// <param name="zone">The zone of the cluster.</param>
        /// <returns>The <seealso cref="KubectlContext"/> for the given <paramref name="cluster"/>.</returns>
        /// <remarks>
        /// Do not use this method directly.
        /// Use <see cref="IKubectlContextProvider.GetKubectlContextForClusterAsync"/>.
        /// </remarks>
        internal static async Task <KubectlContext> GetForClusterAsync(string cluster, string zone)
        {
            var kubctlContext = new KubectlContext();

            if (!await kubctlContext.InitClusterCredentialsAsync(cluster, zone))
            {
                throw new GCloudException($"Failed to get credentials for cluster {cluster}");
            }

            return(kubctlContext);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Exposes the service targetting the deployemnt <paramref name="deployment"/>. The ports being exposed are fixed
        /// to 80 for the service and 8080 for the target pods.
        /// </summary>
        /// <param name="deployment">The deployment for which to create and expose the service.</param>
        /// <param name="makePublic">True if the service should be made public, false otherwise.</param>
        /// <param name="outputAction">The output callback to be called with output from the command.</param>
        /// <param name="context">The context for invoking kubectl.</param>
        /// <returns>True if the operation succeeded false otherwise.</returns>
        public static Task <bool> ExposeServiceAsync(
            string deployment,
            bool makePublic,
            Action <string> outputAction,
            KubectlContext context)
        {
            var type = makePublic ? "--type=LoadBalancer" : "--type=ClusterIP";

            return(RunCommandAsync(
                       $"expose deployment {deployment} --port=80 --target-port=8080 {type}",
                       outputAction,
                       context));
        }
Ejemplo n.º 8
0
        private static async Task <T> GetJsonOutputAsync <T>(string command, KubectlContext context)
        {
            var actualCommand = FormatCommand(command, context, jsonOutput: true);

            try
            {
                Debug.WriteLine($"Executing kubectl command: kubectl {actualCommand}");
                return(await ProcessUtils.GetJsonOutputAsync <T>("kubectl", actualCommand));
            }
            catch (JsonOutputException ex)
            {
                throw new GCloudException($"Failed to exectue command {actualCommand}\nInner exception: {ex.Message}", ex);
            }
        }
 /// <summary>
 /// Returns the <seealso cref="KubectlContext"/> instance to use for the given <paramref name="cluster"/> when
 /// performing Kubernetes operations.
 /// </summary>
 /// <param name="cluster">The cluster to create credentials for.</param>
 /// <returns>The <seealso cref="KubectlContext"/> for the given <paramref name="cluster"/>.</returns>
 public async Task <IKubectlContext> GetKubectlContextForClusterAsync(Cluster cluster) =>
 await KubectlContext.GetForClusterAsync(cluster.Name, cluster.Zone);
Ejemplo n.º 10
0
        private static string FormatCommand(string command, KubectlContext context, bool jsonOutput = false)
        {
            var format = jsonOutput ? "--output=json" : "";

            return($"{command} --kubeconfig=\"{context.ConfigPath}\" {format}");
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Returns the service with the given <paramref name="name"/>.
 /// </summary>
 /// <param name="name">The name of the service to return.</param>
 /// <param name="context">The context for invoking kubectl.</param>
 /// <returns>The service.</returns>
 public static Task <GkeService> GetServiceAsync(string name, KubectlContext context)
 {
     return(GetJsonOutputAsync <GkeService>($"get service {name}", context));
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Returns the list of deployments for the current cluster.
        /// </summary>
        /// <param name="context">The context for invoking kubectl.</param>
        /// <returns>The list of deployments.</returns>
        public static async Task <IList <GkeDeployment> > GetDeploymentsAsync(KubectlContext context)
        {
            var deployments = await GetJsonOutputAsync <GkeList <GkeDeployment> >($"get deployments", context);

            return(deployments.Items);
        }
Ejemplo n.º 13
0
        /// <summary>
        /// Returns the list of services running in the current cluster.
        /// </summary>
        /// <param name="context">The context for invoking kubectl.</param>
        /// <returns>The list of services.</returns>
        public static async Task <IList <GkeService> > GetServicesAsync(KubectlContext context)
        {
            var services = await GetJsonOutputAsync <GkeList <GkeService> >("get services", context);

            return(services.Items);
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Determines if a deployment with the given name already exists.
        /// </summary>
        /// <param name="name">The name of the deployment to check.</param>
        /// <param name="context">The context for invoking kubectl.</param>
        /// <returns>True if the deployment exists, false otherwise.</returns>
        public static async Task <bool> DeploymentExistsAsync(string name, KubectlContext context)
        {
            var deployments = await GetDeploymentsAsync(context);

            return(deployments.FirstOrDefault(x => x.Metadata.Name == name) != null);
        }
Ejemplo n.º 15
0
 /// <summary>
 /// Deletes the service given by <paramref name="name"/>.
 /// </summary>
 /// <param name="name">The name of the service to delete.</param>
 /// <param name="outputAction">The output callback to be called with output from the command.</param>
 /// <param name="context">The context for invoking kubectl.</param>
 /// <returns>True if the operation succeeded false otherwise.</returns>
 public static Task <bool> DeleteServiceAsync(string name, Action <string> outputAction, KubectlContext context)
 => RunCommandAsync($"delete service {name}", outputAction, context);
Ejemplo n.º 16
0
        private static Task <bool> RunCommandAsync(string command, Action <string> outputAction, KubectlContext context)
        {
            var actualCommand = FormatCommand(command, context);

            Debug.WriteLine($"Executing kubectl command: kubectl {actualCommand}");
            Dictionary <string, string> environment = GetEnvironmentForContext(context);

            return(ProcessUtils.RunCommandAsync(
                       "kubectl",
                       actualCommand,
                       (o, e) => outputAction(e.Line),
                       environment: environment));
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Exposes the service targetting the deployemnt <paramref name="deployment"/>. The ports being exposed are fixed
 /// to 80 for the service and 8080 for the target pods.
 /// </summary>
 /// <param name="deployment">The deployment for which to create and expose the service.</param>
 /// <param name="outputAction">The output callback to be called with output from the command.</param>
 /// <param name="context">The context for invoking kubectl.</param>
 /// <returns>True if the operation succeeded false otherwise.</returns>
 public static Task <bool> ExposeServiceAsync(string deployment, Action <string> outputAction, KubectlContext context)
 {
     return(RunCommandAsync(
                $"expose deployment {deployment} --port=80 --target-port=8080 --type=LoadBalancer",
                outputAction,
                context));
 }