Ejemplo n.º 1
0
        /// <summary>
        /// Updates the <b>spec</b> of a cluster scoped custom object of the specified generic
        /// object type and name.
        /// </summary>
        /// <typeparam name="T">The custom object type.</typeparam>
        /// <param name="k8s">The <see cref="Kubernetes"/> client.</param>
        /// <param name="patch">
        /// Specifies the patch to be applied to the object spec.  This is typically a
        /// <see cref="V1Patch"/> instance but additional patch types may be supported in
        /// </param>
        /// <param name="name">Specifies the object name.</param>
        /// <param name="dryRun">
        /// When present, indicates that modifications should not be persisted. An invalid
        /// or unrecognized dryRun directive will result in an error response and no further
        /// processing of the request. Valid values are: - All: all dry run stages will be
        /// processed
        /// </param>
        /// <param name="fieldManager">
        /// fieldManager is a name associated with the actor or entity that is making these
        /// changes. The value must be less than or 128 characters long, and only contain
        /// printable characters, as defined by https://golang.org/pkg/unicode/#IsPrint.
        /// </param>
        /// <param name="force">
        /// Force is going to "force" Apply requests. It means user will re-acquire conflicting
        /// fields owned by other people. Force flag must be unset for non-apply patch requests.
        /// </param>
        /// <param name="cancellationToken">Optionally specifies a cancellation token.</param>
        /// <returns>The updated custom object.</returns>
        public static async Task <T> PatchClusterCustomObjectAsync <T>(
            this IKubernetes k8s,
            V1Patch patch,
            string name,
            string dryRun       = null,
            string fieldManager = null,
            bool?force          = null,
            CancellationToken cancellationToken = default(CancellationToken))

            where T : IKubernetesObject <V1ObjectMeta>, new()
        {
            await SyncContext.Clear;

            Covenant.Requires <ArgumentNullException>(patch != null, nameof(patch));
            Covenant.Requires <ArgumentNullException>(!string.IsNullOrEmpty(name), nameof(name));

            var typeMetadata = typeof(T).GetKubernetesTypeMetadata();
            var result       = await k8s.PatchClusterCustomObjectAsync(
                body :              patch,
                group :             typeMetadata.Group,
                version :           typeMetadata.ApiVersion,
                plural :            typeMetadata.PluralName,
                name :              name,
                dryRun :            dryRun,
                fieldManager :      fieldManager,
                force :             force,
                cancellationToken : cancellationToken);

            return(((JsonElement)result).Deserialize <T>(options: serializeOptions));
        }
Ejemplo n.º 2
0
        PatchDeploymentAsync(Kubernetes k8sClient, MTADeployModel patchModel)
        {
            var namespaceParams = PrepareNamespaceParams(_groupName);
            var deployParams    = PrepareDeployParams(_deployName);

            var existingDeployment = await k8sClient.ReadNamespacedDeploymentAsync
                                         (deployParams.Item1, namespaceParams);

            existingDeployment.Spec.Template.Spec.Containers[0].Image = patchModel.Image;

            existingDeployment.Spec.Template.Spec.Containers[0].ImagePullPolicy =
                patchModel.ImagePullPolicy;

            existingDeployment.Spec.Replicas = patchModel.Replicas;

            var container = existingDeployment.Spec.Template.Spec.Containers[0];

            container.Name = deployParams.Item3;

            if (patchModel.Env.Count > 0)
            {
                var v1EnvList = new List <V1EnvVar>();
                foreach (var env in patchModel.Env)
                {
                    var v1Env = new V1EnvVar(env["name"], env["value"]);
                    v1EnvList.Add(v1Env);
                }
                container.Env = v1EnvList;
            }

            if (patchModel.Ports.Count > 0)
            {
                var containerPorts = new List <V1ContainerPort>();
                foreach (var port in patchModel.Ports)
                {
                    var v1ContainerPort = new V1ContainerPort(port);
                    containerPorts.Add(v1ContainerPort);
                }
                container.Ports = containerPorts;
            }

            try
            {
                var v1Patch      = new V1Patch(existingDeployment, V1Patch.PatchType.MergePatch);
                var v1Deployment = await k8sClient.PatchNamespacedDeploymentAsync
                                       (v1Patch, deployParams.Item1, namespaceParams);

                var deployModel = new MTADeployModel(v1Deployment);
                return(new Tuple <MTADeployModel, MTAErrorModel>(deployModel, null));
            }
            catch (HttpOperationException ex)
            {
                var errorModel = new MTAErrorModel(ex);
                return(new Tuple <MTADeployModel, MTAErrorModel>(null, errorModel));
            }
            catch (Exception)
            {
                throw;
            }
        }
        public string Put(int count)
        {
            string output = "";

            if (count > 0 && count < 10)
            {
                KubernetesClientConfiguration config;
                if (Configuration["ASPNETCORE_ENVIRONMENT"] == "Debug")
                {
                    config = KubernetesClientConfiguration.BuildConfigFromConfigFile();
                }
                else
                {
                    config = KubernetesClientConfiguration.InClusterConfig();
                }
                IKubernetes client = new Kubernetes(config);

                JsonPatchDocument <V1StatefulSet> jsonDoc = new JsonPatchDocument <V1StatefulSet>();
                jsonDoc.Replace(p => p.Spec.Replicas, count);
                Console.WriteLine(JsonConvert.SerializeObject(jsonDoc));
                V1Patch patch = new V1Patch(jsonDoc);
                client.PatchNamespacedStatefulSetScale(patch, Configuration["MCStafefulSetName"], "default");
            }

            //This is where we update the count.
            return(output);
        }
Ejemplo n.º 4
0
        public virtual MediaTypeHeaderValue GetHeader(V1Patch body)
        {
            if (body == null)
            {
                throw new ArgumentNullException(nameof(body));
            }

            switch (body.Type)
            {
            case V1Patch.PatchType.JsonPatch:
                return(MediaTypeHeaderValue.Parse("application/json-patch+json; charset=utf-8"));

            case V1Patch.PatchType.MergePatch:
                return(MediaTypeHeaderValue.Parse("application/merge-patch+json; charset=utf-8"));

            case V1Patch.PatchType.StrategicMergePatch:
                return(MediaTypeHeaderValue.Parse("application/strategic-merge-patch+json; charset=utf-8"));

            case V1Patch.PatchType.ApplyPatch:
                return(MediaTypeHeaderValue.Parse("application/apply-patch+yaml; charset=utf-8"));

            default:
                throw new ArgumentOutOfRangeException(nameof(body.Type), "");
            }
        }
Ejemplo n.º 5
0
        public PodEventHandler(
            Kubernetes client,
            GenericChaosClient chaosClient,
            ArmClient armClient,
            string watchNamespace = ""
            )
        {
            Client      = client;
            ChaosClient = chaosClient;
            ARMClient   = armClient;
            Namespace   = watchNamespace;

            Logger = new LoggerConfiguration()
                     .MinimumLevel.Information()
                     .Enrich
                     .FromLogContext()
                     .WriteTo.Console(
                outputTemplate: "[{Timestamp:hh:mm:ss} {Level:u3}] {Message,-30:lj} {Properties:j}{NewLine}{Exception}",
                theme: AnsiConsoleTheme.Code
                )
                     .CreateLogger();

            PodChaosHandledPatchBody = new V1Patch(PodChaosHandledPatch, V1Patch.PatchType.MergePatch);
            PodChaosResumePatchBody  = new V1Patch(PodChaosResumePatch, V1Patch.PatchType.MergePatch);
        }
Ejemplo n.º 6
0
        public async Task <V1Deployment> UpdateDeploymentAsync(V1Deployment deployment)
        {
            if (deployment == null)
            {
                throw new ArgumentNullException(nameof(deployment));
            }

            var patch = new V1Patch(deployment);

            return(await _k8client.PatchNamespacedDeploymentAsync(patch, deployment.Metadata.Name, deployment.Metadata.NamespaceProperty));
        }
Ejemplo n.º 7
0
 public async Task <HttpOperationResponse <V1Namespace> > PatchNamespaceWithHttpMessagesAsync(
     V1Patch body,
     string name,
     string pretty = null,
     Dictionary <string, List <string> > customHeaders = null,
     CancellationToken cancellationToken = default(CancellationToken))
 {
     return(await _kubernetes.PatchNamespaceWithHttpMessagesAsync(
                body,
                name,
                pretty,
                customHeaders,
                cancellationToken
                ));
 }
Ejemplo n.º 8
0
        public IActionResult Scale([FromBody] int replicas)
        {
            // Use the config object to create a client.
            using (var client = new Kubernetes(k8sConfig))
            {
                // Create a json patch fro the replicas
                var jsonPatch = new JsonPatchDocument <V1Scale>();
                jsonPatch.Replace(e => e.Spec.Replicas, replicas);
                var patch = new V1Patch(jsonPatch);

                // Patch the Deployment
                client.PatchNamespacedDeploymentScale(patch, "invaders", "invaders");

                return(NoContent());
            }
        }
Ejemplo n.º 9
0
        public IActionResult Scale([FromBody] ReplicaRequest request)
        {
            // Use the config object to create a client.
            using (var client = new Kubernetes(k8sConfig))
            {
                // Create a json patch for the replicas
                var jsonPatch = new JsonPatchDocument <V1Scale>();
                // Set the new number of repplcias
                jsonPatch.Replace(e => e.Spec.Replicas, request.Replicas);
                // Creat the patch
                var patch = new V1Patch(jsonPatch);

                // Patch the "minions" Deployment in the "default" namespace
                client.PatchNamespacedDeploymentScale(patch, request.Deployment, request.Namespace);

                return(NoContent());
            }
        }
Ejemplo n.º 10
0
        public async Task <Response> ScaleDeployment(string deploymentName, ModuleReplicas moduleReplicas, string nameSpace = "default")
        {
            // Create json patch for replicas
            var jsonPatch = new JsonPatchDocument <V1Scale>();

            // Insert replicas into patch
            jsonPatch.Replace(e => e.Spec.Replicas, moduleReplicas.Value);

            var patch = new V1Patch(jsonPatch);

            try
            {
                var result = await _client.PatchNamespacedDeploymentScaleWithHttpMessagesAsync(patch, deploymentName, nameSpace);
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return(Response.Unsuccessful(e.Message));
            }

            return(Response.Success());
        }
Ejemplo n.º 11
0
 protected override Task OnResourceApplyPatch(V1Patch patch, KubeRef refId)
 {
     return(Client.PatchNamespacedSecretWithHttpMessagesAsync(patch, refId.Name, refId.Namespace));
 }
Ejemplo n.º 12
0
 public async Task <V1Deployment> PatchNamespacedDeploymentAsync(V1Patch patch, string deploymentName, string namespaceProperty,
                                                                 CancellationToken cancellationToken = default)
 {
     return(await _client.PatchNamespacedDeploymentAsync(patch, deploymentName, namespaceProperty, cancellationToken : cancellationToken));
 }
Ejemplo n.º 13
0
        private static async Task Main(string[] args)
        {
            Console.WriteLine("starting main()...");

            // creating the k8s client
            var         k8SClientConfig = KubernetesClientConfiguration.BuildConfigFromConfigFile();
            IKubernetes client          = new Kubernetes(k8SClientConfig);

            // creating a K8s client for the CRD
            var myCRD = Utils.MakeCRD();

            Console.WriteLine("working with CRD: {0}.{1}", myCRD.PluralName, myCRD.Group);
            var generic = new GenericClient(client, myCRD.Group, myCRD.Version, myCRD.PluralName);

            // creating a sample custom resource content
            var myCr = Utils.MakeCResource();

            try
            {
                Console.WriteLine("creating CR {0}", myCr.Metadata.Name);
                var response = await client.CreateNamespacedCustomObjectWithHttpMessagesAsync(
                    myCr,
                    myCRD.Group, myCRD.Version,
                    myCr.Metadata.NamespaceProperty ?? "default",
                    myCRD.PluralName).ConfigureAwait(false);
            }
            catch (HttpOperationException httpOperationException) when(httpOperationException.Message.Contains("422"))
            {
                var phase   = httpOperationException.Response.ReasonPhrase;
                var content = httpOperationException.Response.Content;

                Console.WriteLine("response content: {0}", content);
                Console.WriteLine("response phase: {0}", phase);
            }
            catch (HttpOperationException)
            {
            }

            // listing the cr instances
            Console.WriteLine("CR list:");
            var crs = await generic.ListNamespacedAsync <CustomResourceList <CResource> >(myCr.Metadata.NamespaceProperty ?? "default").ConfigureAwait(false);

            foreach (var cr in crs.Items)
            {
                Console.WriteLine("- CR Item {0} = {1}", crs.Items.IndexOf(cr), cr.Metadata.Name);
            }

            var old = JsonSerializer.SerializeToDocument(myCr);

            myCr.Metadata.Labels.TryAdd("newKey", "newValue");

            var expected = JsonSerializer.SerializeToDocument(myCr);
            var patch    = old.CreatePatch(expected);

            // updating the custom resource
            var crPatch = new V1Patch(patch, V1Patch.PatchType.JsonPatch);

            try
            {
                var patchResponse = await client.PatchNamespacedCustomObjectAsync(
                    crPatch,
                    myCRD.Group,
                    myCRD.Version,
                    myCr.Metadata.NamespaceProperty ?? "default",
                    myCRD.PluralName,
                    myCr.Metadata.Name).ConfigureAwait(false);
            }
            catch (HttpOperationException httpOperationException)
            {
                var phase   = httpOperationException.Response.ReasonPhrase;
                var content = httpOperationException.Response.Content;
                Console.WriteLine("response content: {0}", content);
                Console.WriteLine("response phase: {0}", phase);
            }

            // getting the updated custom resource
            var fetchedCR = await generic.ReadNamespacedAsync <CResource>(
                myCr.Metadata.NamespaceProperty ?? "default",
                myCr.Metadata.Name).ConfigureAwait(false);

            Console.WriteLine("fetchedCR = {0}", fetchedCR.ToString());

            // deleting the custom resource
            try
            {
                myCr = await generic.DeleteNamespacedAsync <CResource>(
                    myCr.Metadata.NamespaceProperty ?? "default",
                    myCr.Metadata.Name).ConfigureAwait(false);

                Console.WriteLine("Deleted the CR");
            }
            catch (Exception exception)
            {
                Console.WriteLine("Exception type {0}", exception);
            }
        }
Ejemplo n.º 14
0
        static void Main(string[] args)
        {
            var kClient = new Kubernetes(KubernetesClientConfiguration.BuildDefaultConfig());

            var namespacesTask = kClient.ListNamespaceWithHttpMessagesAsync();

            namespacesTask.Wait();
            AssertErrors(namespacesTask.Result);

            var namespaces = namespacesTask.Result.Body;

            var namespaceSet = namespaces.Items.Select(e => new
                                                       { NamespaceName = e.Metadata.Name, Role = GetRole(kClient, e.Metadata.Name) }).Where(e => e.Role != null).ToList();


            // Just to assert existing Policies
            var thoseWithProperRights = namespaceSet.Where(n =>
                                                           n.Role.Rules.Any(r => r.ApiGroups.Any(a => a == "rbac.authorization.k8s.io"))).ToList();

            // List of Roles with missing policy
            var thoseWithoutProperRights = namespaceSet.Where(n =>
                                                              n.Role.Rules.All(r => r.ApiGroups.All(a => a != "rbac.authorization.k8s.io"))).ToList();


            foreach (var thoseWithoutProperRight in thoseWithoutProperRights)
            {
                var policy = new V1PolicyRule
                {
                    ApiGroups = new List <string>
                    {
                        "rbac.authorization.k8s.io"
                    },
                    Resources = new List <string>
                    {
                        "rolebindings",
                        "roles"
                    },
                    Verbs = new List <string>
                    {
                        "*"
                    }
                };
                var patch = new JsonPatchDocument <V1Role>();
                patch.Add(p => p.Rules, policy);
                try
                {
                    var body      = new V1Patch(patch);
                    var patchTask = kClient.PatchNamespacedRoleWithHttpMessagesAsync(body, thoseWithoutProperRight.Role.Metadata.Name, thoseWithoutProperRight.NamespaceName);
                    patchTask.Wait();
                    Console.WriteLine($"Updated Policy on {thoseWithoutProperRight.Role.Metadata.Name}");
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }
            }



            Console.ReadKey();
        }
Ejemplo n.º 15
0
    public async Task <HttpOperationResponse <object> > PatchAnyResourceKindWithHttpMessagesAsync(V1Patch body, string group, string version, string namespaceParameter, string plural, string name, string dryRun = default(string), string fieldManager = default(string), bool?force = default(bool?), Dictionary <string, List <string> > customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
    {
        if (body == null)
        {
            throw new ValidationException(ValidationRules.CannotBeNull, "body");
        }
        if (group == null)
        {
            throw new ValidationException(ValidationRules.CannotBeNull, "group");
        }
        if (version == null)
        {
            throw new ValidationException(ValidationRules.CannotBeNull, "version");
        }
        if (namespaceParameter == null)
        {
            throw new ValidationException(ValidationRules.CannotBeNull, "namespaceParameter");
        }
        if (plural == null)
        {
            throw new ValidationException(ValidationRules.CannotBeNull, "plural");
        }
        if (name == null)
        {
            throw new ValidationException(ValidationRules.CannotBeNull, "name");
        }
        // Tracing
        bool   _shouldTrace  = ServiceClientTracing.IsEnabled;
        string _invocationId = null;

        if (_shouldTrace)
        {
            _invocationId = ServiceClientTracing.NextInvocationId.ToString();
            Dictionary <string, object> tracingParameters = new Dictionary <string, object>();
            tracingParameters.Add("body", body);
            tracingParameters.Add("dryRun", dryRun);
            tracingParameters.Add("fieldManager", fieldManager);
            tracingParameters.Add("force", force);
            tracingParameters.Add("group", group);
            tracingParameters.Add("version", version);
            tracingParameters.Add("namespaceParameter", namespaceParameter);
            tracingParameters.Add("plural", plural);
            tracingParameters.Add("name", name);
            tracingParameters.Add("cancellationToken", cancellationToken);
            ServiceClientTracing.Enter(_invocationId, this, "PatchNamespacedCustomObject", tracingParameters);
        }
        // Construct URL
        var _baseUrl = Client.BaseUri.AbsoluteUri;
        var _url     = new System.Uri(new System.Uri(_baseUrl + (_baseUrl.EndsWith("/") ? "" : "/")), Pattern(group, namespaceParameter) + "/{name}").ToString();

        _url = _url.Replace("{group}", System.Uri.EscapeDataString(group));
        _url = _url.Replace("{version}", System.Uri.EscapeDataString(version));
        _url = _url.Replace("{namespace}", System.Uri.EscapeDataString(namespaceParameter));
        _url = _url.Replace("{plural}", System.Uri.EscapeDataString(plural));
        _url = _url.Replace("{name}", System.Uri.EscapeDataString(name));
        List <string> _queryParameters = new List <string>();

        if (dryRun != null)
        {
            _queryParameters.Add(string.Format("dryRun={0}", System.Uri.EscapeDataString(dryRun)));
        }
        if (fieldManager != null)
        {
            _queryParameters.Add(string.Format("fieldManager={0}", System.Uri.EscapeDataString(fieldManager)));
        }
        if (force != null)
        {
            _queryParameters.Add(string.Format("force={0}", System.Uri.EscapeDataString(SafeJsonConvert.SerializeObject(force, Client.SerializationSettings).Trim('"'))));
        }
        if (_queryParameters.Count > 0)
        {
            _url += "?" + string.Join("&", _queryParameters);
        }
        // Create HTTP transport objects
        var _httpRequest = new HttpRequestMessage();
        HttpResponseMessage _httpResponse = null;

        _httpRequest.Method     = new HttpMethod("PATCH");
        _httpRequest.RequestUri = new System.Uri(_url);
        // Set Headers


        if (customHeaders != null)
        {
            foreach (var _header in customHeaders)
            {
                if (_httpRequest.Headers.Contains(_header.Key))
                {
                    _httpRequest.Headers.Remove(_header.Key);
                }
                _httpRequest.Headers.TryAddWithoutValidation(_header.Key, _header.Value);
            }
        }

        // Serialize Request
        string _requestContent = null;

        if (body != null)
        {
            _requestContent      = SafeJsonConvert.SerializeObject(body, Client.SerializationSettings);
            _httpRequest.Content = new StringContent(_requestContent, System.Text.Encoding.UTF8);
            _httpRequest.Content.Headers.ContentType = Client.GetHeader(body);
        }
        // Set Credentials
        if (Client.Credentials != null)
        {
            cancellationToken.ThrowIfCancellationRequested();
            await Client.Credentials.ProcessHttpRequestAsync(_httpRequest, cancellationToken).ConfigureAwait(false);
        }
        // Send Request
        if (_shouldTrace)
        {
            ServiceClientTracing.SendRequest(_invocationId, _httpRequest);
        }
        cancellationToken.ThrowIfCancellationRequested();
        _httpResponse = await Client.HttpClient.SendAsync(_httpRequest, cancellationToken).ConfigureAwait(false);

        if (_shouldTrace)
        {
            ServiceClientTracing.ReceiveResponse(_invocationId, _httpResponse);
        }
        HttpStatusCode _statusCode = _httpResponse.StatusCode;

        cancellationToken.ThrowIfCancellationRequested();
        string _responseContent = null;

        if ((int)_statusCode != 200)
        {
            var ex = new HttpOperationException(string.Format("Operation returned an invalid status code '{0}'", _statusCode));
            if (_httpResponse.Content != null)
            {
                _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);
            }
            else
            {
                _responseContent = string.Empty;
            }
            ex.Request  = new HttpRequestMessageWrapper(_httpRequest, _requestContent);
            ex.Response = new HttpResponseMessageWrapper(_httpResponse, _responseContent);
            if (_shouldTrace)
            {
                ServiceClientTracing.Error(_invocationId, ex);
            }
            _httpRequest.Dispose();
            if (_httpResponse != null)
            {
                _httpResponse.Dispose();
            }
            throw ex;
        }
        // Create Result
        var _result = new HttpOperationResponse <object>();

        _result.Request  = _httpRequest;
        _result.Response = _httpResponse;
        // Deserialize Response
        if ((int)_statusCode == 200)
        {
            _responseContent = await _httpResponse.Content.ReadAsStringAsync().ConfigureAwait(false);

            try
            {
                _result.Body = SafeJsonConvert.DeserializeObject <object>(_responseContent, Client.DeserializationSettings);
            }
            catch (JsonException ex)
            {
                _httpRequest.Dispose();
                if (_httpResponse != null)
                {
                    _httpResponse.Dispose();
                }
                throw new SerializationException("Unable to deserialize the response.", _responseContent, ex);
            }
        }
        if (_shouldTrace)
        {
            ServiceClientTracing.Exit(_invocationId, _result);
        }
        return(_result);
    }
Ejemplo n.º 16
0
 public Task <HttpOperationResponse <V1Namespace> > PatchNamespaceWithHttpMessagesAsync(V1Patch body, string name, bool?pretty            = null,
                                                                                        Dictionary <string, List <string> > customHeaders = null, CancellationToken cancellationToken = default(CancellationToken))
 {
     return(Task.FromResult(new HttpOperationResponse <V1Namespace>()));
 }
 protected override Task OnResourceApplyPatch(V1Patch patch, KubeRef refId)
 {
     return(Client.PatchNamespacedConfigMapAsync(patch, refId.Name, refId.Namespace));
 }