diff --git a/apis/identity/v1alpha1/zz_generated.deepcopy.go b/apis/identity/v1alpha1/zz_generated.deepcopy.go index 0c816799..876adab7 100644 --- a/apis/identity/v1alpha1/zz_generated.deepcopy.go +++ b/apis/identity/v1alpha1/zz_generated.deepcopy.go @@ -10,6 +10,7 @@ Copyright 2022 Upbound Inc. package v1alpha1 import ( + "github.com/crossplane/crossplane-runtime/apis/common/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -828,16 +829,6 @@ func (in *GroupAlias) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GroupAliasInitParameters) DeepCopyInto(out *GroupAliasInitParameters) { *out = *in - if in.CanonicalID != nil { - in, out := &in.CanonicalID, &out.CanonicalID - *out = new(string) - **out = **in - } - if in.MountAccessor != nil { - in, out := &in.MountAccessor, &out.MountAccessor - *out = new(string) - **out = **in - } if in.Name != nil { in, out := &in.Name, &out.Name *out = new(string) @@ -940,11 +931,31 @@ func (in *GroupAliasParameters) DeepCopyInto(out *GroupAliasParameters) { *out = new(string) **out = **in } + if in.CanonicalIDRef != nil { + in, out := &in.CanonicalIDRef, &out.CanonicalIDRef + *out = new(v1.Reference) + (*in).DeepCopyInto(*out) + } + if in.CanonicalIDSelector != nil { + in, out := &in.CanonicalIDSelector, &out.CanonicalIDSelector + *out = new(v1.Selector) + (*in).DeepCopyInto(*out) + } if in.MountAccessor != nil { in, out := &in.MountAccessor, &out.MountAccessor *out = new(string) **out = **in } + if in.MountAccessorRef != nil { + in, out := &in.MountAccessorRef, &out.MountAccessorRef + *out = new(v1.Reference) + (*in).DeepCopyInto(*out) + } + if in.MountAccessorSelector != nil { + in, out := &in.MountAccessorSelector, &out.MountAccessorSelector + *out = new(v1.Selector) + (*in).DeepCopyInto(*out) + } if in.Name != nil { in, out := &in.Name, &out.Name *out = new(string) diff --git a/apis/identity/v1alpha1/zz_generated.resolvers.go b/apis/identity/v1alpha1/zz_generated.resolvers.go new file mode 100644 index 00000000..9c01a111 --- /dev/null +++ b/apis/identity/v1alpha1/zz_generated.resolvers.go @@ -0,0 +1,57 @@ +/* +Copyright 2022 Upbound Inc. +*/ +// Code generated by angryjet. DO NOT EDIT. + +package v1alpha1 + +import ( + "context" + reference "github.com/crossplane/crossplane-runtime/pkg/reference" + errors "github.com/pkg/errors" + v1alpha1 "github.com/upbound/provider-vault/apis/jwt/v1alpha1" + common "github.com/upbound/provider-vault/config/common" + client "sigs.k8s.io/controller-runtime/pkg/client" +) + +// ResolveReferences of this GroupAlias. +func (mg *GroupAlias) ResolveReferences(ctx context.Context, c client.Reader) error { + r := reference.NewAPIResolver(c, mg) + + var rsp reference.ResolutionResponse + var err error + + rsp, err = r.Resolve(ctx, reference.ResolutionRequest{ + CurrentValue: reference.FromPtrValue(mg.Spec.ForProvider.CanonicalID), + Extract: reference.ExternalName(), + Reference: mg.Spec.ForProvider.CanonicalIDRef, + Selector: mg.Spec.ForProvider.CanonicalIDSelector, + To: reference.To{ + List: &GroupList{}, + Managed: &Group{}, + }, + }) + if err != nil { + return errors.Wrap(err, "mg.Spec.ForProvider.CanonicalID") + } + mg.Spec.ForProvider.CanonicalID = reference.ToPtrValue(rsp.ResolvedValue) + mg.Spec.ForProvider.CanonicalIDRef = rsp.ResolvedReference + + rsp, err = r.Resolve(ctx, reference.ResolutionRequest{ + CurrentValue: reference.FromPtrValue(mg.Spec.ForProvider.MountAccessor), + Extract: common.ExtractAccessor(), + Reference: mg.Spec.ForProvider.MountAccessorRef, + Selector: mg.Spec.ForProvider.MountAccessorSelector, + To: reference.To{ + List: &v1alpha1.AuthBackendList{}, + Managed: &v1alpha1.AuthBackend{}, + }, + }) + if err != nil { + return errors.Wrap(err, "mg.Spec.ForProvider.MountAccessor") + } + mg.Spec.ForProvider.MountAccessor = reference.ToPtrValue(rsp.ResolvedValue) + mg.Spec.ForProvider.MountAccessorRef = rsp.ResolvedReference + + return nil +} diff --git a/apis/identity/v1alpha1/zz_groupalias_types.go b/apis/identity/v1alpha1/zz_groupalias_types.go index 49588eea..61cc3010 100755 --- a/apis/identity/v1alpha1/zz_groupalias_types.go +++ b/apis/identity/v1alpha1/zz_groupalias_types.go @@ -15,14 +15,6 @@ import ( type GroupAliasInitParameters struct { - // ID of the group to which this is an alias. - // ID of the group to which this is an alias. - CanonicalID *string `json:"canonicalId,omitempty" tf:"canonical_id,omitempty"` - - // Mount accessor of the authentication backend to which this alias belongs to. - // Mount accessor to which this alias belongs to. - MountAccessor *string `json:"mountAccessor,omitempty" tf:"mount_accessor,omitempty"` - // Name of the group alias to create. // Name of the group alias. Name *string `json:"name,omitempty" tf:"name,omitempty"` @@ -64,14 +56,33 @@ type GroupAliasParameters struct { // ID of the group to which this is an alias. // ID of the group to which this is an alias. + // +crossplane:generate:reference:type=Group // +kubebuilder:validation:Optional CanonicalID *string `json:"canonicalId,omitempty" tf:"canonical_id,omitempty"` + // Reference to a Group to populate canonicalId. + // +kubebuilder:validation:Optional + CanonicalIDRef *v1.Reference `json:"canonicalIdRef,omitempty" tf:"-"` + + // Selector for a Group to populate canonicalId. + // +kubebuilder:validation:Optional + CanonicalIDSelector *v1.Selector `json:"canonicalIdSelector,omitempty" tf:"-"` + // Mount accessor of the authentication backend to which this alias belongs to. // Mount accessor to which this alias belongs to. + // +crossplane:generate:reference:type=github.com/upbound/provider-vault/apis/jwt/v1alpha1.AuthBackend + // +crossplane:generate:reference:extractor=github.com/upbound/provider-vault/config/common.ExtractAccessor() // +kubebuilder:validation:Optional MountAccessor *string `json:"mountAccessor,omitempty" tf:"mount_accessor,omitempty"` + // Reference to a AuthBackend in jwt to populate mountAccessor. + // +kubebuilder:validation:Optional + MountAccessorRef *v1.Reference `json:"mountAccessorRef,omitempty" tf:"-"` + + // Selector for a AuthBackend in jwt to populate mountAccessor. + // +kubebuilder:validation:Optional + MountAccessorSelector *v1.Selector `json:"mountAccessorSelector,omitempty" tf:"-"` + // Name of the group alias to create. // Name of the group alias. // +kubebuilder:validation:Optional @@ -122,8 +133,6 @@ type GroupAliasStatus struct { type GroupAlias struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - // +kubebuilder:validation:XValidation:rule="!('*' in self.managementPolicies || 'Create' in self.managementPolicies || 'Update' in self.managementPolicies) || has(self.forProvider.canonicalId) || has(self.initProvider.canonicalId)",message="canonicalId is a required parameter" - // +kubebuilder:validation:XValidation:rule="!('*' in self.managementPolicies || 'Create' in self.managementPolicies || 'Update' in self.managementPolicies) || has(self.forProvider.mountAccessor) || has(self.initProvider.mountAccessor)",message="mountAccessor is a required parameter" // +kubebuilder:validation:XValidation:rule="!('*' in self.managementPolicies || 'Create' in self.managementPolicies || 'Update' in self.managementPolicies) || has(self.forProvider.name) || has(self.initProvider.name)",message="name is a required parameter" Spec GroupAliasSpec `json:"spec"` Status GroupAliasStatus `json:"status,omitempty"` diff --git a/config/common/common.go b/config/common/common.go new file mode 100644 index 00000000..765cccc9 --- /dev/null +++ b/config/common/common.go @@ -0,0 +1,48 @@ +/* +Copyright 2021 The Crossplane Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common + +import ( + "github.com/crossplane/crossplane-runtime/pkg/fieldpath" + "github.com/crossplane/crossplane-runtime/pkg/reference" + "github.com/crossplane/crossplane-runtime/pkg/resource" +) + +const ( + // SelfPackagePath is the golang path for this package. + SelfPackagePath = "github.com/upbound/provider-vault/config/common" + + // AccessorExtractor is the golang path to ExtractAccessor function + // in this package. + AccessorExtractor = SelfPackagePath + ".ExtractAccessor()" +) + + +// ExtractAccessor extracts accessor ID of the resources from "status.atProvider.accessor" +func ExtractAccessor() reference.ExtractValueFn { + return func(mg resource.Managed) string { + paved, err := fieldpath.PaveObject(mg) + if err != nil { + return "" + } + r, err := paved.GetString("status.atProvider.accessor") + if err != nil { + return "" + } + return r + } +} \ No newline at end of file diff --git a/config/vault/config.go b/config/vault/config.go index 9a5f1512..ac7f97f5 100644 --- a/config/vault/config.go +++ b/config/vault/config.go @@ -1,6 +1,9 @@ package vault -import "github.com/upbound/upjet/pkg/config" +import ( + "github.com/upbound/provider-vault/config/common" + "github.com/upbound/upjet/pkg/config" +) // ConfigureNamespace configures the namespace resource. func Configure(p *config.Provider) { @@ -8,4 +11,15 @@ func Configure(p *config.Provider) { r.Kind = "VaultNamespace" r.ShortGroup = "vault" }) + p.AddResourceConfigurator("vault_identity_group_alias", func(r *config.Resource) { + r.Kind = "GroupAlias" + r.ShortGroup = "identity" + r.References["canonical_id"] = config.Reference{ + Type: "Group", + } + r.References["mount_accessor"] = config.Reference{ + Type: "github.com/upbound/provider-vault/apis/jwt/v1alpha1.AuthBackend", + Extractor: common.AccessorExtractor, + } + }) } diff --git a/examples-generated/identity/groupalias.yaml b/examples-generated/identity/groupalias.yaml index 84d0819f..ce59525c 100644 --- a/examples-generated/identity/groupalias.yaml +++ b/examples-generated/identity/groupalias.yaml @@ -8,8 +8,12 @@ metadata: name: group-alias spec: forProvider: - canonicalId: ${vault_identity_group.group.id} - mountAccessor: ${vault_auth_backend.github.accessor} + canonicalIdSelector: + matchLabels: + testing.upbound.io/example-name: group + mountAccessorSelector: + matchLabels: + testing.upbound.io/example-name: github name: Github_Team_Slug --- diff --git a/package/crds/identity.vault.upbound.io_groupaliases.yaml b/package/crds/identity.vault.upbound.io_groupaliases.yaml index 30b9c83e..73910648 100644 --- a/package/crds/identity.vault.upbound.io_groupaliases.yaml +++ b/package/crds/identity.vault.upbound.io_groupaliases.yaml @@ -71,11 +71,157 @@ spec: description: ID of the group to which this is an alias. ID of the group to which this is an alias. type: string + canonicalIdRef: + description: Reference to a Group to populate canonicalId. + properties: + name: + description: Name of the referenced object. + type: string + policy: + description: Policies for referencing. + properties: + resolution: + default: Required + description: Resolution specifies whether resolution of + this reference is required. The default is 'Required', + which means the reconcile will fail if the reference + cannot be resolved. 'Optional' means this reference + will be a no-op if it cannot be resolved. + enum: + - Required + - Optional + type: string + resolve: + description: Resolve specifies when this reference should + be resolved. The default is 'IfNotPresent', which will + attempt to resolve the reference only when the corresponding + field is not present. Use 'Always' to resolve the reference + on every reconcile. + enum: + - Always + - IfNotPresent + type: string + type: object + required: + - name + type: object + canonicalIdSelector: + description: Selector for a Group to populate canonicalId. + properties: + matchControllerRef: + description: MatchControllerRef ensures an object with the + same controller reference as the selecting object is selected. + type: boolean + matchLabels: + additionalProperties: + type: string + description: MatchLabels ensures an object with matching labels + is selected. + type: object + policy: + description: Policies for selection. + properties: + resolution: + default: Required + description: Resolution specifies whether resolution of + this reference is required. The default is 'Required', + which means the reconcile will fail if the reference + cannot be resolved. 'Optional' means this reference + will be a no-op if it cannot be resolved. + enum: + - Required + - Optional + type: string + resolve: + description: Resolve specifies when this reference should + be resolved. The default is 'IfNotPresent', which will + attempt to resolve the reference only when the corresponding + field is not present. Use 'Always' to resolve the reference + on every reconcile. + enum: + - Always + - IfNotPresent + type: string + type: object + type: object mountAccessor: description: Mount accessor of the authentication backend to which this alias belongs to. Mount accessor to which this alias belongs to. type: string + mountAccessorRef: + description: Reference to a AuthBackend in jwt to populate mountAccessor. + properties: + name: + description: Name of the referenced object. + type: string + policy: + description: Policies for referencing. + properties: + resolution: + default: Required + description: Resolution specifies whether resolution of + this reference is required. The default is 'Required', + which means the reconcile will fail if the reference + cannot be resolved. 'Optional' means this reference + will be a no-op if it cannot be resolved. + enum: + - Required + - Optional + type: string + resolve: + description: Resolve specifies when this reference should + be resolved. The default is 'IfNotPresent', which will + attempt to resolve the reference only when the corresponding + field is not present. Use 'Always' to resolve the reference + on every reconcile. + enum: + - Always + - IfNotPresent + type: string + type: object + required: + - name + type: object + mountAccessorSelector: + description: Selector for a AuthBackend in jwt to populate mountAccessor. + properties: + matchControllerRef: + description: MatchControllerRef ensures an object with the + same controller reference as the selecting object is selected. + type: boolean + matchLabels: + additionalProperties: + type: string + description: MatchLabels ensures an object with matching labels + is selected. + type: object + policy: + description: Policies for selection. + properties: + resolution: + default: Required + description: Resolution specifies whether resolution of + this reference is required. The default is 'Required', + which means the reconcile will fail if the reference + cannot be resolved. 'Optional' means this reference + will be a no-op if it cannot be resolved. + enum: + - Required + - Optional + type: string + resolve: + description: Resolve specifies when this reference should + be resolved. The default is 'IfNotPresent', which will + attempt to resolve the reference only when the corresponding + field is not present. Use 'Always' to resolve the reference + on every reconcile. + enum: + - Always + - IfNotPresent + type: string + type: object + type: object name: description: Name of the group alias to create. Name of the group alias. @@ -101,15 +247,6 @@ spec: creation, for example because of an external controller is managing them, like an autoscaler. properties: - canonicalId: - description: ID of the group to which this is an alias. ID of - the group to which this is an alias. - type: string - mountAccessor: - description: Mount accessor of the authentication backend to which - this alias belongs to. Mount accessor to which this alias belongs - to. - type: string name: description: Name of the group alias to create. Name of the group alias. @@ -320,14 +457,6 @@ spec: - forProvider type: object x-kubernetes-validations: - - message: canonicalId is a required parameter - rule: '!(''*'' in self.managementPolicies || ''Create'' in self.managementPolicies - || ''Update'' in self.managementPolicies) || has(self.forProvider.canonicalId) - || has(self.initProvider.canonicalId)' - - message: mountAccessor is a required parameter - rule: '!(''*'' in self.managementPolicies || ''Create'' in self.managementPolicies - || ''Update'' in self.managementPolicies) || has(self.forProvider.mountAccessor) - || has(self.initProvider.mountAccessor)' - message: name is a required parameter rule: '!(''*'' in self.managementPolicies || ''Create'' in self.managementPolicies || ''Update'' in self.managementPolicies) || has(self.forProvider.name)