diff --git a/.gitignore b/.gitignore index d277be8..be8d8b3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ *.swp *~ .idea +.venv /docs/site bin build diff --git a/apis/v1alpha1/ack-generate-metadata.yaml b/apis/v1alpha1/ack-generate-metadata.yaml index c6c8298..1b018d9 100755 --- a/apis/v1alpha1/ack-generate-metadata.yaml +++ b/apis/v1alpha1/ack-generate-metadata.yaml @@ -1,8 +1,8 @@ ack_generate_info: - build_date: "2025-09-19T17:08:09Z" - build_hash: 6b4211163dcc34776b01da9a18217bac0f4103fd - go_version: go1.24.6 - version: v0.52.0 + build_date: "2025-11-13T00:20:46Z" + build_hash: c833f2d14f4fe8953663ff92f4661ae5fb01b8c8 + go_version: go1.25.1 + version: v0.53.1 api_directory_checksum: 2627dc306e3a83c86c04050c6c4336451459e728 api_version: v1alpha1 aws_sdk_go_version: v1.32.6 diff --git a/config/controller/deployment.yaml b/config/controller/deployment.yaml index 29b8368..e2edbed 100644 --- a/config/controller/deployment.yaml +++ b/config/controller/deployment.yaml @@ -43,6 +43,7 @@ spec: - "$(RECONCILE_DEFAULT_MAX_CONCURRENT_SYNCS)" - --feature-gates - "$(FEATURE_GATES)" + - --enable-carm=$(ENABLE_CARM) image: controller:latest name: controller ports: @@ -80,6 +81,8 @@ spec: value: "1" - name: "FEATURE_GATES" value: "" + - name: "ENABLE_CARM" + value: "true" securityContext: allowPrivilegeEscalation: false privileged: false diff --git a/config/crd/bases/sqs.services.k8s.aws_queues.yaml b/config/crd/bases/sqs.services.k8s.aws_queues.yaml index bbb33b8..4f2c572 100644 --- a/config/crd/bases/sqs.services.k8s.aws_queues.yaml +++ b/config/crd/bases/sqs.services.k8s.aws_queues.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.2 + controller-gen.kubebuilder.io/version: v0.19.0 name: queues.sqs.services.k8s.aws spec: group: sqs.services.k8s.aws diff --git a/config/crd/common/bases/services.k8s.aws_adoptedresources.yaml b/config/crd/common/bases/services.k8s.aws_adoptedresources.yaml deleted file mode 100644 index b7be322..0000000 --- a/config/crd/common/bases/services.k8s.aws_adoptedresources.yaml +++ /dev/null @@ -1,249 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.2 - name: adoptedresources.services.k8s.aws -spec: - group: services.k8s.aws - names: - kind: AdoptedResource - listKind: AdoptedResourceList - plural: adoptedresources - singular: adoptedresource - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: AdoptedResource is the schema for the AdoptedResource API. - 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: AdoptedResourceSpec defines the desired state of the AdoptedResource. - properties: - aws: - description: AWSIdentifiers provide all unique ways to reference an - AWS resource. - properties: - additionalKeys: - additionalProperties: - type: string - description: |- - AdditionalKeys represents any additional arbitrary identifiers used when - describing the target resource. - type: object - arn: - description: |- - ARN is the AWS Resource Name for the resource. It is a globally - unique identifier. - type: string - nameOrID: - description: |- - NameOrId is a user-supplied string identifier for the resource. It may - or may not be globally unique, depending on the type of resource. - type: string - type: object - kubernetes: - description: |- - ResourceWithMetadata provides the values necessary to create a - Kubernetes resource and override any of its metadata values. - properties: - group: - type: string - kind: - type: string - metadata: - description: |- - ObjectMeta is metadata that all persisted resources must have, which includes all objects - users must create. - It is not possible to use `metav1.ObjectMeta` inside spec, as the controller-gen - automatically converts this to an arbitrary string-string map. - https://github.com/kubernetes-sigs/controller-tools/issues/385 - - Active discussion about inclusion of this field in the spec is happening in this PR: - https://github.com/kubernetes-sigs/controller-tools/pull/395 - - Until this is allowed, or if it never is, we will produce a subset of the object meta - that contains only the fields which the user is allowed to modify in the metadata. - properties: - annotations: - additionalProperties: - type: string - description: |- - Annotations is an unstructured key value map stored with a resource that may be - set by external tools to store and retrieve arbitrary metadata. They are not - queryable and should be preserved when modifying objects. - More info: http://kubernetes.io/docs/user-guide/annotations - type: object - generateName: - description: |- - GenerateName is an optional prefix, used by the server, to generate a unique - name ONLY IF the Name field has not been provided. - If this field is used, the name returned to the client will be different - than the name passed. This value will also be combined with a unique suffix. - The provided value has the same validation rules as the Name field, - and may be truncated by the length of the suffix required to make the value - unique on the server. - - If this field is specified and the generated name exists, the server will - NOT return a 409 - instead, it will either return 201 Created or 500 with Reason - ServerTimeout indicating a unique name could not be found in the time allotted, and the client - should retry (optionally after the time indicated in the Retry-After header). - - Applied only if Name is not specified. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency - type: string - labels: - additionalProperties: - type: string - description: |- - Map of string keys and values that can be used to organize and categorize - (scope and select) objects. May match selectors of replication controllers - and services. - More info: http://kubernetes.io/docs/user-guide/labels - type: object - name: - description: |- - Name must be unique within a namespace. Is required when creating resources, although - some resources may allow a client to request the generation of an appropriate name - automatically. Name is primarily intended for creation idempotence and configuration - definition. - Cannot be updated. - More info: http://kubernetes.io/docs/user-guide/identifiers#names - type: string - namespace: - description: |- - Namespace defines the space within each name must be unique. An empty namespace is - equivalent to the "default" namespace, but "default" is the canonical representation. - Not all objects are required to be scoped to a namespace - the value of this field for - those objects will be empty. - - Must be a DNS_LABEL. - Cannot be updated. - More info: http://kubernetes.io/docs/user-guide/namespaces - type: string - ownerReferences: - description: |- - List of objects depended by this object. If ALL objects in the list have - been deleted, this object will be garbage collected. If this object is managed by a controller, - then an entry in this list will point to this controller, with the controller field set to true. - There cannot be more than one managing controller. - items: - description: |- - OwnerReference contains enough information to let you identify an owning - object. An owning object must be in the same namespace as the dependent, or - be cluster-scoped, so there is no namespace field. - properties: - apiVersion: - description: API version of the referent. - type: string - blockOwnerDeletion: - description: |- - If true, AND if the owner has the "foregroundDeletion" finalizer, then - the owner cannot be deleted from the key-value store until this - reference is removed. - See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion - for how the garbage collector interacts with this field and enforces the foreground deletion. - Defaults to false. - To set this field, a user needs "delete" permission of the owner, - otherwise 422 (Unprocessable Entity) will be returned. - type: boolean - controller: - description: If true, this reference points to the managing - controller. - type: boolean - kind: - description: |- - Kind of the referent. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names - type: string - uid: - description: |- - UID of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids - type: string - required: - - apiVersion - - kind - - name - - uid - type: object - x-kubernetes-map-type: atomic - type: array - type: object - required: - - group - - kind - type: object - required: - - aws - - kubernetes - type: object - status: - description: AdoptedResourceStatus defines the observed status of the - AdoptedResource. - properties: - conditions: - description: |- - A collection of `ackv1alpha1.Condition` objects that describe the various - terminal states of the adopted resource CR and its target custom resource - items: - description: |- - Condition is the common struct used by all CRDs managed by ACK service - controllers to indicate terminal states of the CR and its backend AWS - service API resource - properties: - lastTransitionTime: - description: Last time the condition transitioned from one status - to another. - format: date-time - type: string - message: - description: A human readable message indicating details about - the transition. - type: string - reason: - description: The reason for the condition's last transition. - type: string - status: - description: Status of the condition, one of True, False, Unknown. - type: string - type: - description: Type is the type of the Condition - type: string - required: - - status - - type - type: object - type: array - required: - - conditions - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/config/crd/common/bases/services.k8s.aws_fieldexports.yaml b/config/crd/common/bases/services.k8s.aws_fieldexports.yaml index 49b4f38..6e2c61e 100644 --- a/config/crd/common/bases/services.k8s.aws_fieldexports.yaml +++ b/config/crd/common/bases/services.k8s.aws_fieldexports.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.2 + controller-gen.kubebuilder.io/version: v0.19.0 name: fieldexports.services.k8s.aws spec: group: services.k8s.aws diff --git a/config/crd/common/bases/services.k8s.aws_iamroleselectors.yaml b/config/crd/common/bases/services.k8s.aws_iamroleselectors.yaml new file mode 100644 index 0000000..9477c90 --- /dev/null +++ b/config/crd/common/bases/services.k8s.aws_iamroleselectors.yaml @@ -0,0 +1,90 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + name: iamroleselectors.services.k8s.aws +spec: + group: services.k8s.aws + names: + kind: IAMRoleSelector + listKind: IAMRoleSelectorList + plural: iamroleselectors + singular: iamroleselector + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: IAMRoleSelector is the schema for the IAMRoleSelector API. + 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: + properties: + arn: + type: string + x-kubernetes-validations: + - message: Value is immutable once set + rule: self == oldSelf + namespaceSelector: + description: IAMRoleSelectorSpec defines the desired state of IAMRoleSelector + properties: + labelSelector: + description: LabelSelector is a label query over a set of resources. + properties: + matchLabels: + additionalProperties: + type: string + type: object + required: + - matchLabels + type: object + names: + items: + type: string + type: array + required: + - names + type: object + resourceTypeSelector: + items: + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + type: array + required: + - arn + type: object + status: + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/common/kustomization.yaml b/config/crd/common/kustomization.yaml index 96349f6..8165534 100644 --- a/config/crd/common/kustomization.yaml +++ b/config/crd/common/kustomization.yaml @@ -3,5 +3,5 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - - bases/services.k8s.aws_adoptedresources.yaml + - bases/services.k8s.aws_iamroleselectors.yaml - bases/services.k8s.aws_fieldexports.yaml diff --git a/config/rbac/cluster-role-controller.yaml b/config/rbac/cluster-role-controller.yaml index fe26445..0c135ef 100644 --- a/config/rbac/cluster-role-controller.yaml +++ b/config/rbac/cluster-role-controller.yaml @@ -41,8 +41,8 @@ rules: - apiGroups: - services.k8s.aws resources: - - adoptedresources - fieldexports + - iamroleselectors verbs: - create - delete @@ -54,8 +54,8 @@ rules: - apiGroups: - services.k8s.aws resources: - - adoptedresources/status - fieldexports/status + - iamroleselectors/status verbs: - get - patch diff --git a/go.mod b/go.mod index bd425ee..985ba09 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ toolchain go1.24.1 require ( github.com/aws-controllers-k8s/iam-controller v1.1.1 github.com/aws-controllers-k8s/kms-controller v1.0.2 - github.com/aws-controllers-k8s/runtime v0.52.0 + github.com/aws-controllers-k8s/runtime v0.53.1 github.com/aws/aws-sdk-go v1.55.5 github.com/aws/aws-sdk-go-v2 v1.34.0 github.com/aws/aws-sdk-go-v2/service/sqs v1.37.10 diff --git a/go.sum b/go.sum index 4a0b4d8..b77187f 100644 --- a/go.sum +++ b/go.sum @@ -2,8 +2,8 @@ github.com/aws-controllers-k8s/iam-controller v1.1.1 h1:O6arh7DNlQF26MEKzgA2/kBE github.com/aws-controllers-k8s/iam-controller v1.1.1/go.mod h1:2+ARwRpazTq5MErjMz0MpXHhtAzRfNtY56Uj0gvu9vE= github.com/aws-controllers-k8s/kms-controller v1.0.2 h1:v8nh/oaX/U6spCwBDaWyem7XXpzoP/MnkJyEjNOZN9s= github.com/aws-controllers-k8s/kms-controller v1.0.2/go.mod h1:BeoijsyGjJ9G5VcDjpFdxBW0IxaeKXYX497XmUJiPSQ= -github.com/aws-controllers-k8s/runtime v0.52.0 h1:Q5UIAn6SSBr60t/DiU/zr6NLBlUuK2AG3yy2ma/9gDU= -github.com/aws-controllers-k8s/runtime v0.52.0/go.mod h1:OkUJN+Ds799JLYZsMJrO2vDJ4snxUeHK2MgrQHbU+Qc= +github.com/aws-controllers-k8s/runtime v0.53.1 h1:l9MkR1KfZW8H8icT5rrRK3pdnVVA4io/eINVe5aspWs= +github.com/aws-controllers-k8s/runtime v0.53.1/go.mod h1:OkUJN+Ds799JLYZsMJrO2vDJ4snxUeHK2MgrQHbU+Qc= github.com/aws/aws-sdk-go v1.55.5 h1:KKUZBfBoyqy5d3swXyiC7Q76ic40rYcbqH7qjh59kzU= github.com/aws/aws-sdk-go v1.55.5/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= github.com/aws/aws-sdk-go-v2 v1.34.0 h1:9iyL+cjifckRGEVpRKZP3eIxVlL06Qk1Tk13vreaVQU= diff --git a/helm/crds/services.k8s.aws_adoptedresources.yaml b/helm/crds/services.k8s.aws_adoptedresources.yaml deleted file mode 100644 index b7be322..0000000 --- a/helm/crds/services.k8s.aws_adoptedresources.yaml +++ /dev/null @@ -1,249 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.16.2 - name: adoptedresources.services.k8s.aws -spec: - group: services.k8s.aws - names: - kind: AdoptedResource - listKind: AdoptedResourceList - plural: adoptedresources - singular: adoptedresource - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: AdoptedResource is the schema for the AdoptedResource API. - 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: AdoptedResourceSpec defines the desired state of the AdoptedResource. - properties: - aws: - description: AWSIdentifiers provide all unique ways to reference an - AWS resource. - properties: - additionalKeys: - additionalProperties: - type: string - description: |- - AdditionalKeys represents any additional arbitrary identifiers used when - describing the target resource. - type: object - arn: - description: |- - ARN is the AWS Resource Name for the resource. It is a globally - unique identifier. - type: string - nameOrID: - description: |- - NameOrId is a user-supplied string identifier for the resource. It may - or may not be globally unique, depending on the type of resource. - type: string - type: object - kubernetes: - description: |- - ResourceWithMetadata provides the values necessary to create a - Kubernetes resource and override any of its metadata values. - properties: - group: - type: string - kind: - type: string - metadata: - description: |- - ObjectMeta is metadata that all persisted resources must have, which includes all objects - users must create. - It is not possible to use `metav1.ObjectMeta` inside spec, as the controller-gen - automatically converts this to an arbitrary string-string map. - https://github.com/kubernetes-sigs/controller-tools/issues/385 - - Active discussion about inclusion of this field in the spec is happening in this PR: - https://github.com/kubernetes-sigs/controller-tools/pull/395 - - Until this is allowed, or if it never is, we will produce a subset of the object meta - that contains only the fields which the user is allowed to modify in the metadata. - properties: - annotations: - additionalProperties: - type: string - description: |- - Annotations is an unstructured key value map stored with a resource that may be - set by external tools to store and retrieve arbitrary metadata. They are not - queryable and should be preserved when modifying objects. - More info: http://kubernetes.io/docs/user-guide/annotations - type: object - generateName: - description: |- - GenerateName is an optional prefix, used by the server, to generate a unique - name ONLY IF the Name field has not been provided. - If this field is used, the name returned to the client will be different - than the name passed. This value will also be combined with a unique suffix. - The provided value has the same validation rules as the Name field, - and may be truncated by the length of the suffix required to make the value - unique on the server. - - If this field is specified and the generated name exists, the server will - NOT return a 409 - instead, it will either return 201 Created or 500 with Reason - ServerTimeout indicating a unique name could not be found in the time allotted, and the client - should retry (optionally after the time indicated in the Retry-After header). - - Applied only if Name is not specified. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#idempotency - type: string - labels: - additionalProperties: - type: string - description: |- - Map of string keys and values that can be used to organize and categorize - (scope and select) objects. May match selectors of replication controllers - and services. - More info: http://kubernetes.io/docs/user-guide/labels - type: object - name: - description: |- - Name must be unique within a namespace. Is required when creating resources, although - some resources may allow a client to request the generation of an appropriate name - automatically. Name is primarily intended for creation idempotence and configuration - definition. - Cannot be updated. - More info: http://kubernetes.io/docs/user-guide/identifiers#names - type: string - namespace: - description: |- - Namespace defines the space within each name must be unique. An empty namespace is - equivalent to the "default" namespace, but "default" is the canonical representation. - Not all objects are required to be scoped to a namespace - the value of this field for - those objects will be empty. - - Must be a DNS_LABEL. - Cannot be updated. - More info: http://kubernetes.io/docs/user-guide/namespaces - type: string - ownerReferences: - description: |- - List of objects depended by this object. If ALL objects in the list have - been deleted, this object will be garbage collected. If this object is managed by a controller, - then an entry in this list will point to this controller, with the controller field set to true. - There cannot be more than one managing controller. - items: - description: |- - OwnerReference contains enough information to let you identify an owning - object. An owning object must be in the same namespace as the dependent, or - be cluster-scoped, so there is no namespace field. - properties: - apiVersion: - description: API version of the referent. - type: string - blockOwnerDeletion: - description: |- - If true, AND if the owner has the "foregroundDeletion" finalizer, then - the owner cannot be deleted from the key-value store until this - reference is removed. - See https://kubernetes.io/docs/concepts/architecture/garbage-collection/#foreground-deletion - for how the garbage collector interacts with this field and enforces the foreground deletion. - Defaults to false. - To set this field, a user needs "delete" permission of the owner, - otherwise 422 (Unprocessable Entity) will be returned. - type: boolean - controller: - description: If true, this reference points to the managing - controller. - type: boolean - kind: - description: |- - Kind of the referent. - More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds - type: string - name: - description: |- - Name of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#names - type: string - uid: - description: |- - UID of the referent. - More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names#uids - type: string - required: - - apiVersion - - kind - - name - - uid - type: object - x-kubernetes-map-type: atomic - type: array - type: object - required: - - group - - kind - type: object - required: - - aws - - kubernetes - type: object - status: - description: AdoptedResourceStatus defines the observed status of the - AdoptedResource. - properties: - conditions: - description: |- - A collection of `ackv1alpha1.Condition` objects that describe the various - terminal states of the adopted resource CR and its target custom resource - items: - description: |- - Condition is the common struct used by all CRDs managed by ACK service - controllers to indicate terminal states of the CR and its backend AWS - service API resource - properties: - lastTransitionTime: - description: Last time the condition transitioned from one status - to another. - format: date-time - type: string - message: - description: A human readable message indicating details about - the transition. - type: string - reason: - description: The reason for the condition's last transition. - type: string - status: - description: Status of the condition, one of True, False, Unknown. - type: string - type: - description: Type is the type of the Condition - type: string - required: - - status - - type - type: object - type: array - required: - - conditions - type: object - type: object - served: true - storage: true - subresources: - status: {} diff --git a/helm/crds/services.k8s.aws_fieldexports.yaml b/helm/crds/services.k8s.aws_fieldexports.yaml index 49b4f38..6e2c61e 100644 --- a/helm/crds/services.k8s.aws_fieldexports.yaml +++ b/helm/crds/services.k8s.aws_fieldexports.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.2 + controller-gen.kubebuilder.io/version: v0.19.0 name: fieldexports.services.k8s.aws spec: group: services.k8s.aws diff --git a/helm/crds/services.k8s.aws_iamroleselectors.yaml b/helm/crds/services.k8s.aws_iamroleselectors.yaml new file mode 100644 index 0000000..9477c90 --- /dev/null +++ b/helm/crds/services.k8s.aws_iamroleselectors.yaml @@ -0,0 +1,90 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.19.0 + name: iamroleselectors.services.k8s.aws +spec: + group: services.k8s.aws + names: + kind: IAMRoleSelector + listKind: IAMRoleSelectorList + plural: iamroleselectors + singular: iamroleselector + scope: Cluster + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: IAMRoleSelector is the schema for the IAMRoleSelector API. + 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: + properties: + arn: + type: string + x-kubernetes-validations: + - message: Value is immutable once set + rule: self == oldSelf + namespaceSelector: + description: IAMRoleSelectorSpec defines the desired state of IAMRoleSelector + properties: + labelSelector: + description: LabelSelector is a label query over a set of resources. + properties: + matchLabels: + additionalProperties: + type: string + type: object + required: + - matchLabels + type: object + names: + items: + type: string + type: array + required: + - names + type: object + resourceTypeSelector: + items: + properties: + group: + type: string + kind: + type: string + version: + type: string + required: + - group + - kind + - version + type: object + type: array + required: + - arn + type: object + status: + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/helm/crds/sqs.services.k8s.aws_queues.yaml b/helm/crds/sqs.services.k8s.aws_queues.yaml index d47a775..9b88afc 100644 --- a/helm/crds/sqs.services.k8s.aws_queues.yaml +++ b/helm/crds/sqs.services.k8s.aws_queues.yaml @@ -3,7 +3,7 @@ apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.16.2 + controller-gen.kubebuilder.io/version: v0.19.0 name: queues.sqs.services.k8s.aws spec: group: sqs.services.k8s.aws diff --git a/helm/templates/_helpers.tpl b/helm/templates/_helpers.tpl index 19f3e26..bdb403f 100644 --- a/helm/templates/_helpers.tpl +++ b/helm/templates/_helpers.tpl @@ -88,8 +88,8 @@ rules: - apiGroups: - services.k8s.aws resources: - - adoptedresources - fieldexports + - iamroleselectors verbs: - create - delete @@ -101,8 +101,8 @@ rules: - apiGroups: - services.k8s.aws resources: - - adoptedresources/status - fieldexports/status + - iamroleselectors/status verbs: - get - patch diff --git a/helm/values.yaml b/helm/values.yaml index 1a871f9..e3da2ec 100644 --- a/helm/values.yaml +++ b/helm/values.yaml @@ -181,4 +181,6 @@ featureGates: # Enable ReadOnlyResources feature/annotation. ReadOnlyResources: true # Enable ResourceAdoption feature/annotation. - ResourceAdoption: true \ No newline at end of file + ResourceAdoption: true + # Enable IAMRoleSelector, a multirole feature, replacing CARM. See https://github.com/aws-controllers-k8s/community/pull/2628 + IAMRoleSelector: false \ No newline at end of file diff --git a/pkg/resource/registry.go b/pkg/resource/registry.go index 3f3aa28..969531d 100644 --- a/pkg/resource/registry.go +++ b/pkg/resource/registry.go @@ -20,8 +20,8 @@ import ( acktypes "github.com/aws-controllers-k8s/runtime/pkg/types" ) -// +kubebuilder:rbac:groups=services.k8s.aws,resources=adoptedresources,verbs=get;list;watch;create;update;patch;delete -// +kubebuilder:rbac:groups=services.k8s.aws,resources=adoptedresources/status,verbs=get;update;patch +// +kubebuilder:rbac:groups=services.k8s.aws,resources=iamroleselectors,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=services.k8s.aws,resources=iamroleselectors/status,verbs=get;update;patch // +kubebuilder:rbac:groups=services.k8s.aws,resources=fieldexports,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=services.k8s.aws,resources=fieldexports/status,verbs=get;update;patch // +kubebuilder:rbac:groups="",resources=namespaces,verbs=get;list;watch diff --git a/test/e2e/fixtures.py b/test/e2e/fixtures.py new file mode 100644 index 0000000..9f6c2fe --- /dev/null +++ b/test/e2e/fixtures.py @@ -0,0 +1,41 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You may +# not use this file except in compliance with the License. A copy of the +# License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file 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. + +"""Fixtures common to all SQS controller tests""" + +from acktest.k8s import resource as k8s + +CRD_GROUP = "services.k8s.aws" +CRD_VERSION = "v1alpha1" +RESOURCE_PLURAL = "iamroleselectors" + +def create_iam_role_selector(namespace: str, name: str, role: str): + iam_role_selector = { + "apiVersion": "services.k8s.aws/v1alpha1", + "kind": "IAMRoleSelector", + "metadata": { + "name": name, + }, + "spec": { + "namespaceSelector": { + "names": [namespace] + }, + "arn": role + } + } + + ref = k8s.CustomResourceReference( + CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL, + name, namespace=None, + ) + k8s.create_custom_resource(ref, iam_role_selector) diff --git a/test/e2e/requirements.txt b/test/e2e/requirements.txt index ce60a38..e3fb252 100644 --- a/test/e2e/requirements.txt +++ b/test/e2e/requirements.txt @@ -1 +1 @@ -acktest @ git+https://github.com/aws-controllers-k8s/test-infra.git@5a09bbdb961ea14a65b15b63769134125023ac61 +acktest @ git+https://github.com/michaelhtm/ack-test-infra.git@a9fe15e9690818d63b4ae4f40b978da860a6d291 diff --git a/test/e2e/resources/queue_irs.yaml b/test/e2e/resources/queue_irs.yaml new file mode 100644 index 0000000..32da045 --- /dev/null +++ b/test/e2e/resources/queue_irs.yaml @@ -0,0 +1,7 @@ +apiVersion: sqs.services.k8s.aws/v1alpha1 +kind: Queue +metadata: + name: $QUEUE_NAME + namespace: $NAMESPACE +spec: + queueName: $QUEUE_NAME diff --git a/test/e2e/tests/test_queue.py b/test/e2e/tests/test_queue.py index c4e9f28..e162c7c 100644 --- a/test/e2e/tests/test_queue.py +++ b/test/e2e/tests/test_queue.py @@ -147,26 +147,3 @@ def test_crud(self, simple_queue): tags.assert_equal_without_ack_tags( expect_after_update_tags, latest_tags, ) - - -class TestAdoptQueue(adoption.AbstractAdoptionTest): - RESOURCE_PLURAL: str = RESOURCE_PLURAL - RESOURCE_VERSION: str = CRD_VERSION - - _queue_name: str = random_suffix_name("ack-adopted-queue", 24) - _queue_url: str - - def bootstrap_resource(self): - c = boto3.client('sqs') - resp = c.create_queue(QueueName=self._queue_name) - self._queue_url = resp['QueueUrl'] - - def cleanup_resource(self): - client = boto3.client('sqs') - client.delete_queue(QueueUrl=self._queue_url) - - def get_resource_spec(self) -> adoption.AdoptedResourceSpec: - return adoption.AdoptedResourceSpec( - aws=adoption.AdoptedResourceNameOrIDIdentifier(additionalKeys={}, nameOrID=self._queue_url), - kubernetes=adoption.AdoptedResourceKubernetesIdentifiers(CRD_GROUP, RESOURCE_KIND), - ) diff --git a/test/e2e/tests/test_queue_irs.py b/test/e2e/tests/test_queue_irs.py new file mode 100644 index 0000000..8f8c14b --- /dev/null +++ b/test/e2e/tests/test_queue_irs.py @@ -0,0 +1,117 @@ +# Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"). You may +# not use this file except in compliance with the License. A copy of the +# License is located at +# +# http://aws.amazon.com/apache2.0/ +# +# or in the "license" file accompanying this file. This file 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. + +"""Integration tests for ECR Cross Account Resource Management. +Ideally we want these tests to be in the ACK runtime, but we don't have a way +to run them there yet. So we'll run them here for now. +""" + +import pytest +import time +import logging +import boto3 +import os + +from acktest.resources import random_suffix_name +from acktest.k8s import resource as k8s +from e2e import service_marker, CRD_GROUP, CRD_VERSION, load_sqs_resource +from e2e.replacement_values import REPLACEMENT_VALUES +from e2e.fixtures import create_iam_role_selector + +CREATE_WAIT_AFTER_SECONDS = 5 + +RESOURCE_PLURAL = "queues" + +CREATE_WAIT_AFTER_SECONDS = 10 +UPDATE_WAIT_AFTER_SECONDS = 10 +DELETE_WAIT_AFTER_SECONDS = 10 + +TESTING_NAMESPACE = "irs-testing" +TESTING_ASSUME_ROLE = "arn:aws:iam::637423602339:role/ack-carm-role-DO-NOT-DELETE" + +@service_marker +@pytest.mark.canary +class TestIRS: + def get_queue_url(self, queue_name: str) -> dict: + sqs_client = boto3.client( + "sqs", + aws_access_key_id=os.environ["CARM_AWS_ACCESS_KEY_ID"], + aws_secret_access_key=os.environ["CARM_AWS_SECRET_ACCESS_KEY"], + aws_session_token=os.environ["CARM_AWS_SESSION_TOKEN"], + ) + try: + resp = sqs_client.get_queue_url(QueueName=queue_name) + except Exception as e: + logging.debug(e) + return None + + return resp + + def queue_exists(self, queue_name: str) -> bool: + return self.get_queue_url(queue_name) is not None + + def test_basic_queue(self): + k8s.create_k8s_namespace( + TESTING_NAMESPACE, + annotations={} + ) + time.sleep(CREATE_WAIT_AFTER_SECONDS) + create_iam_role_selector( + TESTING_NAMESPACE, + "ack-role-selector", + TESTING_ASSUME_ROLE + ) + + time.sleep(CREATE_WAIT_AFTER_SECONDS) + + resource_name = random_suffix_name("sqs-queue", 24) + + replacements = REPLACEMENT_VALUES.copy() + replacements["QUEUE_NAME"] = resource_name + replacements["NAMESPACE"] = TESTING_NAMESPACE + # Load ECR CR + resource_data = load_sqs_resource( + "queue_irs", + additional_replacements=replacements, + ) + logging.debug(resource_data) + + # Create k8s resource + ref = k8s.CustomResourceReference( + CRD_GROUP, CRD_VERSION, RESOURCE_PLURAL, + resource_name, namespace=TESTING_NAMESPACE, + ) + + k8s.create_custom_resource(ref, resource_data) + cr = k8s.wait_resource_consumed_by_controller(ref) + assert cr is not None + assert k8s.get_resource_exists(ref) + + time.sleep(CREATE_WAIT_AFTER_SECONDS) + + assert k8s.wait_on_condition(ref, "Ready", "True", wait_periods=5) + assert k8s.wait_on_condition(ref, "ACK.IAMRoleSelected", "True", wait_periods=5) + + # Check SQS queue exists + resp = self.get_queue_url(resource_name) + assert resp != None + + # Delete k8s resource + _, deleted = k8s.delete_custom_resource(ref) + assert deleted is True + + time.sleep(DELETE_WAIT_AFTER_SECONDS) + + # Check SQS queue doesn't exists + exists = self.queue_exists(resource_name) + assert not exists \ No newline at end of file