From ab8c39d3cce032b3c798cc3a6aeaea2ad092dfdf Mon Sep 17 00:00:00 2001 From: jpflueger Date: Tue, 26 May 2020 16:11:50 -0600 Subject: [PATCH 01/10] first pass at actions for redis cache --- PROJECT | 83 ++++++------ api/v1alpha1/rediscacheaction_types.go | 53 ++++++++ config/crd/kustomization.yaml | 3 + .../cainjection_in_rediscacheactions.yaml | 8 ++ .../patches/webhook_in_rediscacheactions.yaml | 17 +++ .../azure_v1alpha1_rediscacheaction.yaml | 10 ++ controllers/async_controller.go | 2 + controllers/rediscacheaction_controller.go | 28 ++++ docs/howto/newoperatorguide.md | 4 +- main.go | 25 +++- pkg/resourcemanager/interfaces.go | 11 +- .../rediscaches/rediscache_manager.go | 4 +- .../rediscaches/rediscache_reconcile.go | 2 +- .../rediscaches/rediscacheaction_manager.go | 20 +++ .../rediscaches/rediscacheaction_reconcile.go | 121 ++++++++++++++++++ .../rediscaches/rediscacheactions.go | 63 +++++++++ .../rediscaches/rediscaches.go | 80 +----------- pkg/resourcemanager/rediscaches/shared.go | 88 +++++++++++++ 18 files changed, 499 insertions(+), 123 deletions(-) create mode 100644 api/v1alpha1/rediscacheaction_types.go create mode 100644 config/crd/patches/cainjection_in_rediscacheactions.yaml create mode 100644 config/crd/patches/webhook_in_rediscacheactions.yaml create mode 100644 config/samples/azure_v1alpha1_rediscacheaction.yaml create mode 100644 controllers/rediscacheaction_controller.go create mode 100644 pkg/resourcemanager/rediscaches/rediscacheaction_manager.go create mode 100644 pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go create mode 100644 pkg/resourcemanager/rediscaches/rediscacheactions.go create mode 100644 pkg/resourcemanager/rediscaches/shared.go diff --git a/PROJECT b/PROJECT index 9f105b0c929..ee6f49a71c2 100644 --- a/PROJECT +++ b/PROJECT @@ -1,121 +1,124 @@ +version: "2" domain: microsoft.com repo: github.com/Azure/azure-service-operator resources: - group: azure - kind: StorageAccount version: v1alpha1 + kind: StorageAccount - group: azure - kind: CosmosDB version: v1alpha1 + kind: CosmosDB - group: azure - kind: RedisCache version: v1alpha1 + kind: RedisCache - group: azure - kind: Eventhub version: v1alpha1 + kind: Eventhub - group: azure - kind: ResourceGroup version: v1alpha1 + kind: ResourceGroup - group: azure - kind: EventhubNamespace version: v1alpha1 + kind: EventhubNamespace - group: azure - kind: AzureSqlServer version: v1alpha1 + kind: AzureSqlServer - group: azure - kind: AzureSqlDatabase version: v1alpha1 + kind: AzureSqlDatabase - group: azure - kind: AzureSqlFirewallRule version: v1alpha1 + kind: AzureSqlFirewallRule - group: azure - kind: KeyVault version: v1alpha1 + kind: KeyVault - group: azure - kind: ConsumerGroup version: v1alpha1 + kind: ConsumerGroup - group: azure - kind: AzureSqlAction version: v1alpha1 + kind: AzureSqlAction - group: azure - kind: BlobContainer version: v1alpha1 + kind: BlobContainer - group: azure - kind: PostgreSQLServer version: v1alpha1 + kind: PostgreSQLServer - group: azure - kind: PostgreSQLDatabase version: v1alpha1 + kind: PostgreSQLDatabase - group: azure - kind: PostgreSQLVNetRule version: v1alpha1 + kind: PostgreSQLVNetRule - group: azure - kind: PostgreSQLFirewallRule version: v1alpha1 + kind: PostgreSQLFirewallRule - group: azure - kind: APIMgmtAPI version: v1alpha1 + kind: APIMgmtAPI - group: azure - kind: ApimService version: v1alpha1 + kind: ApimService - group: azure - kind: VirtualNetwork version: v1alpha1 + kind: VirtualNetwork - group: azure - kind: AzurePublicIPAddress version: v1alpha1 + kind: AzurePublicIPAddress - group: azure - kind: AzureNetworkInterface version: v1alpha1 + kind: AzureNetworkInterface - group: azure - kind: AppInsights version: v1alpha1 + kind: AppInsights - group: azure - kind: KeyVaultKey version: v1alpha1 + kind: KeyVaultKey - group: azure - kind: AzureSQLVNetRule version: v1alpha1 + kind: AzureSQLVNetRule - group: azure - kind: MySQLServer version: v1alpha1 + kind: MySQLServer - group: azure - kind: MySQLDatabase version: v1alpha1 + kind: MySQLDatabase - group: azure - kind: MySQLFirewallRule version: v1alpha1 + kind: MySQLFirewallRule - group: azure - kind: MySQLVNetRule version: v1alpha1 + kind: MySQLVNetRule - group: azure - kind: AzureVirtualMachine version: v1alpha1 + kind: AzureVirtualMachine - group: azure - kind: AzureSQLManagedUser version: v1alpha1 + kind: AzureSQLManagedUser - group: azure - kind: AzureLoadBalancer version: v1alpha1 + kind: AzureLoadBalancer - group: azure - kind: AzureVMScaleSet version: v1alpha1 + kind: AzureVMScaleSet - group: azure - kind: AzureSqlServer version: v1beta1 + kind: AzureSqlServer - group: azure - kind: AzureSqlDatabase version: v1beta1 + kind: AzureSqlDatabase - group: azure - kind: AzureSqlFirewallRule version: v1beta1 + kind: AzureSqlFirewallRule - group: azure - kind: AzureSqlFailoverGroup version: v1beta1 + kind: AzureSqlFailoverGroup - group: azure - kind: BlobContainer version: v1alpha2 + kind: BlobContainer - group: azure - kind: MySQLServer version: v1alpha2 -version: "2" + kind: MySQLServer +- group: azure + version: v1alpha1 + kind: RedisCacheAction diff --git a/api/v1alpha1/rediscacheaction_types.go b/api/v1alpha1/rediscacheaction_types.go new file mode 100644 index 00000000000..5522713e7ab --- /dev/null +++ b/api/v1alpha1/rediscacheaction_types.go @@ -0,0 +1,53 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +kubebuilder:validation:Enum=rollallkeys;rollprimarykey;rollsecondarykey +type RedisCacheActionName string + +const ( + RedisCacheActionNameRollAllKeys RedisCacheActionName = "rollallkeys" + RedisCacheActionNameRollPrimaryKey RedisCacheActionName = "rollprimarykey" + RedisCacheActionNameRollSecondaryKey RedisCacheActionName = "rollsecondarykey" +) + +// RedisCacheActionSpec defines the desired state of RedisCacheAction +type RedisCacheActionSpec struct { + ResourceGroup string `json:"resourceGroup"` + CacheName string `json:"cacheName"` + ActionName RedisCacheActionName `json:"actionName"` + SecretName string `json:"secretName,omitempty"` + KeyVaultToStoreSecrets string `json:"keyVaultToStoreSecrets,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status + +// RedisCacheAction is the Schema for the rediscacheactions API +// +kubebuilder:printcolumn:name="Provisioned",type="string",JSONPath=".status.provisioned" +// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.message" +type RedisCacheAction struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec RedisCacheActionSpec `json:"spec,omitempty"` + Status ASOStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// RedisCacheActionList contains a list of RedisCacheAction +type RedisCacheActionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []RedisCacheAction `json:"items"` +} + +func init() { + SchemeBuilder.Register(&RedisCacheAction{}, &RedisCacheActionList{}) +} diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 99feaa910e7..7aad6be4b68 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -38,6 +38,7 @@ resources: - bases/azure.microsoft.com_azuresqlmanagedusers.yaml - bases/azure.microsoft.com_azureloadbalancers.yaml - bases/azure.microsoft.com_azurevmscalesets.yaml +- bases/azure.microsoft.com_rediscacheactions.yaml # +kubebuilder:scaffold:crdkustomizeresource patches: @@ -75,6 +76,7 @@ patches: #- patches/webhook_in_azuresqlmanagedusers.yaml #- patches/webhook_in_azureloadbalancers.yaml #- patches/webhook_in_azurevmscalesets.yaml +#- patches/webhook_in_rediscacheactions.yaml # +kubebuilder:scaffold:crdkustomizewebhookpatch # [CAINJECTION] patches here are for enabling the CA injection for each CRD @@ -111,6 +113,7 @@ patches: #- patches/cainjection_in_azuresqlmanagedusers.yaml #- patches/cainjection_in_azureloadbalancers.yaml #- patches/cainjection_in_azurevmscalesets.yaml +#- patches/cainjection_in_rediscacheactions.yaml # +kubebuilder:scaffold:crdkustomizecainjectionpatch # the following config is for teaching kustomize how to do kustomization for CRDs. diff --git a/config/crd/patches/cainjection_in_rediscacheactions.yaml b/config/crd/patches/cainjection_in_rediscacheactions.yaml new file mode 100644 index 00000000000..fca6f70d2c3 --- /dev/null +++ b/config/crd/patches/cainjection_in_rediscacheactions.yaml @@ -0,0 +1,8 @@ +# The following patch adds a directive for certmanager to inject CA into the CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + annotations: + certmanager.k8s.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME) + name: rediscacheactions.azure.microsoft.com diff --git a/config/crd/patches/webhook_in_rediscacheactions.yaml b/config/crd/patches/webhook_in_rediscacheactions.yaml new file mode 100644 index 00000000000..b7704636e00 --- /dev/null +++ b/config/crd/patches/webhook_in_rediscacheactions.yaml @@ -0,0 +1,17 @@ +# The following patch enables conversion webhook for CRD +# CRD conversion requires k8s 1.13 or later. +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: rediscacheactions.azure.microsoft.com +spec: + conversion: + strategy: Webhook + webhookClientConfig: + # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank, + # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager) + caBundle: Cg== + service: + namespace: system + name: webhook-service + path: /convert diff --git a/config/samples/azure_v1alpha1_rediscacheaction.yaml b/config/samples/azure_v1alpha1_rediscacheaction.yaml new file mode 100644 index 00000000000..fa0c9fa15f1 --- /dev/null +++ b/config/samples/azure_v1alpha1_rediscacheaction.yaml @@ -0,0 +1,10 @@ +apiVersion: azure.microsoft.com/v1alpha1 +kind: RedisCacheAction +metadata: + name: rediscacheaction-sample-1 +spec: + resourceGroup: resourcegroup-azure-operators + cacheName: rediscache-sample-1 + + # possible values are 'rollallkeys', 'rollprimarykey', 'rollsecondarykey' + actionName: rollallkeys \ No newline at end of file diff --git a/controllers/async_controller.go b/controllers/async_controller.go index cc1f732a74b..0f37b75e5ff 100644 --- a/controllers/async_controller.go +++ b/controllers/async_controller.go @@ -157,6 +157,8 @@ func (r *AsyncReconciler) Reconcile(req ctrl.Request, obj runtime.Object) (resul r.Telemetry.LogInfoByInstance("status", "reconciling object", req.String()) + configOptions = append(configOptions, resourcemanager.WithClient(r.Client)) + if len(KeyVaultName) != 0 { //KeyVault was specified in Spec, so use that for secrets configOptions = append(configOptions, resourcemanager.WithSecretClient(keyvaultSecretClient)) } diff --git a/controllers/rediscacheaction_controller.go b/controllers/rediscacheaction_controller.go new file mode 100644 index 00000000000..471888ab628 --- /dev/null +++ b/controllers/rediscacheaction_controller.go @@ -0,0 +1,28 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +package controllers + +import ( + ctrl "sigs.k8s.io/controller-runtime" + + azurev1alpha1 "github.com/Azure/azure-service-operator/api/v1alpha1" +) + +// RedisCacheActionReconciler reconciles a RedisCacheAction object +type RedisCacheActionReconciler struct { + Reconciler *AsyncReconciler +} + +// +kubebuilder:rbac:groups=azure.microsoft.com,resources=rediscacheactions,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=azure.microsoft.com,resources=rediscacheactions/status,verbs=get;update;patch + +func (r *RedisCacheActionReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { + return r.Reconciler.Reconcile(req, &azurev1alpha1.RedisCacheAction{}) +} + +func (r *RedisCacheActionReconciler) SetupWithManager(mgr ctrl.Manager) error { + return ctrl.NewControllerManagedBy(mgr). + For(&azurev1alpha1.RedisCacheAction{}). + Complete(r) +} diff --git a/docs/howto/newoperatorguide.md b/docs/howto/newoperatorguide.md index da35f5dad19..37359a74aba 100644 --- a/docs/howto/newoperatorguide.md +++ b/docs/howto/newoperatorguide.md @@ -182,7 +182,7 @@ go build -o bin/manager main.go - set `instance.Status.Provisioned` to `true` and `instance.Status.Provisioning` to `false` ```go - func (p *AzureNewTypeClient) Ensure(ctx context.Context, obj runtime.Object) (found bool, err error) { + func (p *AzureNewTypeClient) Ensure(ctx context.Context, obj runtime.Object, opts ...resourcemanager.ConfigOption) (found bool, err error) { instance, err := p.convert(obj) if err != nil { return true, err @@ -193,7 +193,7 @@ go build -o bin/manager main.go return true, nil } - func (p *AzureNewTypeClient) Delete(ctx context.Context, obj runtime.Object) (found bool, err error) { + func (p *AzureNewTypeClient) Delete(ctx context.Context, obj runtime.Object, opts ...resourcemanager.ConfigOption) (found bool, err error) { instance, err := p.convert(obj) if err != nil { return true, err diff --git a/main.go b/main.go index 55ff3cc8086..14c5524ae2b 100644 --- a/main.go +++ b/main.go @@ -48,7 +48,7 @@ import ( psqlfirewallrule "github.com/Azure/azure-service-operator/pkg/resourcemanager/psql/firewallrule" psqlserver "github.com/Azure/azure-service-operator/pkg/resourcemanager/psql/server" psqlvnetrule "github.com/Azure/azure-service-operator/pkg/resourcemanager/psql/vnetrule" - resourcemanagerrediscache "github.com/Azure/azure-service-operator/pkg/resourcemanager/rediscaches" + rediscache "github.com/Azure/azure-service-operator/pkg/resourcemanager/rediscaches" resourcemanagerresourcegroup "github.com/Azure/azure-service-operator/pkg/resourcemanager/resourcegroups" blobContainerManager "github.com/Azure/azure-service-operator/pkg/resourcemanager/storages/blobcontainer" storageaccountManager "github.com/Azure/azure-service-operator/pkg/resourcemanager/storages/storageaccount" @@ -137,7 +137,11 @@ func main() { vnetManager := vnet.NewAzureVNetManager() resourceGroupManager := resourcemanagerresourcegroup.NewAzureResourceGroupManager() - redisCacheManager := resourcemanagerrediscache.NewAzureRedisCacheManager( + redisCacheManager := rediscache.NewAzureRedisCacheManager( + secretClient, + scheme, + ) + redisCacheActionManager := rediscache.NewAzureRedisCacheActionManager( secretClient, scheme, ) @@ -223,6 +227,7 @@ func main() { setupLog.Error(err, "unable to create controller", "controller", "CosmosDB") os.Exit(1) } + err = (&controllers.RedisCacheReconciler{ Reconciler: &controllers.AsyncReconciler{ Client: mgr.GetClient(), @@ -240,6 +245,22 @@ func main() { os.Exit(1) } + if err = (&controllers.RedisCacheActionReconciler{ + Reconciler: &controllers.AsyncReconciler{ + Client: mgr.GetClient(), + AzureClient: redisCacheActionManager, + Telemetry: telemetry.InitializeTelemetryDefault( + "RedisCacheAction", + ctrl.Log.WithName("controllers").WithName("RedisCacheAction"), + ), + Recorder: mgr.GetEventRecorderFor("RedisCacheAction-controller"), + Scheme: scheme, + }, + }).SetupWithManager(mgr); err != nil { + setupLog.Error(err, "unable to create controller", "controller", "RedisCacheAction") + os.Exit(1) + } + err = (&controllers.EventhubReconciler{ Reconciler: &controllers.AsyncReconciler{ Client: mgr.GetClient(), diff --git a/pkg/resourcemanager/interfaces.go b/pkg/resourcemanager/interfaces.go index 592d5d41208..01eac21aef2 100644 --- a/pkg/resourcemanager/interfaces.go +++ b/pkg/resourcemanager/interfaces.go @@ -10,6 +10,7 @@ import ( "github.com/Azure/azure-service-operator/pkg/secrets" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" + "sigs.k8s.io/controller-runtime/pkg/client" ) const ( @@ -18,19 +19,27 @@ const ( // Options contains the inputs available for passing to Ensure optionally type Options struct { + Client client.Client SecretClient secrets.SecretClient } // ConfigOption wraps a function that sets a value in the options struct type ConfigOption func(*Options) -// WithSecretClient can be used to pass aa KeyVault SecretClient +// WithSecretClient can be used to pass in a KeyVault SecretClient func WithSecretClient(secretClient secrets.SecretClient) ConfigOption { return func(op *Options) { op.SecretClient = secretClient } } +// WithClient can be used to pass in a k8s Client +func WithClient(client client.Client) ConfigOption { + return func(op *Options) { + op.Client = client + } +} + type KubeParent struct { Key types.NamespacedName Target runtime.Object diff --git a/pkg/resourcemanager/rediscaches/rediscache_manager.go b/pkg/resourcemanager/rediscaches/rediscache_manager.go index bc6b237cefe..4e573e2ebf1 100644 --- a/pkg/resourcemanager/rediscaches/rediscache_manager.go +++ b/pkg/resourcemanager/rediscaches/rediscache_manager.go @@ -14,11 +14,11 @@ import ( // RedisCacheManager for RedisCache type RedisCacheManager interface { // CreateRedisCache creates a new RedisCache - CreateRedisCache(ctx context.Context, - instance azurev1alpha1.RedisCache) (*redis.ResourceType, error) + CreateRedisCache(ctx context.Context, instance azurev1alpha1.RedisCache) (*redis.ResourceType, error) // DeleteRedisCache removes the resource group named by env var DeleteRedisCache(ctx context.Context, groupName string, redisCacheName string) (result redis.DeleteFuture, err error) + // also embed async client methods resourcemanager.ARMClient } diff --git a/pkg/resourcemanager/rediscaches/rediscache_reconcile.go b/pkg/resourcemanager/rediscaches/rediscache_reconcile.go index 72a5128cfdf..c3f94aaaccf 100644 --- a/pkg/resourcemanager/rediscaches/rediscache_reconcile.go +++ b/pkg/resourcemanager/rediscaches/rediscache_reconcile.go @@ -47,7 +47,7 @@ func (rc *AzureRedisCacheManager) Ensure(ctx context.Context, obj runtime.Object // succeeded! so end reconcilliation successfully if newRc.ProvisioningState == "Succeeded" { - err = rc.ListKeysAndCreateSecrets(groupName, redisName, instance.Spec.SecretName, instance) + err = rc.ListKeysAndCreateSecrets(ctx, groupName, redisName, instance.Spec.SecretName, instance) if err != nil { instance.Status.Message = err.Error() return false, err diff --git a/pkg/resourcemanager/rediscaches/rediscacheaction_manager.go b/pkg/resourcemanager/rediscaches/rediscacheaction_manager.go new file mode 100644 index 00000000000..e4250fd0419 --- /dev/null +++ b/pkg/resourcemanager/rediscaches/rediscacheaction_manager.go @@ -0,0 +1,20 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +package rediscaches + +import ( + "context" + + "github.com/Azure/azure-service-operator/pkg/resourcemanager" +) + +// RedisCacheActionManager for RedisCache +type RedisCacheActionManager interface { + RegeneratePrimaryAccessKey(ctx context.Context, resourceGroup string, cacheName string) (string, error) + + RegenerateSecondaryAccessKey(ctx context.Context, resourceGroup string, cacheName string) (string, error) + + // also embed async client methods + resourcemanager.ARMClient +} diff --git a/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go b/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go new file mode 100644 index 00000000000..c7fa89ffe3b --- /dev/null +++ b/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go @@ -0,0 +1,121 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +package rediscaches + +import ( + "context" + "fmt" + + "github.com/Azure/azure-service-operator/api/v1alpha1" + "github.com/Azure/azure-service-operator/pkg/resourcemanager" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" +) + +func (m *AzureRedisCacheActionManager) Ensure(ctx context.Context, obj runtime.Object, opts ...resourcemanager.ConfigOption) (bool, error) { + options := &resourcemanager.Options{} + for _, opt := range opts { + opt(options) + } + + actionInstance, err := m.convert(obj) + if err != nil { + return true, err + } + + // never re-provision an action + if actionInstance.Status.Provisioned { + return true, nil + } + + // get the RedisCache instance to see if it's done provisioning and set it as an owner + cacheInstance := &v1alpha1.RedisCache{} + cacheName := types.NamespacedName{Name: actionInstance.Spec.CacheName, Namespace: actionInstance.Namespace} + err = options.Client.Get(ctx, cacheName, cacheInstance) + if err != nil { + return false, err + } + + if cacheInstance.Status.FailedProvisioning || cacheInstance.Status.Provisioning { + actionInstance.Status.Message = "Waiting for parent RedisCache to finish provisioning" + return false, nil + } + + rollAllKeys := actionInstance.Spec.ActionName == v1alpha1.RedisCacheActionNameRollAllKeys + + if rollAllKeys || actionInstance.Spec.ActionName == v1alpha1.RedisCacheActionNameRollPrimaryKey { + if err = m.RegeneratePrimaryAccessKey(ctx, actionInstance.Spec.ResourceGroup, actionInstance.Spec.CacheName); err != nil { + actionInstance.Status.Provisioned = false + actionInstance.Status.FailedProvisioning = true + return false, err + } + } + + if rollAllKeys || actionInstance.Spec.ActionName == v1alpha1.RedisCacheActionNameRollSecondaryKey { + if err = m.RegenerateSecondaryAccessKey(ctx, actionInstance.Spec.ResourceGroup, actionInstance.Spec.CacheName); err != nil { + actionInstance.Status.Provisioned = false + actionInstance.Status.FailedProvisioning = true + return false, err + } + } + + // regenerate the secret + if err = m.ListKeysAndCreateSecrets(ctx, actionInstance.Spec.ResourceGroup, actionInstance.Spec.CacheName, cacheInstance.Spec.SecretName, cacheInstance); err != nil { + actionInstance.Status.Provisioned = false + actionInstance.Status.FailedProvisioning = true + return false, err + } + + // successful return + actionInstance.Status.Provisioned = true + actionInstance.Status.FailedProvisioning = false + return true, nil +} + +func (m *AzureRedisCacheActionManager) Delete(ctx context.Context, obj runtime.Object, opts ...resourcemanager.ConfigOption) (bool, error) { + // no deletion necessary for deletion of action + return false, nil +} + +func (m *AzureRedisCacheActionManager) GetParents(obj runtime.Object) ([]resourcemanager.KubeParent, error) { + instance, err := m.convert(obj) + if err != nil { + return nil, err + } + + return []resourcemanager.KubeParent{ + { + Key: types.NamespacedName{ + Namespace: instance.Namespace, + Name: instance.Spec.ResourceGroup, + }, + Target: &v1alpha1.ResourceGroup{}, + }, + { + Key: types.NamespacedName{ + Namespace: instance.Namespace, + Name: instance.Spec.CacheName, + }, + Target: &v1alpha1.RedisCache{}, + }, + }, nil +} + +// GetStatus gets the ASOStatus +func (m *AzureRedisCacheActionManager) GetStatus(obj runtime.Object) (*v1alpha1.ASOStatus, error) { + instance, err := m.convert(obj) + if err != nil { + return nil, err + } + return &instance.Status, nil +} + +func (m *AzureRedisCacheActionManager) convert(obj runtime.Object) (*v1alpha1.RedisCacheAction, error) { + local, ok := obj.(*v1alpha1.RedisCacheAction) + if !ok { + return nil, fmt.Errorf("failed type assertion on kind: %s", obj.GetObjectKind().GroupVersionKind().String()) + } + return local, nil +} diff --git a/pkg/resourcemanager/rediscaches/rediscacheactions.go b/pkg/resourcemanager/rediscaches/rediscacheactions.go new file mode 100644 index 00000000000..64762d46c20 --- /dev/null +++ b/pkg/resourcemanager/rediscaches/rediscacheactions.go @@ -0,0 +1,63 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +package rediscaches + +import ( + "context" + + "github.com/Azure/azure-service-operator/pkg/secrets" + + model "github.com/Azure/azure-sdk-for-go/services/redis/mgmt/2018-03-01/redis" + + "k8s.io/apimachinery/pkg/runtime" +) + +// AzureRedisCacheActionManager creates a new RedisCacheManager +type AzureRedisCacheActionManager struct { + AzureRedisManager +} + +// NewAzureRedisCacheActionManager creates a new RedisCacheManager +func NewAzureRedisCacheActionManager(secretClient secrets.SecretClient, scheme *runtime.Scheme) *AzureRedisCacheActionManager { + return &AzureRedisCacheActionManager{ + AzureRedisManager{ + SecretClient: secretClient, + Scheme: scheme, + }, + } +} + +// RegeneratePrimaryAccessKey regenerates either the primary or secondary access keys +func (r *AzureRedisCacheActionManager) RegeneratePrimaryAccessKey(ctx context.Context, resourceGroup string, cacheName string) error { + client, err := getRedisCacheClient() + if err != nil { + return err + } + + _, err = client.RegenerateKey(ctx, resourceGroup, cacheName, model.RegenerateKeyParameters{ + KeyType: model.Primary, + }) + if err != nil { + return err + } + + return nil +} + +// RegenerateSecondaryAccessKey regenerates either the primary or secondary access keys +func (r *AzureRedisCacheActionManager) RegenerateSecondaryAccessKey(ctx context.Context, resourceGroup string, cacheName string) error { + client, err := getRedisCacheClient() + if err != nil { + return err + } + + _, err = client.RegenerateKey(ctx, resourceGroup, cacheName, model.RegenerateKeyParameters{ + KeyType: model.Secondary, + }) + if err != nil { + return err + } + + return nil +} diff --git a/pkg/resourcemanager/rediscaches/rediscaches.go b/pkg/resourcemanager/rediscaches/rediscaches.go index e7fd22bb484..8437c4be409 100644 --- a/pkg/resourcemanager/rediscaches/rediscaches.go +++ b/pkg/resourcemanager/rediscaches/rediscaches.go @@ -10,41 +10,26 @@ import ( "log" "github.com/Azure/azure-sdk-for-go/services/redis/mgmt/2018-03-01/redis" - model "github.com/Azure/azure-sdk-for-go/services/redis/mgmt/2018-03-01/redis" azurev1alpha1 "github.com/Azure/azure-service-operator/api/v1alpha1" "github.com/Azure/azure-service-operator/pkg/helpers" - "github.com/Azure/azure-service-operator/pkg/resourcemanager/config" - "github.com/Azure/azure-service-operator/pkg/resourcemanager/iam" "github.com/Azure/azure-service-operator/pkg/secrets" "github.com/Azure/go-autorest/autorest/to" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" ) // AzureRedisCacheManager creates a new RedisCacheManager type AzureRedisCacheManager struct { - SecretClient secrets.SecretClient - Scheme *runtime.Scheme + AzureRedisManager } // NewAzureRedisCacheManager creates a new RedisCacheManager func NewAzureRedisCacheManager(secretClient secrets.SecretClient, scheme *runtime.Scheme) *AzureRedisCacheManager { return &AzureRedisCacheManager{ - SecretClient: secretClient, - Scheme: scheme, - } -} - -func getRedisCacheClient() (redis.Client, error) { - redisClient := redis.NewClientWithBaseURI(config.BaseURI(), config.SubscriptionID()) - a, err := iam.GetResourceManagementAuthorizer() - if err != nil { - log.Println("failed to initialize authorizer: " + err.Error()) - return redisClient, err + AzureRedisManager{ + SecretClient: secretClient, + Scheme: scheme, + }, } - redisClient.Authorizer = a - redisClient.AddToUserAgent(config.UserAgent()) - return redisClient, nil } // CreateRedisCache creates a new RedisCache @@ -140,58 +125,3 @@ func (r *AzureRedisCacheManager) DeleteRedisCache(ctx context.Context, groupName } return redisClient.Delete(ctx, groupName, redisCacheName) } - -//ListKeys lists the keys for redis cache -func (r *AzureRedisCacheManager) ListKeys(ctx context.Context, resourceGroupName string, redisCacheName string) (result redis.AccessKeys, err error) { - redisClient, err := getRedisCacheClient() - if err != nil { - return result, err - } - return redisClient.ListKeys(ctx, resourceGroupName, redisCacheName) -} - -// CreateSecrets creates a secret for a redis cache -func (r *AzureRedisCacheManager) CreateSecrets(ctx context.Context, secretName string, instance *azurev1alpha1.RedisCache, data map[string][]byte) error { - key := types.NamespacedName{Name: secretName, Namespace: instance.Namespace} - - err := r.SecretClient.Upsert( - ctx, - key, - data, - secrets.WithOwner(instance), - secrets.WithScheme(r.Scheme), - ) - if err != nil { - return err - } - - return nil -} - -// ListKeysAndCreateSecrets lists keys and creates secrets -func (r *AzureRedisCacheManager) ListKeysAndCreateSecrets(resourceGroupName string, redisCacheName string, secretName string, instance *azurev1alpha1.RedisCache) error { - var err error - var result model.AccessKeys - ctx := context.Background() - - result, err = r.ListKeys(ctx, resourceGroupName, redisCacheName) - if err != nil { - return err - } - data := map[string][]byte{ - "primaryKey": []byte(*result.PrimaryKey), - "secondaryKey": []byte(*result.SecondaryKey), - } - - err = r.CreateSecrets( - ctx, - secretName, - instance, - data, - ) - if err != nil { - return err - } - - return nil -} diff --git a/pkg/resourcemanager/rediscaches/shared.go b/pkg/resourcemanager/rediscaches/shared.go new file mode 100644 index 00000000000..4b560d7f204 --- /dev/null +++ b/pkg/resourcemanager/rediscaches/shared.go @@ -0,0 +1,88 @@ +package rediscaches + +import ( + "context" + "log" + + "github.com/Azure/azure-service-operator/api/v1alpha1" + "github.com/Azure/azure-service-operator/pkg/resourcemanager/config" + "github.com/Azure/azure-service-operator/pkg/resourcemanager/iam" + "github.com/Azure/azure-service-operator/pkg/secrets" + + "github.com/Azure/azure-sdk-for-go/services/redis/mgmt/2018-03-01/redis" + + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" +) + +// AzureRedisManager +type AzureRedisManager struct { + SecretClient secrets.SecretClient + Scheme *runtime.Scheme +} + +func getRedisCacheClient() (redis.Client, error) { + redisClient := redis.NewClientWithBaseURI(config.BaseURI(), config.SubscriptionID()) + a, err := iam.GetResourceManagementAuthorizer() + if err != nil { + log.Println("failed to initialize authorizer: " + err.Error()) + return redisClient, err + } + redisClient.Authorizer = a + redisClient.AddToUserAgent(config.UserAgent()) + return redisClient, nil +} + +//ListKeys lists the keys for redis cache +func (r *AzureRedisManager) ListKeys(ctx context.Context, resourceGroupName string, redisCacheName string) (result redis.AccessKeys, err error) { + redisClient, err := getRedisCacheClient() + if err != nil { + return result, err + } + return redisClient.ListKeys(ctx, resourceGroupName, redisCacheName) +} + +// CreateSecrets creates a secret for a redis cache +func (r *AzureRedisManager) CreateSecrets(ctx context.Context, secretName string, instance *v1alpha1.RedisCache, data map[string][]byte) error { + key := types.NamespacedName{Name: secretName, Namespace: instance.Namespace} + + err := r.SecretClient.Upsert( + ctx, + key, + data, + secrets.WithOwner(instance), + secrets.WithScheme(r.Scheme), + ) + if err != nil { + return err + } + + return nil +} + +// ListKeysAndCreateSecrets lists keys and creates secrets +func (r *AzureRedisManager) ListKeysAndCreateSecrets(ctx context.Context, resourceGroupName string, redisCacheName string, secretName string, instance *v1alpha1.RedisCache) error { + var err error + var result redis.AccessKeys + + result, err = r.ListKeys(ctx, resourceGroupName, redisCacheName) + if err != nil { + return err + } + data := map[string][]byte{ + "primaryKey": []byte(*result.PrimaryKey), + "secondaryKey": []byte(*result.SecondaryKey), + } + + err = r.CreateSecrets( + ctx, + secretName, + instance, + data, + ) + if err != nil { + return err + } + + return nil +} From 423ff13354d8eb0229331a317fa6e908af8f4460 Mon Sep 17 00:00:00 2001 From: jpflueger Date: Tue, 26 May 2020 16:12:48 -0600 Subject: [PATCH 02/10] improvements for generate-test-certs target --- Makefile | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index f92f6340700..5807017093c 100644 --- a/Makefile +++ b/Makefile @@ -19,22 +19,33 @@ TEST_RESOURCE_PREFIX ?= aso-$(BUILD_ID) # Go compiler builds tags: some parts of the test suite use these to selectively compile tests. BUILD_TAGS ?= all -# Temp directory variable, set by environment on macOS and set to default for everything else -TMPDIR ?= /tmp/ +ifdef TMPDIR +TMPDIR := $(realpath ${TMPDIR}) +else +TMPDIR := /tmp +endif all: manager # Generate test certs for development +generate-test-certs: CONFIGTXT := $(shell mktemp) +generate-test-certs: WEBHOOK_DIR := $(TMPDIR)/k8s-webhook-server +generate-test-certs: WEBHOOK_CERT_DIR := $(TMPDIR)/k8s-webhook-server/serving-certs generate-test-certs: - echo "[req]" > config.txt - echo "distinguished_name = req_distinguished_name" >> config.txt - echo "[req_distinguished_name]" >> config.txt - echo "[SAN]" >> config.txt - echo "subjectAltName=DNS:azureoperator-webhook-service.azureoperator-system.svc.cluster.local" >> config.txt - openssl req -x509 -days 730 -out tls.crt -keyout tls.key -newkey rsa:4096 -subj "/CN=azureoperator-webhook-service.azureoperator-system" -config config.txt -nodes - rm -rf $(TMPDIR)/k8s-webhook-server - mkdir -p $(TMPDIR)/k8s-webhook-server/serving-certs - mv tls.* $(TMPDIR)/k8s-webhook-server/serving-certs/ + rm -rf $(WEBHOOK_DIR) + mkdir -p $(WEBHOOK_CERT_DIR) + + @echo "[req]" > $(CONFIGTXT) + @echo "distinguished_name = req_distinguished_name" >> $(CONFIGTXT) + @echo "[req_distinguished_name]" >> $(CONFIGTXT) + @echo "[SAN]" >> $(CONFIGTXT) + @echo "subjectAltName=DNS:azureoperator-webhook-service.azureoperator-system.svc.cluster.local" >> $(CONFIGTXT) + + @echo "OpenSSL Config:" + @cat $(CONFIGTXT) + @echo + + openssl req -x509 -days 730 -out $(WEBHOOK_CERT_DIR)/tls.crt -keyout $(WEBHOOK_CERT_DIR)/tls.key -newkey rsa:4096 -subj "/CN=azureoperator-webhook-service.azureoperator-system" -config $(CONFIGTXT) -nodes # Run Controller tests against the configured cluster test-integration-controllers: generate fmt vet manifests From 1018029971094ee462c1c124ecf2d57e0455a875 Mon Sep 17 00:00:00 2001 From: jpflueger Date: Wed, 27 May 2020 13:58:48 -0600 Subject: [PATCH 03/10] addressing pr feedback, getting owner in kube secret client --- controllers/async_controller.go | 2 - pkg/resourcemanager/interfaces.go | 9 ---- .../rediscaches/rediscache_reconcile.go | 11 ++-- .../rediscaches/rediscacheaction_reconcile.go | 53 ++++++++----------- pkg/resourcemanager/rediscaches/shared.go | 12 +++-- pkg/secrets/interface.go | 11 ++-- pkg/secrets/kube/client.go | 8 +++ 7 files changed, 49 insertions(+), 57 deletions(-) diff --git a/controllers/async_controller.go b/controllers/async_controller.go index 0f37b75e5ff..cc1f732a74b 100644 --- a/controllers/async_controller.go +++ b/controllers/async_controller.go @@ -157,8 +157,6 @@ func (r *AsyncReconciler) Reconcile(req ctrl.Request, obj runtime.Object) (resul r.Telemetry.LogInfoByInstance("status", "reconciling object", req.String()) - configOptions = append(configOptions, resourcemanager.WithClient(r.Client)) - if len(KeyVaultName) != 0 { //KeyVault was specified in Spec, so use that for secrets configOptions = append(configOptions, resourcemanager.WithSecretClient(keyvaultSecretClient)) } diff --git a/pkg/resourcemanager/interfaces.go b/pkg/resourcemanager/interfaces.go index 01eac21aef2..2b6fd7cf57d 100644 --- a/pkg/resourcemanager/interfaces.go +++ b/pkg/resourcemanager/interfaces.go @@ -10,7 +10,6 @@ import ( "github.com/Azure/azure-service-operator/pkg/secrets" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" - "sigs.k8s.io/controller-runtime/pkg/client" ) const ( @@ -19,7 +18,6 @@ const ( // Options contains the inputs available for passing to Ensure optionally type Options struct { - Client client.Client SecretClient secrets.SecretClient } @@ -33,13 +31,6 @@ func WithSecretClient(secretClient secrets.SecretClient) ConfigOption { } } -// WithClient can be used to pass in a k8s Client -func WithClient(client client.Client) ConfigOption { - return func(op *Options) { - op.Client = client - } -} - type KubeParent struct { Key types.NamespacedName Target runtime.Object diff --git a/pkg/resourcemanager/rediscaches/rediscache_reconcile.go b/pkg/resourcemanager/rediscaches/rediscache_reconcile.go index c3f94aaaccf..740170ac22b 100644 --- a/pkg/resourcemanager/rediscaches/rediscache_reconcile.go +++ b/pkg/resourcemanager/rediscaches/rediscache_reconcile.go @@ -33,21 +33,16 @@ func (rc *AzureRedisCacheManager) Ensure(ctx context.Context, obj runtime.Object return false, err } - redisName := instance.Name + name := types.NamespacedName{Name: instance.Name, Namespace: instance.Namespace} groupName := instance.Spec.ResourceGroupName - name := instance.ObjectMeta.Name - - if len(instance.Spec.SecretName) == 0 { - instance.Spec.SecretName = redisName - } // if an error occurs thats ok as it means that it doesn't exist yet - newRc, err := rc.GetRedisCache(ctx, groupName, name) + newRc, err := rc.GetRedisCache(ctx, groupName, name.Name) if err == nil { // succeeded! so end reconcilliation successfully if newRc.ProvisioningState == "Succeeded" { - err = rc.ListKeysAndCreateSecrets(ctx, groupName, redisName, instance.Spec.SecretName, instance) + err = rc.ListKeysAndCreateSecrets(ctx, instance) if err != nil { instance.Status.Message = err.Error() return false, err diff --git a/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go b/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go index c7fa89ffe3b..61421e7e1bb 100644 --- a/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go +++ b/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go @@ -9,7 +9,7 @@ import ( "github.com/Azure/azure-service-operator/api/v1alpha1" "github.com/Azure/azure-service-operator/pkg/resourcemanager" - + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/types" ) @@ -20,57 +20,50 @@ func (m *AzureRedisCacheActionManager) Ensure(ctx context.Context, obj runtime.O opt(options) } - actionInstance, err := m.convert(obj) + instance, err := m.convert(obj) if err != nil { return true, err } // never re-provision an action - if actionInstance.Status.Provisioned { + if instance.Status.Provisioned { return true, nil } - // get the RedisCache instance to see if it's done provisioning and set it as an owner - cacheInstance := &v1alpha1.RedisCache{} - cacheName := types.NamespacedName{Name: actionInstance.Spec.CacheName, Namespace: actionInstance.Namespace} - err = options.Client.Get(ctx, cacheName, cacheInstance) - if err != nil { - return false, err - } + rollAllKeys := instance.Spec.ActionName == v1alpha1.RedisCacheActionNameRollAllKeys - if cacheInstance.Status.FailedProvisioning || cacheInstance.Status.Provisioning { - actionInstance.Status.Message = "Waiting for parent RedisCache to finish provisioning" - return false, nil - } - - rollAllKeys := actionInstance.Spec.ActionName == v1alpha1.RedisCacheActionNameRollAllKeys - - if rollAllKeys || actionInstance.Spec.ActionName == v1alpha1.RedisCacheActionNameRollPrimaryKey { - if err = m.RegeneratePrimaryAccessKey(ctx, actionInstance.Spec.ResourceGroup, actionInstance.Spec.CacheName); err != nil { - actionInstance.Status.Provisioned = false - actionInstance.Status.FailedProvisioning = true + if rollAllKeys || instance.Spec.ActionName == v1alpha1.RedisCacheActionNameRollPrimaryKey { + if err = m.RegeneratePrimaryAccessKey(ctx, instance.Spec.ResourceGroup, instance.Spec.CacheName); err != nil { return false, err } } - if rollAllKeys || actionInstance.Spec.ActionName == v1alpha1.RedisCacheActionNameRollSecondaryKey { - if err = m.RegenerateSecondaryAccessKey(ctx, actionInstance.Spec.ResourceGroup, actionInstance.Spec.CacheName); err != nil { - actionInstance.Status.Provisioned = false - actionInstance.Status.FailedProvisioning = true + if rollAllKeys || instance.Spec.ActionName == v1alpha1.RedisCacheActionNameRollSecondaryKey { + if err = m.RegenerateSecondaryAccessKey(ctx, instance.Spec.ResourceGroup, instance.Spec.CacheName); err != nil { return false, err } } // regenerate the secret - if err = m.ListKeysAndCreateSecrets(ctx, actionInstance.Spec.ResourceGroup, actionInstance.Spec.CacheName, cacheInstance.Spec.SecretName, cacheInstance); err != nil { - actionInstance.Status.Provisioned = false - actionInstance.Status.FailedProvisioning = true + cacheInstance := &v1alpha1.RedisCache{ + ObjectMeta: metav1.ObjectMeta{ + Name: instance.Spec.CacheName, + Namespace: instance.Namespace, + }, + Spec: v1alpha1.RedisCacheSpec{ + SecretName: instance.Spec.SecretName, + ResourceGroupName: instance.Spec.ResourceGroup, + }, + } + if err = m.ListKeysAndCreateSecrets(ctx, cacheInstance); err != nil { + instance.Status.Provisioned = false + instance.Status.FailedProvisioning = true return false, err } // successful return - actionInstance.Status.Provisioned = true - actionInstance.Status.FailedProvisioning = false + instance.Status.Provisioned = true + instance.Status.FailedProvisioning = false return true, nil } diff --git a/pkg/resourcemanager/rediscaches/shared.go b/pkg/resourcemanager/rediscaches/shared.go index 4b560d7f204..f475e277e52 100644 --- a/pkg/resourcemanager/rediscaches/shared.go +++ b/pkg/resourcemanager/rediscaches/shared.go @@ -43,7 +43,12 @@ func (r *AzureRedisManager) ListKeys(ctx context.Context, resourceGroupName stri } // CreateSecrets creates a secret for a redis cache -func (r *AzureRedisManager) CreateSecrets(ctx context.Context, secretName string, instance *v1alpha1.RedisCache, data map[string][]byte) error { +func (r *AzureRedisManager) CreateSecrets(ctx context.Context, instance *v1alpha1.RedisCache, data map[string][]byte) error { + secretName := instance.Spec.SecretName + if secretName == "" { + secretName = instance.Name + } + key := types.NamespacedName{Name: secretName, Namespace: instance.Namespace} err := r.SecretClient.Upsert( @@ -61,11 +66,11 @@ func (r *AzureRedisManager) CreateSecrets(ctx context.Context, secretName string } // ListKeysAndCreateSecrets lists keys and creates secrets -func (r *AzureRedisManager) ListKeysAndCreateSecrets(ctx context.Context, resourceGroupName string, redisCacheName string, secretName string, instance *v1alpha1.RedisCache) error { +func (r *AzureRedisManager) ListKeysAndCreateSecrets(ctx context.Context, instance *v1alpha1.RedisCache) error { var err error var result redis.AccessKeys - result, err = r.ListKeys(ctx, resourceGroupName, redisCacheName) + result, err = r.ListKeys(ctx, instance.Spec.ResourceGroupName, instance.Name) if err != nil { return err } @@ -76,7 +81,6 @@ func (r *AzureRedisManager) ListKeysAndCreateSecrets(ctx context.Context, resour err = r.CreateSecrets( ctx, - secretName, instance, data, ) diff --git a/pkg/secrets/interface.go b/pkg/secrets/interface.go index 4d53da3ea1f..fce3cea915e 100644 --- a/pkg/secrets/interface.go +++ b/pkg/secrets/interface.go @@ -9,7 +9,6 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" ) @@ -20,9 +19,14 @@ type SecretClient interface { Get(ctx context.Context, key types.NamespacedName) (map[string][]byte, error) } +type SecretOwner interface { + runtime.Object + metav1.Object +} + // Options contains the inputs available for passing to some methods of the secret clients type Options struct { - Owner metav1.Object + Owner SecretOwner Scheme *runtime.Scheme Activates *time.Time Expires *time.Time @@ -47,11 +51,10 @@ func WithExpiration(expireAfter *time.Time) SecretOption { } // WithOwner allows setting an owning instance in the options struct -func WithOwner(owner metav1.Object) SecretOption { +func WithOwner(owner SecretOwner) SecretOption { return func(op *Options) { op.Owner = owner } - } // WithScheme allows setting a runtime.Scheme in the options diff --git a/pkg/secrets/kube/client.go b/pkg/secrets/kube/client.go index b84c00fe0cd..e9ff7e186df 100644 --- a/pkg/secrets/kube/client.go +++ b/pkg/secrets/kube/client.go @@ -86,6 +86,14 @@ func (k *KubeSecretClient) Upsert(ctx context.Context, key types.NamespacedName, } if options.Owner != nil && options.Scheme != nil { + // the uid is required for SetControllerReference, try to populate it if it isn't + if options.Owner.GetUID() == "" { + ownerKey := types.NamespacedName{Name: options.Owner.GetName(), Namespace: options.Owner.GetNamespace()} + if err := k.KubeClient.Get(ctx, ownerKey, options.Owner); err != nil { + return err + } + } + if err := controllerutil.SetControllerReference(options.Owner, secret, options.Scheme); err != nil { return err } From 56039d7058caed7f3d541c6093b00cad5e78f96a Mon Sep 17 00:00:00 2001 From: jpflueger Date: Wed, 27 May 2020 14:03:58 -0600 Subject: [PATCH 04/10] add missing copyright header --- pkg/resourcemanager/rediscaches/shared.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/resourcemanager/rediscaches/shared.go b/pkg/resourcemanager/rediscaches/shared.go index f475e277e52..c1f28519fa4 100644 --- a/pkg/resourcemanager/rediscaches/shared.go +++ b/pkg/resourcemanager/rediscaches/shared.go @@ -1,3 +1,6 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + package rediscaches import ( From 1e410a44d21f78a3fadd08b3543f7ecec29ee82b Mon Sep 17 00:00:00 2001 From: jpflueger Date: Thu, 28 May 2020 10:32:45 -0600 Subject: [PATCH 05/10] adding status messages --- pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go b/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go index 61421e7e1bb..d9682fd3eb6 100644 --- a/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go +++ b/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go @@ -34,12 +34,14 @@ func (m *AzureRedisCacheActionManager) Ensure(ctx context.Context, obj runtime.O if rollAllKeys || instance.Spec.ActionName == v1alpha1.RedisCacheActionNameRollPrimaryKey { if err = m.RegeneratePrimaryAccessKey(ctx, instance.Spec.ResourceGroup, instance.Spec.CacheName); err != nil { + instance.Status.Message = err.Error() return false, err } } if rollAllKeys || instance.Spec.ActionName == v1alpha1.RedisCacheActionNameRollSecondaryKey { if err = m.RegenerateSecondaryAccessKey(ctx, instance.Spec.ResourceGroup, instance.Spec.CacheName); err != nil { + instance.Status.Message = err.Error() return false, err } } @@ -58,12 +60,14 @@ func (m *AzureRedisCacheActionManager) Ensure(ctx context.Context, obj runtime.O if err = m.ListKeysAndCreateSecrets(ctx, cacheInstance); err != nil { instance.Status.Provisioned = false instance.Status.FailedProvisioning = true + instance.Status.Message = err.Error() return false, err } // successful return instance.Status.Provisioned = true instance.Status.FailedProvisioning = false + instance.Status.Message = resourcemanager.SuccessMsg return true, nil } From c5cf5df92e50ba78861bcda84a25ef2e0d8577ca Mon Sep 17 00:00:00 2001 From: jpflueger Date: Fri, 29 May 2020 07:34:25 -0600 Subject: [PATCH 06/10] fixing rediscacheaction parent ordering --- .../rediscaches/rediscacheaction_reconcile.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go b/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go index d9682fd3eb6..222c353128e 100644 --- a/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go +++ b/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go @@ -86,16 +86,16 @@ func (m *AzureRedisCacheActionManager) GetParents(obj runtime.Object) ([]resourc { Key: types.NamespacedName{ Namespace: instance.Namespace, - Name: instance.Spec.ResourceGroup, + Name: instance.Spec.CacheName, }, - Target: &v1alpha1.ResourceGroup{}, + Target: &v1alpha1.RedisCache{}, }, { Key: types.NamespacedName{ Namespace: instance.Namespace, - Name: instance.Spec.CacheName, + Name: instance.Spec.ResourceGroup, }, - Target: &v1alpha1.RedisCache{}, + Target: &v1alpha1.ResourceGroup{}, }, }, nil } From 746b0992e124598b712e79d963e7d6cba43ebc6a Mon Sep 17 00:00:00 2001 From: jpflueger Date: Fri, 29 May 2020 07:41:05 -0600 Subject: [PATCH 07/10] moving actions into sub-package --- config/samples/azure_v1alpha1_rediscacheaction.yaml | 2 +- config/samples/azure_v1alpha1_resourcegroup.yaml | 4 ++-- main.go | 3 ++- .../{ => actions}/rediscacheaction_manager.go | 2 +- .../{ => actions}/rediscacheaction_reconcile.go | 2 +- .../rediscaches/{ => actions}/rediscacheactions.go | 11 ++++++----- pkg/resourcemanager/rediscaches/rediscaches.go | 6 +++--- pkg/resourcemanager/rediscaches/shared.go | 4 ++-- 8 files changed, 18 insertions(+), 16 deletions(-) rename pkg/resourcemanager/rediscaches/{ => actions}/rediscacheaction_manager.go (96%) rename pkg/resourcemanager/rediscaches/{ => actions}/rediscacheaction_reconcile.go (99%) rename pkg/resourcemanager/rediscaches/{ => actions}/rediscacheactions.go (86%) diff --git a/config/samples/azure_v1alpha1_rediscacheaction.yaml b/config/samples/azure_v1alpha1_rediscacheaction.yaml index fa0c9fa15f1..e679e97eb38 100644 --- a/config/samples/azure_v1alpha1_rediscacheaction.yaml +++ b/config/samples/azure_v1alpha1_rediscacheaction.yaml @@ -3,7 +3,7 @@ kind: RedisCacheAction metadata: name: rediscacheaction-sample-1 spec: - resourceGroup: resourcegroup-azure-operators + resourceGroup: jupflueg-aso-rg cacheName: rediscache-sample-1 # possible values are 'rollallkeys', 'rollprimarykey', 'rollsecondarykey' diff --git a/config/samples/azure_v1alpha1_resourcegroup.yaml b/config/samples/azure_v1alpha1_resourcegroup.yaml index ad6203b828d..deb2dd6b144 100644 --- a/config/samples/azure_v1alpha1_resourcegroup.yaml +++ b/config/samples/azure_v1alpha1_resourcegroup.yaml @@ -1,6 +1,6 @@ apiVersion: azure.microsoft.com/v1alpha1 kind: ResourceGroup metadata: - name: resourcegroup-azure-operators + name: jupflueg-aso-rg spec: - location: "westus" + location: eastus diff --git a/main.go b/main.go index f70787d6b1f..7f532aee160 100644 --- a/main.go +++ b/main.go @@ -49,6 +49,7 @@ import ( psqlserver "github.com/Azure/azure-service-operator/pkg/resourcemanager/psql/server" psqlvnetrule "github.com/Azure/azure-service-operator/pkg/resourcemanager/psql/vnetrule" rediscache "github.com/Azure/azure-service-operator/pkg/resourcemanager/rediscaches" + rediscacheactions "github.com/Azure/azure-service-operator/pkg/resourcemanager/rediscaches/actions" resourcemanagerresourcegroup "github.com/Azure/azure-service-operator/pkg/resourcemanager/resourcegroups" blobContainerManager "github.com/Azure/azure-service-operator/pkg/resourcemanager/storages/blobcontainer" storageaccountManager "github.com/Azure/azure-service-operator/pkg/resourcemanager/storages/storageaccount" @@ -142,7 +143,7 @@ func main() { secretClient, scheme, ) - redisCacheActionManager := rediscache.NewAzureRedisCacheActionManager( + redisCacheActionManager := rediscacheactions.NewAzureRedisCacheActionManager( secretClient, scheme, ) diff --git a/pkg/resourcemanager/rediscaches/rediscacheaction_manager.go b/pkg/resourcemanager/rediscaches/actions/rediscacheaction_manager.go similarity index 96% rename from pkg/resourcemanager/rediscaches/rediscacheaction_manager.go rename to pkg/resourcemanager/rediscaches/actions/rediscacheaction_manager.go index e4250fd0419..ff47d73fc08 100644 --- a/pkg/resourcemanager/rediscaches/rediscacheaction_manager.go +++ b/pkg/resourcemanager/rediscaches/actions/rediscacheaction_manager.go @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -package rediscaches +package actions import ( "context" diff --git a/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go b/pkg/resourcemanager/rediscaches/actions/rediscacheaction_reconcile.go similarity index 99% rename from pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go rename to pkg/resourcemanager/rediscaches/actions/rediscacheaction_reconcile.go index 222c353128e..52f27c1429d 100644 --- a/pkg/resourcemanager/rediscaches/rediscacheaction_reconcile.go +++ b/pkg/resourcemanager/rediscaches/actions/rediscacheaction_reconcile.go @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -package rediscaches +package actions import ( "context" diff --git a/pkg/resourcemanager/rediscaches/rediscacheactions.go b/pkg/resourcemanager/rediscaches/actions/rediscacheactions.go similarity index 86% rename from pkg/resourcemanager/rediscaches/rediscacheactions.go rename to pkg/resourcemanager/rediscaches/actions/rediscacheactions.go index 64762d46c20..bfc64a7595a 100644 --- a/pkg/resourcemanager/rediscaches/rediscacheactions.go +++ b/pkg/resourcemanager/rediscaches/actions/rediscacheactions.go @@ -1,11 +1,12 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -package rediscaches +package actions import ( "context" + "github.com/Azure/azure-service-operator/pkg/resourcemanager/rediscaches" "github.com/Azure/azure-service-operator/pkg/secrets" model "github.com/Azure/azure-sdk-for-go/services/redis/mgmt/2018-03-01/redis" @@ -15,13 +16,13 @@ import ( // AzureRedisCacheActionManager creates a new RedisCacheManager type AzureRedisCacheActionManager struct { - AzureRedisManager + rediscaches.AzureRedisManager } // NewAzureRedisCacheActionManager creates a new RedisCacheManager func NewAzureRedisCacheActionManager(secretClient secrets.SecretClient, scheme *runtime.Scheme) *AzureRedisCacheActionManager { return &AzureRedisCacheActionManager{ - AzureRedisManager{ + rediscaches.AzureRedisManager{ SecretClient: secretClient, Scheme: scheme, }, @@ -30,7 +31,7 @@ func NewAzureRedisCacheActionManager(secretClient secrets.SecretClient, scheme * // RegeneratePrimaryAccessKey regenerates either the primary or secondary access keys func (r *AzureRedisCacheActionManager) RegeneratePrimaryAccessKey(ctx context.Context, resourceGroup string, cacheName string) error { - client, err := getRedisCacheClient() + client, err := r.GetRedisCacheClient() if err != nil { return err } @@ -47,7 +48,7 @@ func (r *AzureRedisCacheActionManager) RegeneratePrimaryAccessKey(ctx context.Co // RegenerateSecondaryAccessKey regenerates either the primary or secondary access keys func (r *AzureRedisCacheActionManager) RegenerateSecondaryAccessKey(ctx context.Context, resourceGroup string, cacheName string) error { - client, err := getRedisCacheClient() + client, err := r.GetRedisCacheClient() if err != nil { return err } diff --git a/pkg/resourcemanager/rediscaches/rediscaches.go b/pkg/resourcemanager/rediscaches/rediscaches.go index 8437c4be409..510afd36c8f 100644 --- a/pkg/resourcemanager/rediscaches/rediscaches.go +++ b/pkg/resourcemanager/rediscaches/rediscaches.go @@ -42,7 +42,7 @@ func (r *AzureRedisCacheManager) CreateRedisCache( // convert kube labels to expected tag format tags := helpers.LabelsToTags(instance.GetLabels()) - redisClient, err := getRedisCacheClient() + redisClient, err := r.GetRedisCacheClient() if err != nil { return nil, err } @@ -110,7 +110,7 @@ func (r *AzureRedisCacheManager) CreateRedisCache( // GetRedisCache returns a redis cache object if it exists func (r *AzureRedisCacheManager) GetRedisCache(ctx context.Context, groupName string, redisCacheName string) (result redis.ResourceType, err error) { - redisClient, err := getRedisCacheClient() + redisClient, err := r.GetRedisCacheClient() if err != nil { return result, err } @@ -119,7 +119,7 @@ func (r *AzureRedisCacheManager) GetRedisCache(ctx context.Context, groupName st // DeleteRedisCache removes the resource group named by env var func (r *AzureRedisCacheManager) DeleteRedisCache(ctx context.Context, groupName string, redisCacheName string) (result redis.DeleteFuture, err error) { - redisClient, err := getRedisCacheClient() + redisClient, err := r.GetRedisCacheClient() if err != nil { return result, err } diff --git a/pkg/resourcemanager/rediscaches/shared.go b/pkg/resourcemanager/rediscaches/shared.go index c1f28519fa4..b6c3aaa4638 100644 --- a/pkg/resourcemanager/rediscaches/shared.go +++ b/pkg/resourcemanager/rediscaches/shared.go @@ -24,7 +24,7 @@ type AzureRedisManager struct { Scheme *runtime.Scheme } -func getRedisCacheClient() (redis.Client, error) { +func (r *AzureRedisManager) GetRedisCacheClient() (redis.Client, error) { redisClient := redis.NewClientWithBaseURI(config.BaseURI(), config.SubscriptionID()) a, err := iam.GetResourceManagementAuthorizer() if err != nil { @@ -38,7 +38,7 @@ func getRedisCacheClient() (redis.Client, error) { //ListKeys lists the keys for redis cache func (r *AzureRedisManager) ListKeys(ctx context.Context, resourceGroupName string, redisCacheName string) (result redis.AccessKeys, err error) { - redisClient, err := getRedisCacheClient() + redisClient, err := r.GetRedisCacheClient() if err != nil { return result, err } From cede2d5484d48abc74ac9317dc8d17fc8815e165 Mon Sep 17 00:00:00 2001 From: jpflueger Date: Fri, 29 May 2020 08:54:01 -0600 Subject: [PATCH 08/10] fixing secretclient for keyvault and samples --- config/samples/azure_v1alpha1_rediscacheaction.yaml | 3 +-- config/samples/azure_v1alpha1_resourcegroup.yaml | 4 ++-- .../rediscaches/actions/rediscacheaction_reconcile.go | 4 ++++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/config/samples/azure_v1alpha1_rediscacheaction.yaml b/config/samples/azure_v1alpha1_rediscacheaction.yaml index e679e97eb38..5042f016712 100644 --- a/config/samples/azure_v1alpha1_rediscacheaction.yaml +++ b/config/samples/azure_v1alpha1_rediscacheaction.yaml @@ -3,8 +3,7 @@ kind: RedisCacheAction metadata: name: rediscacheaction-sample-1 spec: - resourceGroup: jupflueg-aso-rg + resourceGroup: resourcegroup-azure-operators cacheName: rediscache-sample-1 - # possible values are 'rollallkeys', 'rollprimarykey', 'rollsecondarykey' actionName: rollallkeys \ No newline at end of file diff --git a/config/samples/azure_v1alpha1_resourcegroup.yaml b/config/samples/azure_v1alpha1_resourcegroup.yaml index deb2dd6b144..ad6203b828d 100644 --- a/config/samples/azure_v1alpha1_resourcegroup.yaml +++ b/config/samples/azure_v1alpha1_resourcegroup.yaml @@ -1,6 +1,6 @@ apiVersion: azure.microsoft.com/v1alpha1 kind: ResourceGroup metadata: - name: jupflueg-aso-rg + name: resourcegroup-azure-operators spec: - location: eastus + location: "westus" diff --git a/pkg/resourcemanager/rediscaches/actions/rediscacheaction_reconcile.go b/pkg/resourcemanager/rediscaches/actions/rediscacheaction_reconcile.go index 52f27c1429d..f4898558e98 100644 --- a/pkg/resourcemanager/rediscaches/actions/rediscacheaction_reconcile.go +++ b/pkg/resourcemanager/rediscaches/actions/rediscacheaction_reconcile.go @@ -20,6 +20,10 @@ func (m *AzureRedisCacheActionManager) Ensure(ctx context.Context, obj runtime.O opt(options) } + if options.SecretClient != nil { + m.SecretClient = options.SecretClient + } + instance, err := m.convert(obj) if err != nil { return true, err From fedd10858a3c4280642a6096cc95da563c3b2560 Mon Sep 17 00:00:00 2001 From: jpflueger Date: Fri, 29 May 2020 11:52:53 -0600 Subject: [PATCH 09/10] adding tests for rediscache actions --- controllers/rediscache_controller_test.go | 11 +-- .../rediscacheaction_controller_test.go | 73 +++++++++++++++++++ .../rediscachefirewallrule_controller_test.go | 2 +- controllers/suite_test.go | 24 +++++- 4 files changed, 100 insertions(+), 10 deletions(-) create mode 100644 controllers/rediscacheaction_controller_test.go diff --git a/controllers/rediscache_controller_test.go b/controllers/rediscache_controller_test.go index cdd352c8544..f2477120618 100644 --- a/controllers/rediscache_controller_test.go +++ b/controllers/rediscache_controller_test.go @@ -11,7 +11,6 @@ import ( "time" azurev1alpha1 "github.com/Azure/azure-service-operator/api/v1alpha1" - "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -22,14 +21,12 @@ func TestRedisCacheControllerHappyPath(t *testing.T) { t.Parallel() defer PanicRecover(t) ctx := context.Background() - assert := assert.New(t) var rgLocation string var rgName string var redisCacheName string - var err error - rgName = tc.resourceGroup + rgName = tc.resourceGroupName rgLocation = tc.resourceGroupLocation redisCacheName = GenerateTestResourceNameWithRandom("rediscache", 10) @@ -40,8 +37,8 @@ func TestRedisCacheControllerHappyPath(t *testing.T) { Namespace: "default", }, Spec: azurev1alpha1.RedisCacheSpec{ - Location: rgLocation, - ResourceGroup: rgName, + Location: rgLocation, + ResourceGroupName: rgName, Properties: azurev1alpha1.RedisCacheProperties{ Sku: azurev1alpha1.RedisCacheSku{ Name: "Basic", @@ -57,7 +54,7 @@ func TestRedisCacheControllerHappyPath(t *testing.T) { EnsureInstance(ctx, t, tc, redisCacheInstance) // verify secret exists in secretclient - EnsureSecrets(ctx, t, tc, redisCacheInstance, tc.SecretClient, redisCacheInstance.Name, redisCacheInstance.Namespace) + EnsureSecrets(ctx, t, tc, redisCacheInstance, tc.secretClient, redisCacheInstance.Name, redisCacheInstance.Namespace) // delete rc EnsureDelete(ctx, t, tc, redisCacheInstance) diff --git a/controllers/rediscacheaction_controller_test.go b/controllers/rediscacheaction_controller_test.go new file mode 100644 index 00000000000..b1f2ec76fda --- /dev/null +++ b/controllers/rediscacheaction_controller_test.go @@ -0,0 +1,73 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +// +build all rediscache + +package controllers + +import ( + "context" + "testing" + + azurev1alpha1 "github.com/Azure/azure-service-operator/api/v1alpha1" + "github.com/Azure/azure-service-operator/pkg/errhelp" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestRedisCacheActionControllerNoResourceGroup(t *testing.T) { + t.Parallel() + defer PanicRecover(t) + ctx := context.Background() + + var rgName string + var redisCache string + var redisCacheAction string + + rgName = GenerateTestResourceNameWithRandom("rcfwr-rg", 10) + redisCache = GenerateTestResourceNameWithRandom("rediscache", 10) + redisCacheAction = GenerateTestResourceNameWithRandom("rediscacheaction", 10) + + redisCacheActionInstance := &azurev1alpha1.RedisCacheAction{ + ObjectMeta: metav1.ObjectMeta{ + Name: redisCacheAction, + Namespace: "default", + }, + Spec: azurev1alpha1.RedisCacheActionSpec{ + ResourceGroup: rgName, + CacheName: redisCache, + ActionName: azurev1alpha1.RedisCacheActionNameRollAllKeys, + }, + } + + EnsureInstanceWithResult(ctx, t, tc, redisCacheActionInstance, errhelp.ResourceGroupNotFoundErrorCode, false) + EnsureDelete(ctx, t, tc, redisCacheActionInstance) +} + +func TestRedisCacheActionNoRedisCache(t *testing.T) { + t.Parallel() + defer PanicRecover(t) + ctx := context.Background() + + var rgName string + var redisCache string + var redisCacheAction string + + rgName = tc.resourceGroupName + redisCache = GenerateTestResourceNameWithRandom("rediscache", 10) + redisCacheAction = GenerateTestResourceNameWithRandom("rediscacheaction", 10) + + redisCacheActionInstance := &azurev1alpha1.RedisCacheAction{ + ObjectMeta: metav1.ObjectMeta{ + Name: redisCacheAction, + Namespace: "default", + }, + Spec: azurev1alpha1.RedisCacheActionSpec{ + ResourceGroup: rgName, + CacheName: redisCache, + ActionName: azurev1alpha1.RedisCacheActionNameRollAllKeys, + }, + } + EnsureInstanceWithResult(ctx, t, tc, redisCacheActionInstance, errhelp.ResourceNotFound, false) + EnsureDelete(ctx, t, tc, redisCacheActionInstance) +} diff --git a/controllers/rediscachefirewallrule_controller_test.go b/controllers/rediscachefirewallrule_controller_test.go index 802a53aefa1..60133420823 100644 --- a/controllers/rediscachefirewallrule_controller_test.go +++ b/controllers/rediscachefirewallrule_controller_test.go @@ -1,7 +1,7 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -// +build all resourcegroup +// +build all rediscache package controllers diff --git a/controllers/suite_test.go b/controllers/suite_test.go index e709a4f3202..b6459364ee0 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -45,8 +45,9 @@ import ( resourcemanagerpsqldatabase "github.com/Azure/azure-service-operator/pkg/resourcemanager/psql/database" resourcemanagerpsqlfirewallrule "github.com/Azure/azure-service-operator/pkg/resourcemanager/psql/firewallrule" resourcemanagerpsqlserver "github.com/Azure/azure-service-operator/pkg/resourcemanager/psql/server" + rediscacheactions "github.com/Azure/azure-service-operator/pkg/resourcemanager/rediscaches/actions" rcfwr "github.com/Azure/azure-service-operator/pkg/resourcemanager/rediscaches/firewallrule" - resourcemanagerrediscaches "github.com/Azure/azure-service-operator/pkg/resourcemanager/rediscaches/redis" + rediscaches "github.com/Azure/azure-service-operator/pkg/resourcemanager/rediscaches/redis" resourcegroupsresourcemanager "github.com/Azure/azure-service-operator/pkg/resourcemanager/resourcegroups" resourcemanagerblobcontainer "github.com/Azure/azure-service-operator/pkg/resourcemanager/storages/blobcontainer" resourcemanagerstorageaccount "github.com/Azure/azure-service-operator/pkg/resourcemanager/storages/storageaccount" @@ -271,7 +272,7 @@ func setup() error { err = (&RedisCacheReconciler{ Reconciler: &AsyncReconciler{ Client: k8sManager.GetClient(), - AzureClient: resourcemanagerrediscaches.NewAzureRedisCacheManager( + AzureClient: rediscaches.NewAzureRedisCacheManager( secretClient, scheme.Scheme, ), @@ -287,6 +288,25 @@ func setup() error { return err } + err = (&RedisCacheActionReconciler{ + Reconciler: &AsyncReconciler{ + Client: k8sManager.GetClient(), + AzureClient: rediscacheactions.NewAzureRedisCacheActionManager( + secretClient, + scheme.Scheme, + ), + Telemetry: telemetry.InitializeTelemetryDefault( + "RedisCacheAction", + ctrl.Log.WithName("controllers").WithName("RedisCacheAction"), + ), + Recorder: k8sManager.GetEventRecorderFor("RedisCacheAction-controller"), + Scheme: k8sManager.GetScheme(), + }, + }).SetupWithManager(k8sManager) + if err != nil { + return err + } + err = (&RedisCacheFirewallRuleReconciler{ Reconciler: &AsyncReconciler{ Client: k8sManager.GetClient(), From 63bbf42c01b3c26cb940c744113c40a14ba823b0 Mon Sep 17 00:00:00 2001 From: jpflueger Date: Fri, 29 May 2020 14:10:45 -0600 Subject: [PATCH 10/10] allowing kube secretclient to ignore not found errors --- pkg/secrets/kube/client.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/secrets/kube/client.go b/pkg/secrets/kube/client.go index e9ff7e186df..bee9d12264c 100644 --- a/pkg/secrets/kube/client.go +++ b/pkg/secrets/kube/client.go @@ -90,7 +90,7 @@ func (k *KubeSecretClient) Upsert(ctx context.Context, key types.NamespacedName, if options.Owner.GetUID() == "" { ownerKey := types.NamespacedName{Name: options.Owner.GetName(), Namespace: options.Owner.GetNamespace()} if err := k.KubeClient.Get(ctx, ownerKey, options.Owner); err != nil { - return err + return client.IgnoreNotFound(err) } }