/// <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)); }
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); }
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), ""); } }
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); }
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)); }
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 )); }
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()); } }
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()); } }
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()); }
protected override Task OnResourceApplyPatch(V1Patch patch, KubeRef refId) { return(Client.PatchNamespacedSecretWithHttpMessagesAsync(patch, refId.Name, refId.Namespace)); }
public async Task <V1Deployment> PatchNamespacedDeploymentAsync(V1Patch patch, string deploymentName, string namespaceProperty, CancellationToken cancellationToken = default) { return(await _client.PatchNamespacedDeploymentAsync(patch, deploymentName, namespaceProperty, cancellationToken : cancellationToken)); }
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); } }
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(); }
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); }
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)); }