diff --git a/apis/account/v1beta1/zz_generated.conversion_hubs.go b/apis/account/v1beta1/zz_generated.conversion_hubs.go index 3f455c7508..401c82f4f3 100755 --- a/apis/account/v1beta1/zz_generated.conversion_hubs.go +++ b/apis/account/v1beta1/zz_generated.conversion_hubs.go @@ -8,3 +8,6 @@ package v1beta1 // Hub marks this type as a conversion hub. func (tr *AlternateContact) Hub() {} + +// Hub marks this type as a conversion hub. +func (tr *Region) Hub() {} diff --git a/apis/account/v1beta1/zz_generated.deepcopy.go b/apis/account/v1beta1/zz_generated.deepcopy.go index 6b3e57b173..281d248182 100644 --- a/apis/account/v1beta1/zz_generated.deepcopy.go +++ b/apis/account/v1beta1/zz_generated.deepcopy.go @@ -245,3 +245,197 @@ func (in *AlternateContactStatus) DeepCopy() *AlternateContactStatus { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Region) DeepCopyInto(out *Region) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Region. +func (in *Region) DeepCopy() *Region { + if in == nil { + return nil + } + out := new(Region) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Region) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RegionInitParameters) DeepCopyInto(out *RegionInitParameters) { + *out = *in + if in.AccountID != nil { + in, out := &in.AccountID, &out.AccountID + *out = new(string) + **out = **in + } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegionInitParameters. +func (in *RegionInitParameters) DeepCopy() *RegionInitParameters { + if in == nil { + return nil + } + out := new(RegionInitParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RegionList) DeepCopyInto(out *RegionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Region, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegionList. +func (in *RegionList) DeepCopy() *RegionList { + if in == nil { + return nil + } + out := new(RegionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *RegionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RegionObservation) DeepCopyInto(out *RegionObservation) { + *out = *in + if in.AccountID != nil { + in, out := &in.AccountID, &out.AccountID + *out = new(string) + **out = **in + } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.OptStatus != nil { + in, out := &in.OptStatus, &out.OptStatus + *out = new(string) + **out = **in + } + if in.RegionName != nil { + in, out := &in.RegionName, &out.RegionName + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegionObservation. +func (in *RegionObservation) DeepCopy() *RegionObservation { + if in == nil { + return nil + } + out := new(RegionObservation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RegionParameters) DeepCopyInto(out *RegionParameters) { + *out = *in + if in.AccountID != nil { + in, out := &in.AccountID, &out.AccountID + *out = new(string) + **out = **in + } + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.Region != nil { + in, out := &in.Region, &out.Region + *out = new(string) + **out = **in + } + if in.RegionName != nil { + in, out := &in.RegionName, &out.RegionName + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegionParameters. +func (in *RegionParameters) DeepCopy() *RegionParameters { + if in == nil { + return nil + } + out := new(RegionParameters) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RegionSpec) DeepCopyInto(out *RegionSpec) { + *out = *in + in.ResourceSpec.DeepCopyInto(&out.ResourceSpec) + in.ForProvider.DeepCopyInto(&out.ForProvider) + in.InitProvider.DeepCopyInto(&out.InitProvider) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegionSpec. +func (in *RegionSpec) DeepCopy() *RegionSpec { + if in == nil { + return nil + } + out := new(RegionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RegionStatus) DeepCopyInto(out *RegionStatus) { + *out = *in + in.ResourceStatus.DeepCopyInto(&out.ResourceStatus) + in.AtProvider.DeepCopyInto(&out.AtProvider) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RegionStatus. +func (in *RegionStatus) DeepCopy() *RegionStatus { + if in == nil { + return nil + } + out := new(RegionStatus) + in.DeepCopyInto(out) + return out +} diff --git a/apis/account/v1beta1/zz_generated.managed.go b/apis/account/v1beta1/zz_generated.managed.go index 24bb361416..d7b1b75e85 100644 --- a/apis/account/v1beta1/zz_generated.managed.go +++ b/apis/account/v1beta1/zz_generated.managed.go @@ -66,3 +66,63 @@ func (mg *AlternateContact) SetPublishConnectionDetailsTo(r *xpv1.PublishConnect func (mg *AlternateContact) SetWriteConnectionSecretToReference(r *xpv1.SecretReference) { mg.Spec.WriteConnectionSecretToReference = r } + +// GetCondition of this Region. +func (mg *Region) GetCondition(ct xpv1.ConditionType) xpv1.Condition { + return mg.Status.GetCondition(ct) +} + +// GetDeletionPolicy of this Region. +func (mg *Region) GetDeletionPolicy() xpv1.DeletionPolicy { + return mg.Spec.DeletionPolicy +} + +// GetManagementPolicies of this Region. +func (mg *Region) GetManagementPolicies() xpv1.ManagementPolicies { + return mg.Spec.ManagementPolicies +} + +// GetProviderConfigReference of this Region. +func (mg *Region) GetProviderConfigReference() *xpv1.Reference { + return mg.Spec.ProviderConfigReference +} + +// GetPublishConnectionDetailsTo of this Region. +func (mg *Region) GetPublishConnectionDetailsTo() *xpv1.PublishConnectionDetailsTo { + return mg.Spec.PublishConnectionDetailsTo +} + +// GetWriteConnectionSecretToReference of this Region. +func (mg *Region) GetWriteConnectionSecretToReference() *xpv1.SecretReference { + return mg.Spec.WriteConnectionSecretToReference +} + +// SetConditions of this Region. +func (mg *Region) SetConditions(c ...xpv1.Condition) { + mg.Status.SetConditions(c...) +} + +// SetDeletionPolicy of this Region. +func (mg *Region) SetDeletionPolicy(r xpv1.DeletionPolicy) { + mg.Spec.DeletionPolicy = r +} + +// SetManagementPolicies of this Region. +func (mg *Region) SetManagementPolicies(r xpv1.ManagementPolicies) { + mg.Spec.ManagementPolicies = r +} + +// SetProviderConfigReference of this Region. +func (mg *Region) SetProviderConfigReference(r *xpv1.Reference) { + mg.Spec.ProviderConfigReference = r +} + +// SetPublishConnectionDetailsTo of this Region. +func (mg *Region) SetPublishConnectionDetailsTo(r *xpv1.PublishConnectionDetailsTo) { + mg.Spec.PublishConnectionDetailsTo = r +} + +// SetWriteConnectionSecretToReference of this Region. +func (mg *Region) SetWriteConnectionSecretToReference(r *xpv1.SecretReference) { + mg.Spec.WriteConnectionSecretToReference = r +} diff --git a/apis/account/v1beta1/zz_generated.managedlist.go b/apis/account/v1beta1/zz_generated.managedlist.go index 435369e0bd..0b0ea597f3 100644 --- a/apis/account/v1beta1/zz_generated.managedlist.go +++ b/apis/account/v1beta1/zz_generated.managedlist.go @@ -15,3 +15,12 @@ func (l *AlternateContactList) GetItems() []resource.Managed { } return items } + +// GetItems of this RegionList. +func (l *RegionList) GetItems() []resource.Managed { + items := make([]resource.Managed, len(l.Items)) + for i := range l.Items { + items[i] = &l.Items[i] + } + return items +} diff --git a/apis/account/v1beta1/zz_region_terraformed.go b/apis/account/v1beta1/zz_region_terraformed.go new file mode 100755 index 0000000000..aa6f7ff408 --- /dev/null +++ b/apis/account/v1beta1/zz_region_terraformed.go @@ -0,0 +1,129 @@ +// SPDX-FileCopyrightText: 2024 The Crossplane Authors +// +// SPDX-License-Identifier: Apache-2.0 + +// Code generated by upjet. DO NOT EDIT. + +package v1beta1 + +import ( + "dario.cat/mergo" + "github.com/pkg/errors" + + "github.com/crossplane/upjet/pkg/resource" + "github.com/crossplane/upjet/pkg/resource/json" +) + +// GetTerraformResourceType returns Terraform resource type for this Region +func (mg *Region) GetTerraformResourceType() string { + return "aws_account_region" +} + +// GetConnectionDetailsMapping for this Region +func (tr *Region) GetConnectionDetailsMapping() map[string]string { + return nil +} + +// GetObservation of this Region +func (tr *Region) GetObservation() (map[string]any, error) { + o, err := json.TFParser.Marshal(tr.Status.AtProvider) + if err != nil { + return nil, err + } + base := map[string]any{} + return base, json.TFParser.Unmarshal(o, &base) +} + +// SetObservation for this Region +func (tr *Region) SetObservation(obs map[string]any) error { + p, err := json.TFParser.Marshal(obs) + if err != nil { + return err + } + return json.TFParser.Unmarshal(p, &tr.Status.AtProvider) +} + +// GetID returns ID of underlying Terraform resource of this Region +func (tr *Region) GetID() string { + if tr.Status.AtProvider.ID == nil { + return "" + } + return *tr.Status.AtProvider.ID +} + +// GetParameters of this Region +func (tr *Region) GetParameters() (map[string]any, error) { + p, err := json.TFParser.Marshal(tr.Spec.ForProvider) + if err != nil { + return nil, err + } + base := map[string]any{} + return base, json.TFParser.Unmarshal(p, &base) +} + +// SetParameters for this Region +func (tr *Region) SetParameters(params map[string]any) error { + p, err := json.TFParser.Marshal(params) + if err != nil { + return err + } + return json.TFParser.Unmarshal(p, &tr.Spec.ForProvider) +} + +// GetInitParameters of this Region +func (tr *Region) GetInitParameters() (map[string]any, error) { + p, err := json.TFParser.Marshal(tr.Spec.InitProvider) + if err != nil { + return nil, err + } + base := map[string]any{} + return base, json.TFParser.Unmarshal(p, &base) +} + +// GetInitParameters of this Region +func (tr *Region) GetMergedParameters(shouldMergeInitProvider bool) (map[string]any, error) { + params, err := tr.GetParameters() + if err != nil { + return nil, errors.Wrapf(err, "cannot get parameters for resource '%q'", tr.GetName()) + } + if !shouldMergeInitProvider { + return params, nil + } + + initParams, err := tr.GetInitParameters() + if err != nil { + return nil, errors.Wrapf(err, "cannot get init parameters for resource '%q'", tr.GetName()) + } + + // Note(lsviben): mergo.WithSliceDeepCopy is needed to merge the + // slices from the initProvider to forProvider. As it also sets + // overwrite to true, we need to set it back to false, we don't + // want to overwrite the forProvider fields with the initProvider + // fields. + err = mergo.Merge(¶ms, initParams, mergo.WithSliceDeepCopy, func(c *mergo.Config) { + c.Overwrite = false + }) + if err != nil { + return nil, errors.Wrapf(err, "cannot merge spec.initProvider and spec.forProvider parameters for resource '%q'", tr.GetName()) + } + + return params, nil +} + +// LateInitialize this Region using its observed tfState. +// returns True if there are any spec changes for the resource. +func (tr *Region) LateInitialize(attrs []byte) (bool, error) { + params := &RegionParameters{} + if err := json.TFParser.Unmarshal(attrs, params); err != nil { + return false, errors.Wrap(err, "failed to unmarshal Terraform state parameters for late-initialization") + } + opts := []resource.GenericLateInitializerOption{resource.WithZeroValueJSONOmitEmptyFilter(resource.CNameWildcard)} + + li := resource.NewGenericLateInitializer(opts...) + return li.LateInitialize(&tr.Spec.ForProvider, params) +} + +// GetTerraformSchemaVersion returns the associated Terraform schema version +func (tr *Region) GetTerraformSchemaVersion() int { + return 0 +} diff --git a/apis/account/v1beta1/zz_region_types.go b/apis/account/v1beta1/zz_region_types.go new file mode 100755 index 0000000000..baa2df0538 --- /dev/null +++ b/apis/account/v1beta1/zz_region_types.go @@ -0,0 +1,122 @@ +// SPDX-FileCopyrightText: 2024 The Crossplane Authors +// +// SPDX-License-Identifier: Apache-2.0 + +// Code generated by upjet. DO NOT EDIT. + +package v1beta1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + + v1 "github.com/crossplane/crossplane-runtime/apis/common/v1" +) + +type RegionInitParameters struct { + + // The ID of the target account when managing member accounts. Will manage current user's account by default if omitted. To use this parameter, the caller must be an identity in the organization's management account or a delegated administrator account. The specified account ID must also be a member account in the same organization. The organization must have all features enabled, and the organization must have trusted access enabled for the Account Management service, and optionally a delegated admin account assigned. + AccountID *string `json:"accountId,omitempty" tf:"account_id,omitempty"` + + // Whether the region is enabled. + Enabled *bool `json:"enabled,omitempty" tf:"enabled,omitempty"` +} + +type RegionObservation struct { + + // The ID of the target account when managing member accounts. Will manage current user's account by default if omitted. To use this parameter, the caller must be an identity in the organization's management account or a delegated administrator account. The specified account ID must also be a member account in the same organization. The organization must have all features enabled, and the organization must have trusted access enabled for the Account Management service, and optionally a delegated admin account assigned. + AccountID *string `json:"accountId,omitempty" tf:"account_id,omitempty"` + + // Whether the region is enabled. + Enabled *bool `json:"enabled,omitempty" tf:"enabled,omitempty"` + + ID *string `json:"id,omitempty" tf:"id,omitempty"` + + // The region opt status. + OptStatus *string `json:"optStatus,omitempty" tf:"opt_status,omitempty"` + + // The region name to manage. + RegionName *string `json:"regionName,omitempty" tf:"region_name,omitempty"` +} + +type RegionParameters struct { + + // The ID of the target account when managing member accounts. Will manage current user's account by default if omitted. To use this parameter, the caller must be an identity in the organization's management account or a delegated administrator account. The specified account ID must also be a member account in the same organization. The organization must have all features enabled, and the organization must have trusted access enabled for the Account Management service, and optionally a delegated admin account assigned. + // +kubebuilder:validation:Optional + AccountID *string `json:"accountId,omitempty" tf:"account_id,omitempty"` + + // Whether the region is enabled. + // +kubebuilder:validation:Optional + Enabled *bool `json:"enabled,omitempty" tf:"enabled,omitempty"` + + // Region is the region you'd like your resource to be created in. + // +upjet:crd:field:TFTag=- + // +kubebuilder:validation:Required + Region *string `json:"region" tf:"-"` + + // The region name to manage. + // +kubebuilder:validation:Required + RegionName *string `json:"regionName" tf:"region_name,omitempty"` +} + +// RegionSpec defines the desired state of Region +type RegionSpec struct { + v1.ResourceSpec `json:",inline"` + ForProvider RegionParameters `json:"forProvider"` + // THIS IS A BETA FIELD. It will be honored + // unless the Management Policies feature flag is disabled. + // InitProvider holds the same fields as ForProvider, with the exception + // of Identifier and other resource reference fields. The fields that are + // in InitProvider are merged into ForProvider when the resource is created. + // The same fields are also added to the terraform ignore_changes hook, to + // avoid updating them after creation. This is useful for fields that are + // required on creation, but we do not desire to update them after creation, + // for example because of an external controller is managing them, like an + // autoscaler. + InitProvider RegionInitParameters `json:"initProvider,omitempty"` +} + +// RegionStatus defines the observed state of Region. +type RegionStatus struct { + v1.ResourceStatus `json:",inline"` + AtProvider RegionObservation `json:"atProvider,omitempty"` +} + +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:storageversion + +// Region is the Schema for the Regions API. Enable (Opt-In) or Disable (Opt-Out) a particular Region for an AWS account +// +kubebuilder:printcolumn:name="SYNCED",type="string",JSONPath=".status.conditions[?(@.type=='Synced')].status" +// +kubebuilder:printcolumn:name="READY",type="string",JSONPath=".status.conditions[?(@.type=='Ready')].status" +// +kubebuilder:printcolumn:name="EXTERNAL-NAME",type="string",JSONPath=".metadata.annotations.crossplane\\.io/external-name" +// +kubebuilder:printcolumn:name="AGE",type="date",JSONPath=".metadata.creationTimestamp" +// +kubebuilder:resource:scope=Cluster,categories={crossplane,managed,aws} +type Region 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.enabled) || (has(self.initProvider) && has(self.initProvider.enabled))",message="spec.forProvider.enabled is a required parameter" + Spec RegionSpec `json:"spec"` + Status RegionStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// RegionList contains a list of Regions +type RegionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []Region `json:"items"` +} + +// Repository type metadata. +var ( + Region_Kind = "Region" + Region_GroupKind = schema.GroupKind{Group: CRDGroup, Kind: Region_Kind}.String() + Region_KindAPIVersion = Region_Kind + "." + CRDGroupVersion.String() + Region_GroupVersionKind = CRDGroupVersion.WithKind(Region_Kind) +) + +func init() { + SchemeBuilder.Register(&Region{}, &RegionList{}) +} diff --git a/config/externalname.go b/config/externalname.go index 94b0907122..2bbce5885f 100644 --- a/config/externalname.go +++ b/config/externalname.go @@ -111,6 +111,8 @@ var TerraformPluginSDKExternalNameConfigs = map[string]config.ExternalName{ // // The Alternate Contact for the current account can be imported using the alternate_contact_type "aws_account_alternate_contact": config.TemplatedStringAsIdentifier("", "{{ .parameters.alternate_contact_type }}"), + // The account region can be imported using region_name or a comma separated account_id and region_name + "aws_account_region": config.TemplatedStringAsIdentifier("", "{{ .parameters.region_name }}"), // ACM // Imported using ARN that has a random substring: diff --git a/config/generated.lst b/config/generated.lst index ace2118fdd..c24193b2cf 100644 --- a/config/generated.lst +++ b/config/generated.lst @@ -2,6 +2,7 @@ "aws_accessanalyzer_analyzer", "aws_accessanalyzer_archive_rule", "aws_account_alternate_contact", +"aws_account_region", "aws_acm_certificate", "aws_acm_certificate_validation", "aws_acmpca_certificate", diff --git a/examples-generated/account/v1beta1/region.yaml b/examples-generated/account/v1beta1/region.yaml new file mode 100644 index 0000000000..97cc3fb3ac --- /dev/null +++ b/examples-generated/account/v1beta1/region.yaml @@ -0,0 +1,13 @@ +apiVersion: account.aws.upbound.io/v1beta1 +kind: Region +metadata: + annotations: + meta.upbound.io/example-id: account/v1beta1/region + labels: + testing.upbound.io/example-name: example + name: example +spec: + forProvider: + enabled: true + region: us-west-1 + regionName: ap-southeast-3 diff --git a/examples/account/v1beta1/region.yaml b/examples/account/v1beta1/region.yaml new file mode 100644 index 0000000000..97cc3fb3ac --- /dev/null +++ b/examples/account/v1beta1/region.yaml @@ -0,0 +1,13 @@ +apiVersion: account.aws.upbound.io/v1beta1 +kind: Region +metadata: + annotations: + meta.upbound.io/example-id: account/v1beta1/region + labels: + testing.upbound.io/example-name: example + name: example +spec: + forProvider: + enabled: true + region: us-west-1 + regionName: ap-southeast-3 diff --git a/internal/controller/account/region/zz_controller.go b/internal/controller/account/region/zz_controller.go new file mode 100755 index 0000000000..5ff5ad88c4 --- /dev/null +++ b/internal/controller/account/region/zz_controller.go @@ -0,0 +1,92 @@ +// SPDX-FileCopyrightText: 2024 The Crossplane Authors +// +// SPDX-License-Identifier: Apache-2.0 + +// Code generated by upjet. DO NOT EDIT. + +package region + +import ( + "time" + + "github.com/crossplane/crossplane-runtime/pkg/connection" + "github.com/crossplane/crossplane-runtime/pkg/event" + "github.com/crossplane/crossplane-runtime/pkg/ratelimiter" + "github.com/crossplane/crossplane-runtime/pkg/reconciler/managed" + xpresource "github.com/crossplane/crossplane-runtime/pkg/resource" + "github.com/crossplane/crossplane-runtime/pkg/statemetrics" + tjcontroller "github.com/crossplane/upjet/pkg/controller" + "github.com/crossplane/upjet/pkg/controller/handler" + "github.com/crossplane/upjet/pkg/metrics" + "github.com/pkg/errors" + ctrl "sigs.k8s.io/controller-runtime" + + v1beta1 "github.com/upbound/provider-aws/apis/account/v1beta1" + features "github.com/upbound/provider-aws/internal/features" +) + +// Setup adds a controller that reconciles Region managed resources. +func Setup(mgr ctrl.Manager, o tjcontroller.Options) error { + name := managed.ControllerName(v1beta1.Region_GroupVersionKind.String()) + var initializers managed.InitializerChain + initializers = append(initializers, managed.NewNameAsExternalName(mgr.GetClient())) + cps := []managed.ConnectionPublisher{managed.NewAPISecretPublisher(mgr.GetClient(), mgr.GetScheme())} + if o.SecretStoreConfigGVK != nil { + cps = append(cps, connection.NewDetailsManager(mgr.GetClient(), *o.SecretStoreConfigGVK, connection.WithTLSConfig(o.ESSOptions.TLSConfig))) + } + eventHandler := handler.NewEventHandler(handler.WithLogger(o.Logger.WithValues("gvk", v1beta1.Region_GroupVersionKind))) + ac := tjcontroller.NewAPICallbacks(mgr, xpresource.ManagedKind(v1beta1.Region_GroupVersionKind), tjcontroller.WithEventHandler(eventHandler), tjcontroller.WithStatusUpdates(false)) + opts := []managed.ReconcilerOption{ + managed.WithExternalConnecter( + tjcontroller.NewTerraformPluginSDKAsyncConnector(mgr.GetClient(), o.OperationTrackerStore, o.SetupFn, o.Provider.Resources["aws_account_region"], + tjcontroller.WithTerraformPluginSDKAsyncLogger(o.Logger), + tjcontroller.WithTerraformPluginSDKAsyncConnectorEventHandler(eventHandler), + tjcontroller.WithTerraformPluginSDKAsyncCallbackProvider(ac), + tjcontroller.WithTerraformPluginSDKAsyncMetricRecorder(metrics.NewMetricRecorder(v1beta1.Region_GroupVersionKind, mgr, o.PollInterval)), + tjcontroller.WithTerraformPluginSDKAsyncManagementPolicies(o.Features.Enabled(features.EnableBetaManagementPolicies)))), + managed.WithLogger(o.Logger.WithValues("controller", name)), + managed.WithRecorder(event.NewAPIRecorder(mgr.GetEventRecorderFor(name))), + managed.WithFinalizer(tjcontroller.NewOperationTrackerFinalizer(o.OperationTrackerStore, xpresource.NewAPIFinalizer(mgr.GetClient(), managed.FinalizerName))), + managed.WithTimeout(3 * time.Minute), + managed.WithInitializers(initializers), + managed.WithConnectionPublishers(cps...), + managed.WithPollInterval(o.PollInterval), + } + if o.PollJitter != 0 { + opts = append(opts, managed.WithPollJitterHook(o.PollJitter)) + } + if o.Features.Enabled(features.EnableBetaManagementPolicies) { + opts = append(opts, managed.WithManagementPolicies()) + } + if o.MetricOptions != nil { + opts = append(opts, managed.WithMetricRecorder(o.MetricOptions.MRMetrics)) + } + + // register webhooks for the kind v1beta1.Region + // if they're enabled. + if o.StartWebhooks { + if err := ctrl.NewWebhookManagedBy(mgr). + For(&v1beta1.Region{}). + Complete(); err != nil { + return errors.Wrap(err, "cannot register webhook for the kind v1beta1.Region") + } + } + + if o.MetricOptions != nil && o.MetricOptions.MRStateMetrics != nil { + stateMetricsRecorder := statemetrics.NewMRStateRecorder( + mgr.GetClient(), o.Logger, o.MetricOptions.MRStateMetrics, &v1beta1.RegionList{}, o.MetricOptions.PollStateMetricInterval, + ) + if err := mgr.Add(stateMetricsRecorder); err != nil { + return errors.Wrap(err, "cannot register MR state metrics recorder for kind v1beta1.RegionList") + } + } + + r := managed.NewReconciler(mgr, xpresource.ManagedKind(v1beta1.Region_GroupVersionKind), opts...) + + return ctrl.NewControllerManagedBy(mgr). + Named(name). + WithOptions(o.ForControllerRuntime()). + WithEventFilter(xpresource.DesiredStateChanged()). + Watches(&v1beta1.Region{}, eventHandler). + Complete(ratelimiter.NewReconciler(name, r, o.GlobalRateLimiter)) +} diff --git a/internal/controller/zz_account_setup.go b/internal/controller/zz_account_setup.go index f09ba8aa60..bfea494339 100755 --- a/internal/controller/zz_account_setup.go +++ b/internal/controller/zz_account_setup.go @@ -10,6 +10,7 @@ import ( "github.com/crossplane/upjet/pkg/controller" alternatecontact "github.com/upbound/provider-aws/internal/controller/account/alternatecontact" + region "github.com/upbound/provider-aws/internal/controller/account/region" ) // Setup_account creates all controllers with the supplied logger and adds them to @@ -17,6 +18,7 @@ import ( func Setup_account(mgr ctrl.Manager, o controller.Options) error { for _, setup := range []func(ctrl.Manager, controller.Options) error{ alternatecontact.Setup, + region.Setup, } { if err := setup(mgr, o); err != nil { return err diff --git a/internal/controller/zz_monolith_setup.go b/internal/controller/zz_monolith_setup.go index cb6428f3b6..20b68afa97 100755 --- a/internal/controller/zz_monolith_setup.go +++ b/internal/controller/zz_monolith_setup.go @@ -12,6 +12,7 @@ import ( analyzer "github.com/upbound/provider-aws/internal/controller/accessanalyzer/analyzer" archiverule "github.com/upbound/provider-aws/internal/controller/accessanalyzer/archiverule" alternatecontact "github.com/upbound/provider-aws/internal/controller/account/alternatecontact" + region "github.com/upbound/provider-aws/internal/controller/account/region" certificate "github.com/upbound/provider-aws/internal/controller/acm/certificate" certificatevalidation "github.com/upbound/provider-aws/internal/controller/acm/certificatevalidation" certificateacmpca "github.com/upbound/provider-aws/internal/controller/acmpca/certificate" @@ -972,6 +973,7 @@ func Setup_monolith(mgr ctrl.Manager, o controller.Options) error { analyzer.Setup, archiverule.Setup, alternatecontact.Setup, + region.Setup, certificate.Setup, certificatevalidation.Setup, certificateacmpca.Setup, diff --git a/package/crds/account.aws.upbound.io_regions.yaml b/package/crds/account.aws.upbound.io_regions.yaml new file mode 100644 index 0000000000..5d66349b86 --- /dev/null +++ b/package/crds/account.aws.upbound.io_regions.yaml @@ -0,0 +1,389 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: regions.account.aws.upbound.io +spec: + group: account.aws.upbound.io + names: + categories: + - crossplane + - managed + - aws + kind: Region + listKind: RegionList + plural: regions + singular: region + scope: Cluster + versions: + - additionalPrinterColumns: + - jsonPath: .status.conditions[?(@.type=='Synced')].status + name: SYNCED + type: string + - jsonPath: .status.conditions[?(@.type=='Ready')].status + name: READY + type: string + - jsonPath: .metadata.annotations.crossplane\.io/external-name + name: EXTERNAL-NAME + type: string + - jsonPath: .metadata.creationTimestamp + name: AGE + type: date + name: v1beta1 + schema: + openAPIV3Schema: + description: Region is the Schema for the Regions API. Enable (Opt-In) or + Disable (Opt-Out) a particular Region for an AWS account + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: RegionSpec defines the desired state of Region + properties: + deletionPolicy: + default: Delete + description: |- + DeletionPolicy specifies what will happen to the underlying external + when this managed resource is deleted - either "Delete" or "Orphan" the + external resource. + This field is planned to be deprecated in favor of the ManagementPolicies + field in a future release. Currently, both could be set independently and + non-default values would be honored if the feature flag is enabled. + See the design doc for more information: https://github.com/crossplane/crossplane/blob/499895a25d1a1a0ba1604944ef98ac7a1a71f197/design/design-doc-observe-only-resources.md?plain=1#L223 + enum: + - Orphan + - Delete + type: string + forProvider: + properties: + accountId: + description: The ID of the target account when managing member + accounts. Will manage current user's account by default if omitted. + To use this parameter, the caller must be an identity in the + organization's management account or a delegated administrator + account. The specified account ID must also be a member account + in the same organization. The organization must have all features + enabled, and the organization must have trusted access enabled + for the Account Management service, and optionally a delegated + admin account assigned. + type: string + enabled: + description: Whether the region is enabled. + type: boolean + region: + description: Region is the region you'd like your resource to + be created in. + type: string + regionName: + description: The region name to manage. + type: string + required: + - region + - regionName + type: object + initProvider: + description: |- + THIS IS A BETA FIELD. It will be honored + unless the Management Policies feature flag is disabled. + InitProvider holds the same fields as ForProvider, with the exception + of Identifier and other resource reference fields. The fields that are + in InitProvider are merged into ForProvider when the resource is created. + The same fields are also added to the terraform ignore_changes hook, to + avoid updating them after creation. This is useful for fields that are + required on creation, but we do not desire to update them after creation, + for example because of an external controller is managing them, like an + autoscaler. + properties: + accountId: + description: The ID of the target account when managing member + accounts. Will manage current user's account by default if omitted. + To use this parameter, the caller must be an identity in the + organization's management account or a delegated administrator + account. The specified account ID must also be a member account + in the same organization. The organization must have all features + enabled, and the organization must have trusted access enabled + for the Account Management service, and optionally a delegated + admin account assigned. + type: string + enabled: + description: Whether the region is enabled. + type: boolean + type: object + managementPolicies: + default: + - '*' + description: |- + THIS IS A BETA FIELD. It is on by default but can be opted out + through a Crossplane feature flag. + ManagementPolicies specify the array of actions Crossplane is allowed to + take on the managed and external resources. + This field is planned to replace the DeletionPolicy field in a future + release. Currently, both could be set independently and non-default + values would be honored if the feature flag is enabled. If both are + custom, the DeletionPolicy field will be ignored. + See the design doc for more information: https://github.com/crossplane/crossplane/blob/499895a25d1a1a0ba1604944ef98ac7a1a71f197/design/design-doc-observe-only-resources.md?plain=1#L223 + and this one: https://github.com/crossplane/crossplane/blob/444267e84783136daa93568b364a5f01228cacbe/design/one-pager-ignore-changes.md + items: + description: |- + A ManagementAction represents an action that the Crossplane controllers + can take on an external resource. + enum: + - Observe + - Create + - Update + - Delete + - LateInitialize + - '*' + type: string + type: array + providerConfigRef: + default: + name: default + description: |- + ProviderConfigReference specifies how the provider that will be used to + create, observe, update, and delete this managed resource should be + configured. + 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 + publishConnectionDetailsTo: + description: |- + PublishConnectionDetailsTo specifies the connection secret config which + contains a name, metadata and a reference to secret store config to + which any connection details for this managed resource should be written. + Connection details frequently include the endpoint, username, + and password required to connect to the managed resource. + properties: + configRef: + default: + name: default + description: |- + SecretStoreConfigRef specifies which secret store config should be used + for this ConnectionSecret. + 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 + metadata: + description: Metadata is the metadata for connection secret. + properties: + annotations: + additionalProperties: + type: string + description: |- + Annotations are the annotations to be added to connection secret. + - For Kubernetes secrets, this will be used as "metadata.annotations". + - It is up to Secret Store implementation for others store types. + type: object + labels: + additionalProperties: + type: string + description: |- + Labels are the labels/tags to be added to connection secret. + - For Kubernetes secrets, this will be used as "metadata.labels". + - It is up to Secret Store implementation for others store types. + type: object + type: + description: |- + Type is the SecretType for the connection secret. + - Only valid for Kubernetes Secret Stores. + type: string + type: object + name: + description: Name is the name of the connection secret. + type: string + required: + - name + type: object + writeConnectionSecretToRef: + description: |- + WriteConnectionSecretToReference specifies the namespace and name of a + Secret to which any connection details for this managed resource should + be written. Connection details frequently include the endpoint, username, + and password required to connect to the managed resource. + This field is planned to be replaced in a future release in favor of + PublishConnectionDetailsTo. Currently, both could be set independently + and connection details would be published to both without affecting + each other. + properties: + name: + description: Name of the secret. + type: string + namespace: + description: Namespace of the secret. + type: string + required: + - name + - namespace + type: object + required: + - forProvider + type: object + x-kubernetes-validations: + - message: spec.forProvider.enabled is a required parameter + rule: '!(''*'' in self.managementPolicies || ''Create'' in self.managementPolicies + || ''Update'' in self.managementPolicies) || has(self.forProvider.enabled) + || (has(self.initProvider) && has(self.initProvider.enabled))' + status: + description: RegionStatus defines the observed state of Region. + properties: + atProvider: + properties: + accountId: + description: The ID of the target account when managing member + accounts. Will manage current user's account by default if omitted. + To use this parameter, the caller must be an identity in the + organization's management account or a delegated administrator + account. The specified account ID must also be a member account + in the same organization. The organization must have all features + enabled, and the organization must have trusted access enabled + for the Account Management service, and optionally a delegated + admin account assigned. + type: string + enabled: + description: Whether the region is enabled. + type: boolean + id: + type: string + optStatus: + description: The region opt status. + type: string + regionName: + description: The region name to manage. + type: string + type: object + conditions: + description: Conditions of the resource. + items: + description: A Condition that may apply to a resource. + properties: + lastTransitionTime: + description: |- + LastTransitionTime is the last time this condition transitioned from one + status to another. + format: date-time + type: string + message: + description: |- + A Message containing details about this condition's last transition from + one status to another, if any. + type: string + observedGeneration: + description: |- + ObservedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + type: integer + reason: + description: A Reason for this condition's last transition from + one status to another. + type: string + status: + description: Status of this condition; is it currently True, + False, or Unknown? + type: string + type: + description: |- + Type of this condition. At most one of each condition type may apply to + a resource at any point in time. + type: string + required: + - lastTransitionTime + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + observedGeneration: + description: |- + ObservedGeneration is the latest metadata.generation + which resulted in either a ready state, or stalled due to error + it can not recover from without human intervention. + format: int64 + type: integer + type: object + required: + - spec + type: object + served: true + storage: true + subresources: + status: {}