diff --git a/Makefile b/Makefile index 1f1e94d..c1594f7 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ # To re-generate a bundle for another specific version without changing the standard setup, you can: # - use the VERSION as arg of the bundle target (e.g make bundle VERSION=0.0.2) # - use environment variables to overwrite this value (e.g export VERSION=0.0.2) -VERSION ?= 0.0.1 +VERSION ?= 0.0.2 # CHANNELS define the bundle channels used in the bundle. # Add a new line here if you would like to change its default config. (E.g CHANNELS = "candidate,fast,stable") diff --git a/README.md b/README.md index 6f838ef..fee87eb 100644 --- a/README.md +++ b/README.md @@ -571,6 +571,44 @@ the controller will attempt to discover credentials using the SDK, but then fall permissions identified from above. The resulting secret will be used. +###### Additional Permissions + +You can add permissions to the credentials minted by OpenShift via the Config object: + +```yaml +apiVersion: services.k8s.aws.cuppett.dev/v1alpha1 +kind: Config +metadata: + name: default + namespace: aws-cloudformation-operator-system +spec: + tags: + cluster: prod1 + additionalPermissions: + apiVersion: cloudcredential.openshift.io/v1 + kind: AWSProviderSpec + statementEntries: + - action: + - 's3:CreateBucket' + - 's3:ListBuckets' + effect: Allow + resource: '*' + ## Allowing all S3 actions against buckets owned by this cluster tag + - action: + - 's3:*' + effect: Allow + policyCondition: + StringEquals: + 'aws:ResourceTag/cluster': prod1 + resource: '*' +``` + +> NOTE: You *only* need supply additional permissions here. The default permissions will always be included in the `CredentialsRequest`. + +This is the easy way to allow the operator to create/manage resources in various services. +However, it should be more desirable to limit the operator to CloudFormation and iam:PassRole (default). +Using only PassRole enables you to set up OPA rules ensuring `Stack` objects in namespaces always specify `roleArn` in their objects and match any desired assignment conventions you may have. + #### Using kustomize & make to deploy Deploy and start the CloudFormation operator in your cluster by using the provided manifests and Makefile: diff --git a/apis/services.k8s.aws/v1alpha1/config_types.go b/apis/services.k8s.aws/v1alpha1/config_types.go index 79f67c8..c74b547 100644 --- a/apis/services.k8s.aws/v1alpha1/config_types.go +++ b/apis/services.k8s.aws/v1alpha1/config_types.go @@ -26,6 +26,7 @@ package v1alpha1 import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" ) // EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! @@ -37,6 +38,10 @@ type ConfigSpec struct { // +kubebuilder:validation:Optional // +optional Tags map[string]string `json:"tags,omitempty"` + // +kubebuilder:validation:Optional + // +kubebuilder:pruning:PreserveUnknownFields + // +optional + AdditionalPermissions *runtime.RawExtension `json:"additionalPermissions,omitempty"` } // ConfigStatus defines the observed state of Config diff --git a/apis/services.k8s.aws/v1alpha1/zz_generated.deepcopy.go b/apis/services.k8s.aws/v1alpha1/zz_generated.deepcopy.go index e3969f3..81cf1b2 100644 --- a/apis/services.k8s.aws/v1alpha1/zz_generated.deepcopy.go +++ b/apis/services.k8s.aws/v1alpha1/zz_generated.deepcopy.go @@ -30,7 +30,7 @@ SOFTWARE. package v1alpha1 import ( - runtime "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime" ) // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -102,6 +102,11 @@ func (in *ConfigSpec) DeepCopyInto(out *ConfigSpec) { (*out)[key] = val } } + if in.AdditionalPermissions != nil { + in, out := &in.AdditionalPermissions, &out.AdditionalPermissions + *out = new(runtime.RawExtension) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConfigSpec. diff --git a/bundle.Dockerfile b/bundle.Dockerfile index 9c0678d..c3ddf30 100644 --- a/bundle.Dockerfile +++ b/bundle.Dockerfile @@ -6,7 +6,7 @@ LABEL operators.operatorframework.io.bundle.manifests.v1=manifests/ LABEL operators.operatorframework.io.bundle.metadata.v1=metadata/ LABEL operators.operatorframework.io.bundle.package.v1=aws-cloudformation-operator LABEL operators.operatorframework.io.bundle.channels.v1=alpha -LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.15.0+git +LABEL operators.operatorframework.io.metrics.builder=operator-sdk-v1.14.0+git LABEL operators.operatorframework.io.metrics.mediatype.v1=metrics+v1 LABEL operators.operatorframework.io.metrics.project_layout=go.kubebuilder.io/v3 diff --git a/bundle/manifests/aws-cloudformation-operator.clusterserviceversion.yaml b/bundle/manifests/aws-cloudformation-operator.clusterserviceversion.yaml index 65966f7..ea3e298 100644 --- a/bundle/manifests/aws-cloudformation-operator.clusterserviceversion.yaml +++ b/bundle/manifests/aws-cloudformation-operator.clusterserviceversion.yaml @@ -53,9 +53,9 @@ metadata: ] capabilities: Basic Install operatorframework.io/suggested-namespace: aws-cloudformation-operator - operators.operatorframework.io/builder: operator-sdk-v1.15.0+git + operators.operatorframework.io/builder: operator-sdk-v1.14.0+git operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 - name: aws-cloudformation-operator.v0.0.1 + name: aws-cloudformation-operator.v0.0.2 namespace: placeholder spec: apiservicedefinitions: {} @@ -115,6 +115,8 @@ spec: - create - get - list + - patch + - update - watch - apiGroups: - cloudformation.services.k8s.aws.cuppett.dev @@ -201,6 +203,24 @@ spec: control-plane: controller-manager spec: containers: + - args: + - --secure-listen-address=0.0.0.0:8443 + - --upstream=http://127.0.0.1:8080/ + - --logtostderr=true + - --v=0 + image: quay.io/cuppett/kube-rbac-proxy:v0.11.0 + name: kube-rbac-proxy + ports: + - containerPort: 8443 + name: https + protocol: TCP + resources: + limits: + cpu: 500m + memory: 128Mi + requests: + cpu: 5m + memory: 64Mi - args: - --health-probe-bind-address=:8081 - --metrics-bind-address=127.0.0.1:8080 @@ -220,7 +240,7 @@ spec: valueFrom: fieldRef: fieldPath: metadata.annotations['olm.targetNamespaces'] - image: quay.io/cuppett/aws-cloudformation-operator:v0.0.1 + image: quay.io/cuppett/aws-cloudformation-operator:v0.0.2 livenessProbe: httpGet: path: /healthz @@ -244,24 +264,6 @@ spec: memory: 100Mi securityContext: allowPrivilegeEscalation: false - - args: - - --secure-listen-address=0.0.0.0:8443 - - --upstream=http://127.0.0.1:8080/ - - --logtostderr=true - - --v=0 - image: quay.io/cuppett/kube-rbac-proxy:v0.11.0 - name: kube-rbac-proxy - ports: - - containerPort: 8443 - name: https - protocol: TCP - resources: - limits: - cpu: 500m - memory: 128Mi - requests: - cpu: 5m - memory: 64Mi securityContext: runAsNonRoot: true serviceAccountName: aws-cloudformation-operator-controller-manager @@ -327,7 +329,8 @@ spec: provider: name: Stephen Cuppett url: https://github.com/cuppett - version: 0.0.1 + replaces: aws-cloudformation-operator.v0.0.1 + version: 0.0.2 webhookdefinitions: - admissionReviewVersions: - v1 diff --git a/bundle/manifests/cloudformation.services.k8s.aws.cuppett.dev_stacks.yaml b/bundle/manifests/cloudformation.services.k8s.aws.cuppett.dev_stacks.yaml index 1fd300b..7980f52 100644 --- a/bundle/manifests/cloudformation.services.k8s.aws.cuppett.dev_stacks.yaml +++ b/bundle/manifests/cloudformation.services.k8s.aws.cuppett.dev_stacks.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.8.0 creationTimestamp: null name: stacks.cloudformation.services.k8s.aws.cuppett.dev spec: diff --git a/bundle/manifests/services.k8s.aws.cuppett.dev_configs.yaml b/bundle/manifests/services.k8s.aws.cuppett.dev_configs.yaml index 42f72b3..5de73e2 100644 --- a/bundle/manifests/services.k8s.aws.cuppett.dev_configs.yaml +++ b/bundle/manifests/services.k8s.aws.cuppett.dev_configs.yaml @@ -2,7 +2,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.7.0 + controller-gen.kubebuilder.io/version: v0.8.0 creationTimestamp: null name: configs.services.k8s.aws.cuppett.dev spec: @@ -34,6 +34,9 @@ spec: spec: description: ConfigSpec defines the desired state of Config properties: + additionalPermissions: + type: object + x-kubernetes-preserve-unknown-fields: true region: type: string tags: diff --git a/bundle/metadata/annotations.yaml b/bundle/metadata/annotations.yaml index 550a5be..c454701 100644 --- a/bundle/metadata/annotations.yaml +++ b/bundle/metadata/annotations.yaml @@ -5,7 +5,7 @@ annotations: operators.operatorframework.io.bundle.metadata.v1: metadata/ operators.operatorframework.io.bundle.package.v1: aws-cloudformation-operator operators.operatorframework.io.bundle.channels.v1: alpha - operators.operatorframework.io.metrics.builder: operator-sdk-v1.15.0+git + operators.operatorframework.io.metrics.builder: operator-sdk-v1.14.0+git operators.operatorframework.io.metrics.mediatype.v1: metrics+v1 operators.operatorframework.io.metrics.project_layout: go.kubebuilder.io/v3 diff --git a/config/crd/bases/services.k8s.aws.cuppett.dev_configs.yaml b/config/crd/bases/services.k8s.aws.cuppett.dev_configs.yaml index beea784..45bd750 100644 --- a/config/crd/bases/services.k8s.aws.cuppett.dev_configs.yaml +++ b/config/crd/bases/services.k8s.aws.cuppett.dev_configs.yaml @@ -35,6 +35,9 @@ spec: spec: description: ConfigSpec defines the desired state of Config properties: + additionalPermissions: + type: object + x-kubernetes-preserve-unknown-fields: true region: type: string tags: diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index f99352a..926d67b 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -13,4 +13,4 @@ kind: Kustomization images: - name: controller newName: quay.io/cuppett/aws-cloudformation-operator - newTag: v0.0.1 + newTag: v0.0.2 diff --git a/config/manifests/bases/aws-cloudformation-operator.clusterserviceversion.yaml b/config/manifests/bases/aws-cloudformation-operator.clusterserviceversion.yaml index 1c35740..f67ad9c 100644 --- a/config/manifests/bases/aws-cloudformation-operator.clusterserviceversion.yaml +++ b/config/manifests/bases/aws-cloudformation-operator.clusterserviceversion.yaml @@ -5,7 +5,7 @@ metadata: alm-examples: '[]' capabilities: Basic Install operatorframework.io/suggested-namespace: aws-cloudformation-operator - name: aws-cloudformation-operator.v0.0.1 + name: aws-cloudformation-operator.v0.0.2 namespace: placeholder spec: apiservicedefinitions: {} @@ -56,4 +56,5 @@ spec: provider: name: Stephen Cuppett url: https://github.com/cuppett - version: 0.0.1 + replaces: aws-cloudformation-operator.v0.0.1 + version: 0.0.2 diff --git a/config/manifests/kustomization.yaml b/config/manifests/kustomization.yaml index 2b91e15..c721a5b 100644 --- a/config/manifests/kustomization.yaml +++ b/config/manifests/kustomization.yaml @@ -18,21 +18,21 @@ patchesJson6902: namespace: system patch: |- - op: remove - path: /spec/template/spec/containers/0/env/5 + path: /spec/template/spec/containers/1/env/5 - op: remove - path: /spec/template/spec/containers/0/env/4 + path: /spec/template/spec/containers/1/env/4 - op: remove - path: /spec/template/spec/containers/0/env/3 + path: /spec/template/spec/containers/1/env/3 - op: remove - path: /spec/template/spec/containers/0/env/2 + path: /spec/template/spec/containers/1/env/2 - op: remove - path: /spec/template/spec/containers/0/env/1 + path: /spec/template/spec/containers/1/env/1 - op: remove - path: /spec/template/spec/containers/0/env/0 + path: /spec/template/spec/containers/1/env/0 # Remove the manager container's "cert" volumeMount, since OLM will create and mount a set of certs. # Update the indices in this path if adding or removing containers/volumeMounts in the manager's Deployment. - op: remove - path: /spec/template/spec/containers/0/volumeMounts/0 + path: /spec/template/spec/containers/1/volumeMounts/0 # Remove the "cert" volume, since OLM will create and mount a set of certs. # Update the indices in this path if adding or removing volumes in the manager's Deployment. - op: remove diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index fa41ac0..5359ff1 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -40,6 +40,8 @@ rules: - create - get - list + - patch + - update - watch - apiGroups: - cloudformation.services.k8s.aws.cuppett.dev diff --git a/controllers/cloudformation.services.k8s.aws/stack_controller.go b/controllers/cloudformation.services.k8s.aws/stack_controller.go index 7960e62..4aed82a 100644 --- a/controllers/cloudformation.services.k8s.aws/stack_controller.go +++ b/controllers/cloudformation.services.k8s.aws/stack_controller.go @@ -31,6 +31,7 @@ import ( "github.com/cuppett/aws-cloudformation-operator/apis/cloudformation.services.k8s.aws/v1alpha1" v1 "k8s.io/api/core/v1" "sigs.k8s.io/controller-runtime/pkg/event" + "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/predicate" "strings" @@ -88,7 +89,7 @@ type StackLoop struct { // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.10.3/pkg/reconcile func (r *StackReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { loop := &StackLoop{ctx, req, &v1alpha1.Stack{}, nil, - r.Log.WithValues("Request.Namespace", req.Namespace, "Request.Name", req.Name)} + log.FromContext(ctx).WithValues("Request.Namespace", req.Namespace, "Request.Name", req.Name)} // Fetch the Stack instance err := r.Client.Get(loop.ctx, loop.req.NamespacedName, loop.instance) diff --git a/controllers/services.k8s.aws/config_controller.go b/controllers/services.k8s.aws/config_controller.go index 445cc47..a53dc31 100644 --- a/controllers/services.k8s.aws/config_controller.go +++ b/controllers/services.k8s.aws/config_controller.go @@ -26,6 +26,7 @@ package servicesk8saws import ( "context" + coreerrors "errors" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/config" "github.com/aws/aws-sdk-go-v2/service/cloudformation" @@ -82,6 +83,12 @@ func InitializeConfigReconciler(client client.Client, log logr.Logger, scheme *r return reconciler } +type ConfigLoop struct { + ctx context.Context + config *servicesv1alpha1.Config + Log logr.Logger +} + //+kubebuilder:rbac:groups=services.k8s.aws.cuppett.dev,resources=configs,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=services.k8s.aws.cuppett.dev,resources=configs/status,verbs=get;update;patch //+kubebuilder:rbac:groups=services.k8s.aws.cuppett.dev,resources=configs/finalizers,verbs=update @@ -96,10 +103,23 @@ func InitializeConfigReconciler(client client.Client, log logr.Logger, scheme *r // For more details, check Reconcile and its Result here: // - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.10.0/pkg/reconcile func (r *ConfigReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - _ = log.FromContext(ctx) + + loop := &ConfigLoop{ctx, &servicesv1alpha1.Config{}, + log.FromContext(ctx).WithValues("Request.Namespace", req.Namespace, "Request.Name", req.Name)} + + // Fetch the Stack instance + err := r.client.Get(loop.ctx, req.NamespacedName, loop.config) + if err != nil { + loop.Log.Error(err, "Failed to get Config") + return ctrl.Result{}, err + } + r.cfLock.Lock() - r.createCloudFormation() + r.createCloudFormation(loop) r.cfLock.Unlock() + + r.createOrUpdateCredentialRequest(loop) + return ctrl.Result{}, nil } @@ -149,45 +169,48 @@ func (r *ConfigReconciler) GetCloudFormation() *cloudformation.Client { if r.cloudFormation == nil { r.cfLock.Lock() if r.cloudFormation == nil { - r.createCloudFormation() + ctx := context.TODO() + loop := &ConfigLoop{ctx, r.getDefaultConfig(ctx), + log.FromContext(ctx)} + r.createCloudFormation(loop) } r.cfLock.Unlock() } return r.cloudFormation } -func (r *ConfigReconciler) createCloudFormation() { - cfg := r.loadConfig(context.TODO()) +func (r *ConfigReconciler) createCloudFormation(loop *ConfigLoop) { + cfg := r.loadConfig(loop) r.cloudFormation = cloudformation.NewFromConfig(*cfg) } -func (r *ConfigReconciler) loadConfig(ctx context.Context) *aws.Config { +func (r *ConfigReconciler) loadConfig(loop *ConfigLoop) *aws.Config { - cfg, err := config.LoadDefaultConfig(context.TODO()) + cfg, err := config.LoadDefaultConfig(loop.ctx) if err != nil { r.log.Error(err, "error getting AWS config") return nil } if cfg.Region == "" { - cfg.Region = r.getClusterRegion(ctx) + cfg.Region = r.getClusterRegion(loop) } r.log.Info("Region resolved", "region", cfg.Region) // Looking for credentials - credentials, err := cfg.Credentials.Retrieve(ctx) + credentials, err := cfg.Credentials.Retrieve(loop.ctx) // If the default ways didn't give it to us and we're in OpenShift Mint Mode - if (err != nil || !credentials.HasKeys()) && r.isMintMode(ctx) { + if (err != nil || !credentials.HasKeys()) && r.isMintMode(loop.ctx) { secret := &v12.Secret{} namespacedName := types.NamespacedName{ Namespace: podNamespace, Name: credSecretName, } - err = r.client.Get(ctx, namespacedName, secret) + err = r.client.Get(loop.ctx, namespacedName, secret) if err != nil { r.log.Info("Failed to get Secret", "error", err) - r.checkCredentialRequest(ctx) + r.createOrUpdateCredentialRequest(loop) } else { cfg.Credentials = &SecretProvider{ *secret, @@ -209,35 +232,67 @@ func (r *ConfigReconciler) loadConfig(ctx context.Context) *aws.Config { //+kubebuilder:rbac:groups=cloudcredential.openshift.io,resources=credentialsrequests,verbs=get;list;watch -func (r *ConfigReconciler) checkCredentialRequest(ctx context.Context) { +func (r *ConfigReconciler) createOrUpdateCredentialRequest(loop *ConfigLoop) { credentialRequest := &ccmv1.CredentialsRequest{} namespacedName := types.NamespacedName{ Name: credReqName, Namespace: credReqNamespace, } - err := r.client.Get(ctx, namespacedName, credentialRequest) + err := r.client.Get(loop.ctx, namespacedName, credentialRequest) if err != nil { if errors.IsNotFound(err) { - r.log.Info("CredentialRequest does not exist") - r.createCredentialRequest(ctx, namespacedName) + r.log.Info("CredentialsRequest does not exist") + credentialRequest.Name = namespacedName.Name + credentialRequest.Namespace = namespacedName.Namespace + r.createCredentialRequest(loop, credentialRequest) } else { r.log.Error(err, "Failed to get CredentialRequest") } + } else { + r.updateCredentialRequest(loop, credentialRequest) + r.log.Info("CredentialsRequest exists", "status", credentialRequest.Status) } - r.log.Info("credential request exists, something else wrong.", "status", credentialRequest.Status) } //+kubebuilder:rbac:groups=cloudcredential.openshift.io,resources=credentialsrequests,verbs=create -func (r *ConfigReconciler) createCredentialRequest(ctx context.Context, namespacedName types.NamespacedName) { +func (r *ConfigReconciler) createCredentialRequest(loop *ConfigLoop, credentialRequest *ccmv1.CredentialsRequest) { - credentialRequest := ccmv1.CredentialsRequest{} - credentialRequest.Name = namespacedName.Name - credentialRequest.Namespace = namespacedName.Namespace credentialRequest.Spec.SecretRef.Name = credSecretName credentialRequest.Spec.SecretRef.Namespace = podNamespace credentialRequest.Spec.ServiceAccountNames = []string{podServiceAccount} + err := r.updateCredentialsRequestPolicyStatements(loop, credentialRequest) + + if err == nil { + err = r.client.Create(loop.ctx, credentialRequest) + } + if err != nil { + r.log.Error(err, "Failure creating CredentialsRequest object") + } else { + r.log.Info("Created CredentialsRequest") + } +} + +//+kubebuilder:rbac:groups=cloudcredential.openshift.io,resources=credentialsrequests,verbs=update;patch + +func (r *ConfigReconciler) updateCredentialRequest(loop *ConfigLoop, credentialRequest *ccmv1.CredentialsRequest) { + + err := r.updateCredentialsRequestPolicyStatements(loop, credentialRequest) + + if err == nil { + r.log.Info("updating with", "credentialrequest", credentialRequest) + err = r.client.Update(loop.ctx, credentialRequest) + } + if err != nil { + r.log.Error(err, "Failure updating CredentialsRequest object") + } else { + r.log.Info("Updated CredentialsRequest") + } +} + +func (r *ConfigReconciler) updateCredentialsRequestPolicyStatements(loop *ConfigLoop, credentialRequest *ccmv1.CredentialsRequest) error { + credentialRequestProviderSpec := ccmv1.AWSProviderSpec{} credentialRequestProviderSpec.StatementEntries = []ccmv1.StatementEntry{ { @@ -274,19 +329,47 @@ func (r *ConfigReconciler) createCredentialRequest(ctx context.Context, namespac } codec, err := ccmv1.NewCodec() + if err != nil { + r.log.Error(err, "Failure creating codec") + } + + // Pick up any additional permissions required to be minted in via OpenShift + if loop.config != nil { + if loop.config.Spec.AdditionalPermissions != nil { + awsSpec := ccmv1.AWSProviderSpec{} + err = codec.DecodeProviderSpec(loop.config.Spec.AdditionalPermissions, &awsSpec) + if err == nil { + for _, entry := range awsSpec.StatementEntries { + r.log.Info("Appending in something", "entry", entry) + credentialRequestProviderSpec.StatementEntries = append(credentialRequestProviderSpec.StatementEntries, entry) + } + if len(awsSpec.StatementEntries) == 0 { + r.log.Info("There are no entries", "awsSpec", awsSpec) + } + } else { + r.log.Error(err, "Failed to decode.") + } + } else { + r.log.Error(err, "No additional permissions.") + } + } else { + err = coreerrors.New("Config is nil") + r.log.Error(err, "Config could not be retrieved") + } + + r.log.Info("Our current providerspec", "spec", credentialRequestProviderSpec) + var raw *runtime.RawExtension if err == nil { raw, err = codec.EncodeProviderSpec(credentialRequestProviderSpec.DeepCopyObject()) } if err == nil && raw != nil { credentialRequest.Spec.ProviderSpec = raw - err = r.client.Create(ctx, &credentialRequest) + } else if raw == nil { + err = coreerrors.New("Failed to marshal the raw object into a ProviderSpec") } - if err != nil || raw == nil { - r.log.Error(err, "Failure marshaling or creating object") - - } + return err } func (r *ConfigReconciler) retrieveConfig(ctx context.Context, name types.NamespacedName) (*servicesv1alpha1.Config, error) { @@ -315,15 +398,14 @@ func (r *ConfigReconciler) getDefaultConfig(ctx context.Context) *servicesv1alph return defaultConfig } -func (r *ConfigReconciler) getClusterRegion(ctx context.Context) string { +func (r *ConfigReconciler) getClusterRegion(loop *ConfigLoop) string { // Look for direct configuration via our Config CRD - defaultConfig := r.getDefaultConfig(ctx) - if defaultConfig != nil && defaultConfig.Spec.Region != "" { - return defaultConfig.Spec.Region + if loop.config != nil && loop.config.Spec.Region != "" { + return loop.config.Spec.Region } // Lastly, if we're on OpenShift, check what the region is for the infra. - return r.getInfraRegion(ctx) + return r.getInfraRegion(loop.ctx) } //+kubebuilder:rbac:groups=config.openshift.io,resources=infrastructures,verbs=get;list;watch diff --git a/go.sum b/go.sum index a4a3ef6..1e3896d 100644 --- a/go.sum +++ b/go.sum @@ -103,6 +103,7 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/aws/aws-sdk-go v1.37.14 h1:thuR1hd1doCvsaMDYDMhqCGSmw39bSvZaw+DPGhMm5w= github.com/aws/aws-sdk-go v1.37.14/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v1.13.0 h1:1XIXAfxsEmbhbj5ry3D3vX+6ZcUYvIqSm4CWWEuGZCA= github.com/aws/aws-sdk-go-v2 v1.13.0/go.mod h1:L6+ZpqHaLbAaxsqV0L4cvxZY7QupWJB4fhkf8LXvC7w= @@ -457,6 +458,7 @@ github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= @@ -645,6 +647,7 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -660,6 +663,7 @@ github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3 github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/cobra v1.1.1/go.mod h1:WnodtKOvamDL/PwE2M4iKs8aMDBZ5Q5klgD3qfVJQMI= +github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= @@ -816,6 +820,7 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1213,6 +1218,7 @@ gopkg.in/ldap.v2 v2.5.1/go.mod h1:oI0cpe/D7HRtBQl8aTg+ZmzFUAvu4lsv3eLXMLGFxWk= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.5.1 h1:7odma5RETjNHWJnR32wx8t+Io4djHE1PqxCFx3iiZ2w= gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/src-d/go-billy.v4 v4.3.0/go.mod h1:tm33zBoOwxjYHZIE+OV8bxTWFMJLrconzFMd38aARFk= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=