/// <summary> /// Realizes a desired state by creating, updating and deleting resources as required. /// </summary> /// <param name="client">The client used to perform operations.</param> /// <param name="desired">The desired state to achieve.</param> /// <param name="labelSelector">A label selector to restrict the modifications to.</param> /// <param name="namespace">A namespace to restrict the modifications to.</param> /// <param name="cancellationToken">The cancellation token.</param> public static async Task RealizeStateAsync <TResource>(this ICustomResourceClient <TResource> client, IReadOnlyCollection <TResource> desired, string labelSelector = null, string @namespace = null, CancellationToken cancellationToken = default) where TResource : CustomResource, IPayloadPatchable <TResource> { var existing = await client.ListAsync(labelSelector, @namespace, cancellationToken); foreach (var resource in desired) { var existingResource = existing.FirstOrDefault(resource.NameEquals); if (existingResource == null) { await client.CreateAsync(resource, cancellationToken); } else if (!existingResource.Equals(resource)) { await client.UpdateAsync(resource, cancellationToken); } } foreach (var resource in existing.Where(desired.DoesNotContain)) { await client.DeleteAsync(resource.Metadata.Name, resource.Metadata.Namespace, cancellationToken); } }
/// <summary> /// Updates an existing resource using GET, PUT and MVCC. /// </summary> /// <param name="client">The client used to perform operations.</param> /// <param name="resourceName">The name of the target resource to update.</param> /// <param name="modifyResource">A callback that applies the desired modifications to the resource.</param> /// <param name="namespace">The namespace the resource is located in.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The current state for the modified resource.</returns> public static async Task <TResource> UpdateAsync <TResource>(this ICustomResourceClient <TResource> client, string resourceName, Func <TResource, Task> modifyResource, string @namespace = null, CancellationToken cancellationToken = default) where TResource : CustomResource { while (true) { var resource = await client.ReadAsync(resourceName, @namespace, cancellationToken); await modifyResource(resource); try { return(await client.ReplaceAsync(resource, cancellationToken)); } catch (HttpRequestException <StatusV1> ex) when(ex.StatusCode == HttpStatusCode.Conflict) { client.KubeClient.LoggerFactory .CreateLogger(typeof(CustomResourceClientExtensions).FullName) .LogWarning(ex, "Conflict detected while updating {0}. Retrying in a moment.", resourceName); await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken); } } }
public CustomResourceWatcher(ILogger <CustomResourceWatcher <TResource> > logger, ICustomResourceClient <TResource> client, CustomResourceNamespace <TResource> @namespace = null) { _logger = logger; _crd = new TResource().Definition; _client = client; _namespace = @namespace?.Value ?? ""; }
/// <summary> /// Updates an existing resource using GET, PUT and MVCC. /// </summary> /// <param name="client">The client used to perform operations.</param> /// <param name="resourceName">The name of the target resource to update.</param> /// <param name="modifyResource">A callback that applies the desired modifications to the resource.</param> /// <param name="namespace">The namespace the resource is located in.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The current state for the modified resource.</returns> public static Task <TResource> UpdateAsync <TResource>(this ICustomResourceClient <TResource> client, string resourceName, Action <TResource> modifyResource, string @namespace = null, CancellationToken cancellationToken = default) where TResource : CustomResource => client.UpdateAsync(resourceName, resource => { modifyResource(resource); return(Task.CompletedTask); }, @namespace, cancellationToken);
/// <summary> /// Updates an existing resource using PATCH. /// </summary> /// <param name="client">The client used to perform operations.</param> /// <param name="resource">The new desired state of the resource.</param> /// <param name="cancellationToken">The cancellation token.</param> /// <returns>The current state for the updated resource.</returns> public static Task <TResource> UpdateAsync <TResource>(this ICustomResourceClient <TResource> client, TResource resource, CancellationToken cancellationToken = default) where TResource : CustomResource, IPayloadPatchable <TResource> => client.UpdateAsync( resource.Metadata.Name, patch => { patch.Replace(x => x.Metadata.Labels, resource.Metadata.Labels); resource.ToPayloadPatch(patch); }, resource.Metadata.Namespace, cancellationToken);
public CustomResourceClientRealizeStateFacts() { _client = _clientMock.Object; }