From 5b0809e76ed9b15e8bc65816a26ada33241f2112 Mon Sep 17 00:00:00 2001 From: visdmin Date: Sun, 29 Oct 2023 01:46:37 +0300 Subject: [PATCH 1/6] ObjectStoragev2 controller idea WIP!!! --- .../V1Alpha1ObjectStorage2Controller.cs | 70 +++++++++ .../Entities/V1Alpha1ObjectStorage2.cs | 143 ++++++++++++++++++ .../V1Alpha1ObjectStorageFinalizer.cs | 19 +++ src/UpcloudApiKubernetesOperator/Program.cs | 1 + 4 files changed, 233 insertions(+) create mode 100644 src/UpcloudApiKubernetesOperator/Controller/V1Alpha1ObjectStorage2Controller.cs create mode 100644 src/UpcloudApiKubernetesOperator/Entities/V1Alpha1ObjectStorage2.cs create mode 100644 src/UpcloudApiKubernetesOperator/Finalizer/V1Alpha1ObjectStorageFinalizer.cs diff --git a/src/UpcloudApiKubernetesOperator/Controller/V1Alpha1ObjectStorage2Controller.cs b/src/UpcloudApiKubernetesOperator/Controller/V1Alpha1ObjectStorage2Controller.cs new file mode 100644 index 0000000..a02ef9e --- /dev/null +++ b/src/UpcloudApiKubernetesOperator/Controller/V1Alpha1ObjectStorage2Controller.cs @@ -0,0 +1,70 @@ +using System.Text.Json; + +using k8s; +using k8s.Models; +using KubeOps.Operator.Controller; +using KubeOps.Operator.Controller.Results; +using KubeOps.Operator.Finalizer; +using KubeOps.Operator.Kubernetes; +using KubeOps.Operator.Rbac; + +using UpcloudApiKubernetesOperator.Finalizer; +using UpcloudApiKubernetesOperator.Entities; +using KubeOps.KubernetesClient; +using IdentityModel.Client; + + +namespace UpcloudApiKubernetesOperator.Controller.Storage; + +[EntityRbac(typeof(V1Alpha1ObjectStorage2), Verbs = RbacVerb.All)] +public class V1Alpha1ObjectStorage2Controller : IResourceController +{ + private readonly IKubernetesClient KubernetesClient; + private readonly HttpClient HttpClient; + private readonly ILogger Logger; + private readonly IFinalizerManager FinalizerManager; + private readonly static TimeSpan ResourceInterval = TimeSpan.FromSeconds(30); + private readonly JsonSerializerOptions JsonSerializerOptions = new JsonSerializerOptions { WriteIndented = true }; + + public V1Alpha1ObjectStorage2Controller( + IKubernetesClient kubernetesClient, + IHttpClientFactory httpClientFactory, + ILogger logger, + IFinalizerManager finalizerManager + ) { + KubernetesClient = kubernetesClient; + HttpClient = httpClientFactory.CreateClient(); + Logger = logger; + FinalizerManager = finalizerManager; + } + + public async Task ReconcileAsync(V1Alpha1ObjectStorage2 entity) + { + Logger.LogInformation("Reconciling (entity: {entity}, spec: {entitySpec}, status: {entityStatus})", + new { kind = entity.GetType(), name = entity.Name() }, + JsonSerializer.Serialize(entity.Spec, options: JsonSerializerOptions), + JsonSerializer.Serialize(entity.Status, options: JsonSerializerOptions) + ); + + // TODO: Research what is the best way to obtain required api credentials from a secret. + // Maybe during the operator startup ? + // KubernetesClient.Get() + + await FinalizerManager.RegisterFinalizerAsync(entity); + + return ResourceControllerResult.RequeueEvent(ResourceInterval); + } + + public Task StatusModifiedAsync(V1Alpha1ObjectStorage2 entity) + { + Logger.LogInformation($"entity {entity.Name()} called {nameof(StatusModifiedAsync)}."); + return Task.CompletedTask; + } + + public Task DeletedAsync(V1Alpha1ObjectStorage2 entity) + { + Logger.LogInformation($"entity {entity.Name()} called {nameof(DeletedAsync)}."); + + return Task.CompletedTask; + } +} diff --git a/src/UpcloudApiKubernetesOperator/Entities/V1Alpha1ObjectStorage2.cs b/src/UpcloudApiKubernetesOperator/Entities/V1Alpha1ObjectStorage2.cs new file mode 100644 index 0000000..fcfac92 --- /dev/null +++ b/src/UpcloudApiKubernetesOperator/Entities/V1Alpha1ObjectStorage2.cs @@ -0,0 +1,143 @@ +using System.Collections.ObjectModel; + +using k8s.Models; +using KubeOps.Operator.Entities; +using KubeOps.Operator.Entities.Annotations; + +namespace UpcloudApiKubernetesOperator.Entities; + +[KubernetesEntity(Group = "api.upcloud.com", ApiVersion = "v1alpha1", Kind = "ObjectStorage2")] +public class V1Alpha1ObjectStorage2 : CustomKubernetesEntity +{ + [Description("Specification for UpCloud router entity: https://developers.upcloud.com/1.3/13-networks/#create-router")] + public class V1Alpha1ObjectStorageSpec + { + [Length(MaxLength = 36, MinLength = -1)] + [Description("UUID of already existing object storage instance")] + public string Id { get; set; } = string.Empty; + + [Required] + [Length(MinLength = 1, MaxLength = 255)] + [Description("Region, see: https://developers.upcloud.com/1.3/21-managed-object-storage/#list-regions")] + public string Region { get; set; } = string.Empty; + + [Required] + [Pattern("stopped|started")] + [Description("Service status, see: https://developers.upcloud.com/1.3/21-managed-object-storage/#service-configured-status")] + public string ConfiguredStatus { get; set; } = string.Empty; + + [Items(MaxItems = 8, MinItems = 0)] + [Description("Contains blocks that define static routes for this router.")] + public Collection Networks { get; set; } = new (); + + [Required] + [Items(MaxItems = 50, MinItems = 0)] + [Description("List of cloud Users allowed to use object storage, see: https://developers.upcloud.com/1.3/21-managed-object-storage/#list-users")] + public Collection Users { get; set; } = new (); + + [Items(MaxItems = 255, MinItems = -1)] + [Description("Labels used for service filtering, see labels usage https://developers.upcloud.com/1.3/21-managed-object-storage/#labels-usage-examples")] + public Collection