From e367bc03e886a26da944c634054fe6ec6efaf983 Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Sat, 29 Nov 2025 18:26:29 -0300 Subject: [PATCH 1/9] endpoint: generate code with scaffolding tool go run ./cmd/scaffold-controller \ -interactive=false \ -kind Endpoint \ -gophercloud-client NewIdentityV3 \ -gophercloud-module github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints \ -required-create-dependency Service Signed-off-by: Winicius Silva --- api/v1alpha1/endpoint_types.go | 88 +++++ .../zz_generated.endpoint-resource.go | 177 ++++++++++ .../openstack.k-orc.cloud_endpoints.yaml | 322 ++++++++++++++++++ .../samples/openstack_v1alpha1_endpoint.yaml | 14 + internal/controllers/endpoint/actuator.go | 283 +++++++++++++++ .../controllers/endpoint/actuator_test.go | 119 +++++++ internal/controllers/endpoint/controller.go | 114 +++++++ internal/controllers/endpoint/status.go | 64 ++++ .../tests/endpoint-create-full/00-assert.yaml | 33 ++ .../00-create-resource.yaml | 29 ++ .../tests/endpoint-create-full/00-secret.yaml | 6 + .../tests/endpoint-create-full/README.md | 11 + .../endpoint-create-minimal/00-assert.yaml | 32 ++ .../00-create-resource.yaml | 28 ++ .../endpoint-create-minimal/00-secret.yaml | 6 + .../endpoint-create-minimal/01-assert.yaml | 11 + .../01-delete-secret.yaml | 7 + .../tests/endpoint-create-minimal/README.md | 15 + .../endpoint-import-dependency/00-assert.yaml | 17 + .../00-import-resource.yaml | 26 ++ .../endpoint-import-dependency/00-secret.yaml | 6 + .../endpoint-import-dependency/01-assert.yaml | 32 ++ .../01-create-trap-resource.yaml | 42 +++ .../endpoint-import-dependency/02-assert.yaml | 34 ++ .../02-create-resource.yaml | 41 +++ .../endpoint-import-dependency/03-assert.yaml | 6 + .../03-delete-import-dependencies.yaml | 7 + .../endpoint-import-dependency/04-assert.yaml | 6 + .../04-delete-resource.yaml | 7 + .../endpoint-import-dependency/README.md | 29 ++ .../endpoint-import-error/00-assert.yaml | 30 ++ .../00-create-resources.yaml | 43 +++ .../endpoint-import-error/00-secret.yaml | 6 + .../endpoint-import-error/01-assert.yaml | 15 + .../01-import-resource.yaml | 13 + .../tests/endpoint-import-error/README.md | 13 + .../tests/endpoint-import/00-assert.yaml | 15 + .../endpoint-import/00-import-resource.yaml | 15 + .../tests/endpoint-import/00-secret.yaml | 6 + .../tests/endpoint-import/01-assert.yaml | 34 ++ .../01-create-trap-resource.yaml | 31 ++ .../tests/endpoint-import/02-assert.yaml | 33 ++ .../endpoint-import/02-create-resource.yaml | 28 ++ .../endpoint/tests/endpoint-import/README.md | 18 + .../tests/endpoint-update/00-assert.yaml | 26 ++ .../endpoint-update/00-minimal-resource.yaml | 28 ++ .../endpoint-update/00-prerequisites.yaml | 6 + .../tests/endpoint-update/01-assert.yaml | 17 + .../endpoint-update/01-updated-resource.yaml | 10 + .../tests/endpoint-update/02-assert.yaml | 26 ++ .../endpoint-update/02-reverted-resource.yaml | 7 + .../endpoint/tests/endpoint-update/README.md | 17 + .../endpoint/zz_generated.adapter.go | 88 +++++ .../endpoint/zz_generated.controller.go | 45 +++ internal/osclients/endpoint.go | 104 ++++++ internal/osclients/mock/endpoint.go | 131 +++++++ .../api/v1alpha1/endpoint.go | 281 +++++++++++++++ .../api/v1alpha1/endpointfilter.go | 61 ++++ .../api/v1alpha1/endpointimport.go | 48 +++ .../api/v1alpha1/endpointresourcespec.go | 79 +++++ .../api/v1alpha1/endpointresourcestatus.go | 75 ++++ .../api/v1alpha1/endpointspec.go | 79 +++++ .../api/v1alpha1/endpointstatus.go | 66 ++++ .../clientset/typed/api/v1alpha1/endpoint.go | 74 ++++ .../typed/api/v1alpha1/fake/fake_endpoint.go | 51 +++ .../externalversions/api/v1alpha1/endpoint.go | 102 ++++++ pkg/clients/listers/api/v1alpha1/endpoint.go | 70 ++++ 67 files changed, 3403 insertions(+) create mode 100644 api/v1alpha1/endpoint_types.go create mode 100644 api/v1alpha1/zz_generated.endpoint-resource.go create mode 100644 config/crd/bases/openstack.k-orc.cloud_endpoints.yaml create mode 100644 config/samples/openstack_v1alpha1_endpoint.yaml create mode 100644 internal/controllers/endpoint/actuator.go create mode 100644 internal/controllers/endpoint/actuator_test.go create mode 100644 internal/controllers/endpoint/controller.go create mode 100644 internal/controllers/endpoint/status.go create mode 100644 internal/controllers/endpoint/tests/endpoint-create-full/00-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-create-full/00-create-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-create-full/00-secret.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-create-full/README.md create mode 100644 internal/controllers/endpoint/tests/endpoint-create-minimal/00-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-create-minimal/00-create-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-create-minimal/00-secret.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-create-minimal/01-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-create-minimal/01-delete-secret.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-create-minimal/README.md create mode 100644 internal/controllers/endpoint/tests/endpoint-import-dependency/00-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-dependency/00-import-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-dependency/00-secret.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-dependency/01-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-dependency/01-create-trap-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-dependency/02-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-dependency/02-create-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-dependency/03-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-dependency/03-delete-import-dependencies.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-dependency/04-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-dependency/04-delete-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-dependency/README.md create mode 100644 internal/controllers/endpoint/tests/endpoint-import-error/00-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-error/00-create-resources.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-error/00-secret.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-error/01-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-error/01-import-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import-error/README.md create mode 100644 internal/controllers/endpoint/tests/endpoint-import/00-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import/00-import-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import/00-secret.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import/01-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import/01-create-trap-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import/02-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import/02-create-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-import/README.md create mode 100644 internal/controllers/endpoint/tests/endpoint-update/00-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-update/00-minimal-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-update/00-prerequisites.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-update/01-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-update/01-updated-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-update/02-assert.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-update/02-reverted-resource.yaml create mode 100644 internal/controllers/endpoint/tests/endpoint-update/README.md create mode 100644 internal/controllers/endpoint/zz_generated.adapter.go create mode 100644 internal/controllers/endpoint/zz_generated.controller.go create mode 100644 internal/osclients/endpoint.go create mode 100644 internal/osclients/mock/endpoint.go create mode 100644 pkg/clients/applyconfiguration/api/v1alpha1/endpoint.go create mode 100644 pkg/clients/applyconfiguration/api/v1alpha1/endpointfilter.go create mode 100644 pkg/clients/applyconfiguration/api/v1alpha1/endpointimport.go create mode 100644 pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcespec.go create mode 100644 pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcestatus.go create mode 100644 pkg/clients/applyconfiguration/api/v1alpha1/endpointspec.go create mode 100644 pkg/clients/applyconfiguration/api/v1alpha1/endpointstatus.go create mode 100644 pkg/clients/clientset/clientset/typed/api/v1alpha1/endpoint.go create mode 100644 pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_endpoint.go create mode 100644 pkg/clients/informers/externalversions/api/v1alpha1/endpoint.go create mode 100644 pkg/clients/listers/api/v1alpha1/endpoint.go diff --git a/api/v1alpha1/endpoint_types.go b/api/v1alpha1/endpoint_types.go new file mode 100644 index 000000000..39271d1c2 --- /dev/null +++ b/api/v1alpha1/endpoint_types.go @@ -0,0 +1,88 @@ +/* +Copyright 2025 The ORC 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 v1alpha1 + +// EndpointResourceSpec contains the desired state of the resource. +type EndpointResourceSpec struct { + // name will be the name of the created resource. If not specified, the + // name of the ORC object will be used. + // +optional + Name *OpenStackName `json:"name,omitempty"` + + // description is a human-readable description for the resource. + // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MaxLength:=255 + // +optional + Description *string `json:"description,omitempty"` + + // serviceRef is a reference to the ORC Service which this resource is associated with. + // +required + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="serviceRef is immutable" + ServiceRef KubernetesNameRef `json:"serviceRef,omitempty"` + + // TODO(scaffolding): Add more types. + // To see what is supported, you can take inspiration from the CreateOpts structure from + // github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints + // + // Until you have implemented mutability for the field, you must add a CEL validation + // preventing the field being modified: + // `// +kubebuilder:validation:XValidation:rule="self == oldSelf",message=" is immutable"` +} + +// EndpointFilter defines an existing resource by its properties +// +kubebuilder:validation:MinProperties:=1 +type EndpointFilter struct { + // name of the existing resource + // +optional + Name *OpenStackName `json:"name,omitempty"` + + // description of the existing resource + // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MaxLength:=255 + // +optional + Description *string `json:"description,omitempty"` + + // serviceRef is a reference to the ORC Service which this resource is associated with. + // +optional + ServiceRef *KubernetesNameRef `json:"serviceRef,omitempty"` + + // TODO(scaffolding): Add more types. + // To see what is supported, you can take inspiration from the ListOpts structure from + // github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints +} + +// EndpointResourceStatus represents the observed state of the resource. +type EndpointResourceStatus struct { + // name is a Human-readable name for the resource. Might not be unique. + // +kubebuilder:validation:MaxLength=1024 + // +optional + Name string `json:"name,omitempty"` + + // description is a human-readable description for the resource. + // +kubebuilder:validation:MaxLength=1024 + // +optional + Description string `json:"description,omitempty"` + + // serviceID is the ID of the Service to which the resource is associated. + // +kubebuilder:validation:MaxLength=1024 + // +optional + ServiceID string `json:"serviceID,omitempty"` + + // TODO(scaffolding): Add more types. + // To see what is supported, you can take inspiration from the Endpoint structure from + // github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints +} diff --git a/api/v1alpha1/zz_generated.endpoint-resource.go b/api/v1alpha1/zz_generated.endpoint-resource.go new file mode 100644 index 000000000..33bebc76d --- /dev/null +++ b/api/v1alpha1/zz_generated.endpoint-resource.go @@ -0,0 +1,177 @@ +// Code generated by resource-generator. DO NOT EDIT. +/* +Copyright 2025 The ORC 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 v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EndpointImport specifies an existing resource which will be imported instead of +// creating a new one +// +kubebuilder:validation:MinProperties:=1 +// +kubebuilder:validation:MaxProperties:=1 +type EndpointImport struct { + // id contains the unique identifier of an existing OpenStack resource. Note + // that when specifying an import by ID, the resource MUST already exist. + // The ORC object will enter an error state if the resource does not exist. + // +optional + // +kubebuilder:validation:Format:=uuid + ID *string `json:"id,omitempty"` + + // filter contains a resource query which is expected to return a single + // result. The controller will continue to retry if filter returns no + // results. If filter returns multiple results the controller will set an + // error state and will not continue to retry. + // +optional + Filter *EndpointFilter `json:"filter,omitempty"` +} + +// EndpointSpec defines the desired state of an ORC object. +// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? has(self.resource) : true",message="resource must be specified when policy is managed" +// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'managed' ? !has(self.__import__) : true",message="import may not be specified when policy is managed" +// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? !has(self.resource) : true",message="resource may not be specified when policy is unmanaged" +// +kubebuilder:validation:XValidation:rule="self.managementPolicy == 'unmanaged' ? has(self.__import__) : true",message="import must be specified when policy is unmanaged" +// +kubebuilder:validation:XValidation:rule="has(self.managedOptions) ? self.managementPolicy == 'managed' : true",message="managedOptions may only be provided when policy is managed" +type EndpointSpec struct { + // import refers to an existing OpenStack resource which will be imported instead of + // creating a new one. + // +optional + Import *EndpointImport `json:"import,omitempty"` + + // resource specifies the desired state of the resource. + // + // resource may not be specified if the management policy is `unmanaged`. + // + // resource must be specified if the management policy is `managed`. + // +optional + Resource *EndpointResourceSpec `json:"resource,omitempty"` + + // managementPolicy defines how ORC will treat the object. Valid values are + // `managed`: ORC will create, update, and delete the resource; `unmanaged`: + // ORC will import an existing resource, and will not apply updates to it or + // delete it. + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="managementPolicy is immutable" + // +kubebuilder:default:=managed + // +optional + ManagementPolicy ManagementPolicy `json:"managementPolicy,omitempty"` + + // managedOptions specifies options which may be applied to managed objects. + // +optional + ManagedOptions *ManagedOptions `json:"managedOptions,omitempty"` + + // cloudCredentialsRef points to a secret containing OpenStack credentials + // +required + CloudCredentialsRef CloudCredentialsReference `json:"cloudCredentialsRef"` +} + +// EndpointStatus defines the observed state of an ORC resource. +type EndpointStatus struct { + // conditions represents the observed status of the object. + // Known .status.conditions.type are: "Available", "Progressing" + // + // Available represents the availability of the OpenStack resource. If it is + // true then the resource is ready for use. + // + // Progressing indicates whether the controller is still attempting to + // reconcile the current state of the OpenStack resource to the desired + // state. Progressing will be False either because the desired state has + // been achieved, or because some terminal error prevents it from ever being + // achieved and the controller is no longer attempting to reconcile. If + // Progressing is True, an observer waiting on the resource should continue + // to wait. + // + // +kubebuilder:validation:MaxItems:=32 + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` + + // id is the unique identifier of the OpenStack resource. + // +optional + ID *string `json:"id,omitempty"` + + // resource contains the observed state of the OpenStack resource. + // +optional + Resource *EndpointResourceStatus `json:"resource,omitempty"` +} + +var _ ObjectWithConditions = &Endpoint{} + +func (i *Endpoint) GetConditions() []metav1.Condition { + return i.Status.Conditions +} + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:resource:categories=openstack +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="ID",type="string",JSONPath=".status.id",description="Resource ID" +// +kubebuilder:printcolumn:name="Available",type="string",JSONPath=".status.conditions[?(@.type=='Available')].status",description="Availability status of resource" +// +kubebuilder:printcolumn:name="Message",type="string",JSONPath=".status.conditions[?(@.type=='Progressing')].message",description="Message describing current progress status" + +// Endpoint is the Schema for an ORC resource. +type Endpoint struct { + metav1.TypeMeta `json:",inline"` + + // metadata contains the object metadata + // +optional + metav1.ObjectMeta `json:"metadata,omitempty"` + + // spec specifies the desired state of the resource. + // +optional + Spec EndpointSpec `json:"spec,omitempty"` + + // status defines the observed state of the resource. + // +optional + Status EndpointStatus `json:"status,omitempty"` +} + +// +kubebuilder:object:root=true + +// EndpointList contains a list of Endpoint. +type EndpointList struct { + metav1.TypeMeta `json:",inline"` + + // metadata contains the list metadata + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + + // items contains a list of Endpoint. + // +required + Items []Endpoint `json:"items"` +} + +func (l *EndpointList) GetItems() []Endpoint { + return l.Items +} + +func init() { + SchemeBuilder.Register(&Endpoint{}, &EndpointList{}) +} + +func (i *Endpoint) GetCloudCredentialsRef() (*string, *CloudCredentialsReference) { + if i == nil { + return nil, nil + } + + return &i.Namespace, &i.Spec.CloudCredentialsRef +} + +var _ CloudCredentialsRefProvider = &Endpoint{} diff --git a/config/crd/bases/openstack.k-orc.cloud_endpoints.yaml b/config/crd/bases/openstack.k-orc.cloud_endpoints.yaml new file mode 100644 index 000000000..34a49522b --- /dev/null +++ b/config/crd/bases/openstack.k-orc.cloud_endpoints.yaml @@ -0,0 +1,322 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.1 + name: endpoints.openstack.k-orc.cloud +spec: + group: openstack.k-orc.cloud + names: + categories: + - openstack + kind: Endpoint + listKind: EndpointList + plural: endpoints + singular: endpoint + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Resource ID + jsonPath: .status.id + name: ID + type: string + - description: Availability status of resource + jsonPath: .status.conditions[?(@.type=='Available')].status + name: Available + type: string + - description: Message describing current progress status + jsonPath: .status.conditions[?(@.type=='Progressing')].message + name: Message + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: Endpoint is the Schema for an ORC resource. + 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: spec specifies the desired state of the resource. + properties: + cloudCredentialsRef: + description: cloudCredentialsRef points to a secret containing OpenStack + credentials + properties: + cloudName: + description: cloudName specifies the name of the entry in the + clouds.yaml file to use. + maxLength: 256 + minLength: 1 + type: string + secretName: + description: |- + secretName is the name of a secret in the same namespace as the resource being provisioned. + The secret must contain a key named `clouds.yaml` which contains an OpenStack clouds.yaml file. + The secret may optionally contain a key named `cacert` containing a PEM-encoded CA certificate. + maxLength: 253 + minLength: 1 + type: string + required: + - cloudName + - secretName + type: object + import: + description: |- + import refers to an existing OpenStack resource which will be imported instead of + creating a new one. + maxProperties: 1 + minProperties: 1 + properties: + filter: + description: |- + filter contains a resource query which is expected to return a single + result. The controller will continue to retry if filter returns no + results. If filter returns multiple results the controller will set an + error state and will not continue to retry. + minProperties: 1 + properties: + interface: + description: interface of the existing endpoint. + type: string + serviceRef: + description: serviceRef is a reference to which the endpoint + belongs. + maxLength: 253 + minLength: 1 + type: string + url: + description: url is the URL of the existing endpoint. + type: string + type: object + id: + description: |- + id contains the unique identifier of an existing OpenStack resource. Note + that when specifying an import by ID, the resource MUST already exist. + The ORC object will enter an error state if the resource does not exist. + format: uuid + type: string + type: object + managedOptions: + description: managedOptions specifies options which may be applied + to managed objects. + properties: + onDelete: + default: delete + description: |- + onDelete specifies the behaviour of the controller when the ORC + object is deleted. Options are `delete` - delete the OpenStack resource; + `detach` - do not delete the OpenStack resource. If not specified, the + default is `delete`. + enum: + - delete + - detach + type: string + type: object + managementPolicy: + default: managed + description: |- + managementPolicy defines how ORC will treat the object. Valid values are + `managed`: ORC will create, update, and delete the resource; `unmanaged`: + ORC will import an existing resource, and will not apply updates to it or + delete it. + enum: + - managed + - unmanaged + type: string + x-kubernetes-validations: + - message: managementPolicy is immutable + rule: self == oldSelf + resource: + description: |- + resource specifies the desired state of the resource. + + resource may not be specified if the management policy is `unmanaged`. + + resource must be specified if the management policy is `managed`. + properties: + enabled: + default: true + description: enabled indicates whether the endpoint is enabled + or not. + type: boolean + interface: + description: interface indicates the visibility of the endpoint. + enum: + - admin + - internal + - public + type: string + name: + description: |- + name will be the name of the created resource. If not specified, the + name of the ORC object will be used. + maxLength: 255 + minLength: 1 + pattern: ^[^,]+$ + type: string + serviceRef: + description: serviceRef is a reference to the ORC Service which + this resource is associated with. + maxLength: 253 + minLength: 1 + type: string + x-kubernetes-validations: + - message: serviceRef is immutable + rule: self == oldSelf + url: + description: url is the endpoint URL. + type: string + required: + - interface + - serviceRef + - url + type: object + required: + - cloudCredentialsRef + type: object + x-kubernetes-validations: + - message: resource must be specified when policy is managed + rule: 'self.managementPolicy == ''managed'' ? has(self.resource) : true' + - message: import may not be specified when policy is managed + rule: 'self.managementPolicy == ''managed'' ? !has(self.__import__) + : true' + - message: resource may not be specified when policy is unmanaged + rule: 'self.managementPolicy == ''unmanaged'' ? !has(self.resource) + : true' + - message: import must be specified when policy is unmanaged + rule: 'self.managementPolicy == ''unmanaged'' ? has(self.__import__) + : true' + - message: managedOptions may only be provided when policy is managed + rule: 'has(self.managedOptions) ? self.managementPolicy == ''managed'' + : true' + status: + description: status defines the observed state of the resource. + properties: + conditions: + description: |- + conditions represents the observed status of the object. + Known .status.conditions.type are: "Available", "Progressing" + + Available represents the availability of the OpenStack resource. If it is + true then the resource is ready for use. + + Progressing indicates whether the controller is still attempting to + reconcile the current state of the OpenStack resource to the desired + state. Progressing will be False either because the desired state has + been achieved, or because some terminal error prevents it from ever being + achieved and the controller is no longer attempting to reconcile. If + Progressing is True, an observer waiting on the resource should continue + to wait. + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + 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 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 32 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: id is the unique identifier of the OpenStack resource. + type: string + resource: + description: resource contains the observed state of the OpenStack + resource. + properties: + enabled: + description: enabled indicates whether the endpoint is enabled + or not. + type: boolean + interface: + description: interface indicates the visibility of the endpoint. + enum: + - admin + - internal + - public + type: string + name: + description: name is a Human-readable name for the resource. Might + not be unique. + maxLength: 1024 + type: string + serviceID: + description: serviceID is the ID of the Service to which the resource + is associated. + maxLength: 1024 + type: string + url: + description: url is the endpoint URL. + type: string + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/samples/openstack_v1alpha1_endpoint.yaml b/config/samples/openstack_v1alpha1_endpoint.yaml new file mode 100644 index 000000000..a45971790 --- /dev/null +++ b/config/samples/openstack_v1alpha1_endpoint.yaml @@ -0,0 +1,14 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-sample +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + resource: + description: Sample Endpoint + # TODO(scaffolding): Add all fields the resource supports diff --git a/internal/controllers/endpoint/actuator.go b/internal/controllers/endpoint/actuator.go new file mode 100644 index 000000000..7416577a2 --- /dev/null +++ b/internal/controllers/endpoint/actuator.go @@ -0,0 +1,283 @@ +/* +Copyright 2025 The ORC 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 endpoint + +import ( + "context" + "iter" + + "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/utils/ptr" + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + + orcv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" + "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/interfaces" + "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress" + "github.com/k-orc/openstack-resource-controller/v2/internal/logging" + "github.com/k-orc/openstack-resource-controller/v2/internal/osclients" + orcerrors "github.com/k-orc/openstack-resource-controller/v2/internal/util/errors" +) + +// OpenStack resource types +type ( + osResourceT = endpoints.Endpoint + + createResourceActuator = interfaces.CreateResourceActuator[orcObjectPT, orcObjectT, filterT, osResourceT] + deleteResourceActuator = interfaces.DeleteResourceActuator[orcObjectPT, orcObjectT, osResourceT] + resourceReconciler = interfaces.ResourceReconciler[orcObjectPT, osResourceT] + helperFactory = interfaces.ResourceHelperFactory[orcObjectPT, orcObjectT, resourceSpecT, filterT, osResourceT] +) + +type endpointActuator struct { + osClient osclients.EndpointClient + k8sClient client.Client +} + +var _ createResourceActuator = endpointActuator{} +var _ deleteResourceActuator = endpointActuator{} + +func (endpointActuator) GetResourceID(osResource *osResourceT) string { + return osResource.ID +} + +func (actuator endpointActuator) GetOSResourceByID(ctx context.Context, id string) (*osResourceT, progress.ReconcileStatus) { + resource, err := actuator.osClient.GetEndpoint(ctx, id) + if err != nil { + return nil, progress.WrapError(err) + } + return resource, nil +} + +func (actuator endpointActuator) ListOSResourcesForAdoption(ctx context.Context, orcObject orcObjectPT) (iter.Seq2[*osResourceT, error], bool) { + resourceSpec := orcObject.Spec.Resource + if resourceSpec == nil { + return nil, false + } + + // TODO(scaffolding) If you need to filter resources on fields that the List() function + // of gophercloud does not support, it's possible to perform client-side filtering. + // Check osclients.ResourceFilter + + listOpts := endpoints.ListOpts{ + Name: getResourceName(orcObject), + Description: ptr.Deref(resourceSpec.Description, ""), + } + + return actuator.osClient.ListEndpoints(ctx, listOpts), true +} + +func (actuator endpointActuator) ListOSResourcesForImport(ctx context.Context, obj orcObjectPT, filter filterT) (iter.Seq2[*osResourceT, error], progress.ReconcileStatus) { + // TODO(scaffolding) If you need to filter resources on fields that the List() function + // of gophercloud does not support, it's possible to perform client-side filtering. + // Check osclients.ResourceFilter + var reconcileStatus progress.ReconcileStatus + + service := &orcv1alpha1.Service{} + if filter.ServiceRef != nil { + serviceKey := client.ObjectKey{Name: string(*filter.ServiceRef), Namespace: obj.Namespace} + if err := actuator.k8sClient.Get(ctx, serviceKey, service); err != nil { + if apierrors.IsNotFound(err) { + reconcileStatus = reconcileStatus.WithReconcileStatus( + progress.WaitingOnObject("Service", serviceKey.Name, progress.WaitingOnCreation)) + } else { + reconcileStatus = reconcileStatus.WithReconcileStatus( + progress.WrapError(fmt.Errorf("fetching service %s: %w", serviceKey.Name, err))) + } + } else { + if !orcv1alpha1.IsAvailable(service) || service.Status.ID == nil { + reconcileStatus = reconcileStatus.WithReconcileStatus( + progress.WaitingOnObject("Service", serviceKey.Name, progress.WaitingOnReady)) + } + } + } + + if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { + return nil, reconcileStatus + } + + listOpts := endpoints.ListOpts{ + Name: string(ptr.Deref(filter.Name, "")), + Description: string(ptr.Deref(filter.Description, "")), + Service: ptr.Deref(service.Status.ID, ""), + // TODO(scaffolding): Add more import filters + } + + return actuator.osClient.ListEndpoints(ctx, listOpts), nil +} + +func (actuator endpointActuator) CreateResource(ctx context.Context, obj orcObjectPT) (*osResourceT, progress.ReconcileStatus) { + resource := obj.Spec.Resource + + if resource == nil { + // Should have been caught by API validation + return nil, progress.WrapError( + orcerrors.Terminal(orcv1alpha1.ConditionReasonInvalidConfiguration, "Creation requested, but spec.resource is not set")) + } + var reconcileStatus progress.ReconcileStatus + + var serviceID string + service, serviceDepRS := serviceDependency.GetDependency( + ctx, actuator.k8sClient, obj, func(dep *orcv1alpha1.Service) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(serviceDepRS) + if service != nil { + serviceID = ptr.Deref(service.Status.ID, "") + } + if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { + return nil, reconcileStatus + } + createOpts := endpoints.CreateOpts{ + Name: getResourceName(obj), + Description: ptr.Deref(resource.Description, ""), + ServiceID: serviceID, + // TODO(scaffolding): Add more fields + } + + osResource, err := actuator.osClient.CreateEndpoint(ctx, createOpts) + if err != nil { + // We should require the spec to be updated before retrying a create which returned a conflict + if !orcerrors.IsRetryable(err) { + err = orcerrors.Terminal(orcv1alpha1.ConditionReasonInvalidConfiguration, "invalid configuration creating resource: "+err.Error(), err) + } + return nil, progress.WrapError(err) + } + + return osResource, nil +} + +func (actuator endpointActuator) DeleteResource(ctx context.Context, _ orcObjectPT, resource *osResourceT) progress.ReconcileStatus { + return progress.WrapError(actuator.osClient.DeleteEndpoint(ctx, resource.ID)) +} + +func (actuator endpointActuator) updateResource(ctx context.Context, obj orcObjectPT, osResource *osResourceT) progress.ReconcileStatus { + log := ctrl.LoggerFrom(ctx) + resource := obj.Spec.Resource + if resource == nil { + // Should have been caught by API validation + return progress.WrapError( + orcerrors.Terminal(orcv1alpha1.ConditionReasonInvalidConfiguration, "Update requested, but spec.resource is not set")) + } + + updateOpts := endpoints.UpdateOpts{} + + handleNameUpdate(&updateOpts, obj, osResource) + handleDescriptionUpdate(&updateOpts, resource, osResource) + + // TODO(scaffolding): add handler for all fields supporting mutability + + needsUpdate, err := needsUpdate(updateOpts) + if err != nil { + return progress.WrapError( + orcerrors.Terminal(orcv1alpha1.ConditionReasonInvalidConfiguration, "invalid configuration updating resource: "+err.Error(), err)) + } + if !needsUpdate { + log.V(logging.Debug).Info("No changes") + return nil + } + + _, err = actuator.osClient.UpdateEndpoint(ctx, osResource.ID, updateOpts) + + // We should require the spec to be updated before retrying an update which returned a conflict + if orcerrors.IsConflict(err) { + err = orcerrors.Terminal(orcv1alpha1.ConditionReasonInvalidConfiguration, "invalid configuration updating resource: "+err.Error(), err) + } + + if err != nil { + return progress.WrapError(err) + } + + return progress.NeedsRefresh() +} + +func needsUpdate(updateOpts endpoints.UpdateOpts) (bool, error) { + updateOptsMap, err := updateOpts.ToEndpointUpdateMap() + if err != nil { + return false, err + } + + updateMap, ok := updateOptsMap["endpoint"].(map[string]any) + if !ok { + updateMap = make(map[string]any) + } + + return len(updateMap) > 0, nil +} + +func handleNameUpdate(updateOpts *endpoints.UpdateOpts, obj orcObjectPT, osResource *osResourceT) { + name := getResourceName(obj) + if osResource.Name != name { + updateOpts.Name = &name + } +} + +func handleDescriptionUpdate(updateOpts *endpoints.UpdateOpts, resource *resourceSpecT, osResource *osResourceT) { + description := ptr.Deref(resource.Description, "") + if osResource.Description != description { + updateOpts.Description = &description + } +} + +func (actuator endpointActuator) GetResourceReconcilers(ctx context.Context, orcObject orcObjectPT, osResource *osResourceT, controller interfaces.ResourceController) ([]resourceReconciler, progress.ReconcileStatus) { + return []resourceReconciler{ + actuator.updateResource, + }, nil +} + +type endpointHelperFactory struct{} + +var _ helperFactory = endpointHelperFactory{} + +func newActuator(ctx context.Context, orcObject *orcv1alpha1.Endpoint, controller interfaces.ResourceController) (endpointActuator, progress.ReconcileStatus) { + log := ctrl.LoggerFrom(ctx) + + // Ensure credential secrets exist and have our finalizer + _, reconcileStatus := credentialsDependency.GetDependencies(ctx, controller.GetK8sClient(), orcObject, func(*corev1.Secret) bool { return true }) + if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { + return endpointActuator{}, reconcileStatus + } + + clientScope, err := controller.GetScopeFactory().NewClientScopeFromObject(ctx, controller.GetK8sClient(), log, orcObject) + if err != nil { + return endpointActuator{}, progress.WrapError(err) + } + osClient, err := clientScope.NewEndpointClient() + if err != nil { + return endpointActuator{}, progress.WrapError(err) + } + + return endpointActuator{ + osClient: osClient, + k8sClient: controller.GetK8sClient(), + }, nil +} + +func (endpointHelperFactory) NewAPIObjectAdapter(obj orcObjectPT) adapterI { + return endpointAdapter{obj} +} + +func (endpointHelperFactory) NewCreateActuator(ctx context.Context, orcObject orcObjectPT, controller interfaces.ResourceController) (createResourceActuator, progress.ReconcileStatus) { + return newActuator(ctx, orcObject, controller) +} + +func (endpointHelperFactory) NewDeleteActuator(ctx context.Context, orcObject orcObjectPT, controller interfaces.ResourceController) (deleteResourceActuator, progress.ReconcileStatus) { + return newActuator(ctx, orcObject, controller) +} diff --git a/internal/controllers/endpoint/actuator_test.go b/internal/controllers/endpoint/actuator_test.go new file mode 100644 index 000000000..ed7fdce2c --- /dev/null +++ b/internal/controllers/endpoint/actuator_test.go @@ -0,0 +1,119 @@ +/* +Copyright 2025 The ORC 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 endpoint + +import ( + "testing" + + "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints" + orcv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" + "k8s.io/utils/ptr" +) + +func TestNeedsUpdate(t *testing.T) { + testCases := []struct { + name string + updateOpts endpoints.UpdateOpts + expectChange bool + }{ + { + name: "Empty base opts", + updateOpts: endpoints.UpdateOpts{}, + expectChange: false, + }, + { + name: "Updated opts", + updateOpts: endpoints.UpdateOpts{Name: ptr.To("updated")}, + expectChange: true, + }, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + got, _ := needsUpdate(tt.updateOpts) + if got != tt.expectChange { + t.Errorf("Expected change: %v, got: %v", tt.expectChange, got) + } + }) + } +} + +func TestHandleNameUpdate(t *testing.T) { + ptrToName := ptr.To[orcv1alpha1.OpenStackName] + testCases := []struct { + name string + newValue *orcv1alpha1.OpenStackName + existingValue string + expectChange bool + }{ + {name: "Identical", newValue: ptrToName("name"), existingValue: "name", expectChange: false}, + {name: "Different", newValue: ptrToName("new-name"), existingValue: "name", expectChange: true}, + {name: "No value provided, existing is identical to object name", newValue: nil, existingValue: "object-name", expectChange: false}, + {name: "No value provided, existing is different from object name", newValue: nil, existingValue: "different-from-object-name", expectChange: true}, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + resource := &orcv1alpha1.Endpoint{} + resource.Name = "object-name" + resource.Spec = orcv1alpha1.EndpointSpec{ + Resource: &orcv1alpha1.EndpointResourceSpec{Name: tt.newValue}, + } + osResource := &osResourceT{Name: tt.existingValue} + + updateOpts := endpoints.UpdateOpts{} + handleNameUpdate(&updateOpts, resource, osResource) + + got, _ := needsUpdate(updateOpts) + if got != tt.expectChange { + t.Errorf("Expected change: %v, got: %v", tt.expectChange, got) + } + }) + + } +} + +func TestHandleDescriptionUpdate(t *testing.T) { + ptrToDescription := ptr.To[string] + testCases := []struct { + name string + newValue *string + existingValue string + expectChange bool + }{ + {name: "Identical", newValue: ptrToDescription("desc"), existingValue: "desc", expectChange: false}, + {name: "Different", newValue: ptrToDescription("new-desc"), existingValue: "desc", expectChange: true}, + {name: "No value provided, existing is set", newValue: nil, existingValue: "desc", expectChange: true}, + {name: "No value provided, existing is empty", newValue: nil, existingValue: "", expectChange: false}, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + resource := &orcv1alpha1.EndpointResourceSpec{Description: tt.newValue} + osResource := &osResourceT{Description: tt.existingValue} + + updateOpts := endpoints.UpdateOpts{} + handleDescriptionUpdate(&updateOpts, resource, osResource) + + got, _ := needsUpdate(updateOpts) + if got != tt.expectChange { + t.Errorf("Expected change: %v, got: %v", tt.expectChange, got) + } + }) + + } +} diff --git a/internal/controllers/endpoint/controller.go b/internal/controllers/endpoint/controller.go new file mode 100644 index 000000000..5f4a3a342 --- /dev/null +++ b/internal/controllers/endpoint/controller.go @@ -0,0 +1,114 @@ +/* +Copyright 2025 The ORC 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 endpoint + +import ( + "context" + "errors" + + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/builder" + "sigs.k8s.io/controller-runtime/pkg/controller" + + orcv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" + + "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/interfaces" + "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/reconciler" + "github.com/k-orc/openstack-resource-controller/v2/internal/scope" + "github.com/k-orc/openstack-resource-controller/v2/internal/util/credentials" + "github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency" + "github.com/k-orc/openstack-resource-controller/v2/pkg/predicates" +) + +const controllerName = "endpoint" + +// +kubebuilder:rbac:groups=openstack.k-orc.cloud,resources=endpoints,verbs=get;list;watch;create;update;patch;delete +// +kubebuilder:rbac:groups=openstack.k-orc.cloud,resources=endpoints/status,verbs=get;update;patch + +type endpointReconcilerConstructor struct { + scopeFactory scope.Factory +} + +func New(scopeFactory scope.Factory) interfaces.Controller { + return endpointReconcilerConstructor{scopeFactory: scopeFactory} +} + +func (endpointReconcilerConstructor) GetName() string { + return controllerName +} + +var serviceDependency = dependency.NewDeletionGuardDependency[*orcv1alpha1.EndpointList, *orcv1alpha1.Service]( + "spec.resource.serviceRef", + func(endpoint *orcv1alpha1.Endpoint) []string { + resource := endpoint.Spec.Resource + if resource == nil { + return nil + } + return []string{string(resource.ServiceRef)} + }, + finalizer, externalObjectFieldOwner, +) + +var serviceImportDependency = dependency.NewDependency[*orcv1alpha1.EndpointList, *orcv1alpha1.Service]( + "spec.import.filter.serviceRef", + func(endpoint *orcv1alpha1.Endpoint) []string { + resource := endpoint.Spec.Import + if resource == nil || resource.Filter == nil || resource.Filter.ServiceRef == nil { + return nil + } + return []string{string(*resource.Filter.ServiceRef)} + }, +) + +// SetupWithManager sets up the controller with the Manager. +func (c endpointReconcilerConstructor) SetupWithManager(ctx context.Context, mgr ctrl.Manager, options controller.Options) error { + log := ctrl.LoggerFrom(ctx) + k8sClient := mgr.GetClient() + + serviceWatchEventHandler, err := serviceDependency.WatchEventHandler(log, k8sClient) + if err != nil { + return err + } + + serviceImportWatchEventHandler, err := serviceImportDependency.WatchEventHandler(log, k8sClient) + if err != nil { + return err + } + + builder := ctrl.NewControllerManagedBy(mgr). + WithOptions(options). + Watches(&orcv1alpha1.Service{}, serviceWatchEventHandler, + builder.WithPredicates(predicates.NewBecameAvailable(log, &orcv1alpha1.Service{})), + ). + // A second watch is necessary because we need a different handler that omits deletion guards + Watches(&orcv1alpha1.Service{}, serviceImportWatchEventHandler, + builder.WithPredicates(predicates.NewBecameAvailable(log, &orcv1alpha1.Service{})), + ). + For(&orcv1alpha1.Endpoint{}) + + if err := errors.Join( + serviceDependency.AddToManager(ctx, mgr), + serviceImportDependency.AddToManager(ctx, mgr), + credentialsDependency.AddToManager(ctx, mgr), + credentials.AddCredentialsWatch(log, mgr.GetClient(), builder, credentialsDependency), + ); err != nil { + return err + } + + r := reconciler.NewController(controllerName, mgr.GetClient(), c.scopeFactory, endpointHelperFactory{}, endpointStatusWriter{}) + return builder.Complete(&r) +} diff --git a/internal/controllers/endpoint/status.go b/internal/controllers/endpoint/status.go new file mode 100644 index 000000000..e4e4a104f --- /dev/null +++ b/internal/controllers/endpoint/status.go @@ -0,0 +1,64 @@ +/* +Copyright 2025 The ORC 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 endpoint + +import ( + "github.com/go-logr/logr" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + orcv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" + "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/interfaces" + "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress" + orcapplyconfigv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/pkg/clients/applyconfiguration/api/v1alpha1" +) + +type endpointStatusWriter struct{} + +type objectApplyT = orcapplyconfigv1alpha1.EndpointApplyConfiguration +type statusApplyT = orcapplyconfigv1alpha1.EndpointStatusApplyConfiguration + +var _ interfaces.ResourceStatusWriter[*orcv1alpha1.Endpoint, *osResourceT, *objectApplyT, *statusApplyT] = endpointStatusWriter{} + +func (endpointStatusWriter) GetApplyConfig(name, namespace string) *objectApplyT { + return orcapplyconfigv1alpha1.Endpoint(name, namespace) +} + +func (endpointStatusWriter) ResourceAvailableStatus(orcObject *orcv1alpha1.Endpoint, osResource *osResourceT) (metav1.ConditionStatus, progress.ReconcileStatus) { + if osResource == nil { + if orcObject.Status.ID == nil { + return metav1.ConditionFalse, nil + } else { + return metav1.ConditionUnknown, nil + } + } + return metav1.ConditionTrue, nil +} + +func (endpointStatusWriter) ApplyResourceStatus(log logr.Logger, osResource *osResourceT, statusApply *statusApplyT) { + resourceStatus := orcapplyconfigv1alpha1.EndpointResourceStatus(). + WithServiceID(osResource.ServiceID). + WithName(osResource.Name) + + // TODO(scaffolding): add all of the fields supported in the EndpointResourceStatus struct + // If a zero-value isn't expected in the response, place it behind a conditional + + if osResource.Description != "" { + resourceStatus.WithDescription(osResource.Description) + } + + statusApply.WithResource(resourceStatus) +} diff --git a/internal/controllers/endpoint/tests/endpoint-create-full/00-assert.yaml b/internal/controllers/endpoint/tests/endpoint-create-full/00-assert.yaml new file mode 100644 index 000000000..881c9a9f4 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-create-full/00-assert.yaml @@ -0,0 +1,33 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-create-full +status: + resource: + name: endpoint-create-full-override + description: Endpoint from "create full" test + # TODO(scaffolding): Add all fields the resource supports + conditions: + - type: Available + status: "True" + reason: Success + - type: Progressing + status: "False" + reason: Success +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +resourceRefs: + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Endpoint + name: endpoint-create-full + ref: endpoint + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Service + name: endpoint-create-full + ref: service +assertAll: + - celExpr: "endpoint.status.id != ''" + - celExpr: "endpoint.status.resource.serviceID == service.status.id" + # TODO(scaffolding): Add more checks diff --git a/internal/controllers/endpoint/tests/endpoint-create-full/00-create-resource.yaml b/internal/controllers/endpoint/tests/endpoint-create-full/00-create-resource.yaml new file mode 100644 index 000000000..ee7772a11 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-create-full/00-create-resource.yaml @@ -0,0 +1,29 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Service +metadata: + name: endpoint-create-full +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + # TODO(scaffolding): Add the necessary fields to create the resource + resource: {} +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-create-full +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + resource: + name: endpoint-create-full-override + description: Endpoint from "create full" test + serviceRef: endpoint-create-full + # TODO(scaffolding): Add all fields the resource supports diff --git a/internal/controllers/endpoint/tests/endpoint-create-full/00-secret.yaml b/internal/controllers/endpoint/tests/endpoint-create-full/00-secret.yaml new file mode 100644 index 000000000..045711ee7 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-create-full/00-secret.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl create secret generic openstack-clouds --from-file=clouds.yaml=${E2E_KUTTL_OSCLOUDS} ${E2E_KUTTL_CACERT_OPT} + namespaced: true diff --git a/internal/controllers/endpoint/tests/endpoint-create-full/README.md b/internal/controllers/endpoint/tests/endpoint-create-full/README.md new file mode 100644 index 000000000..d625e7b61 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-create-full/README.md @@ -0,0 +1,11 @@ +# Create a Endpoint with all the options + +## Step 00 + +Create a Endpoint using all available fields, and verify that the observed state corresponds to the spec. + +Also validate that the OpenStack resource uses the name from the spec when it is specified. + +## Reference + +https://k-orc.cloud/development/writing-tests/#create-full diff --git a/internal/controllers/endpoint/tests/endpoint-create-minimal/00-assert.yaml b/internal/controllers/endpoint/tests/endpoint-create-minimal/00-assert.yaml new file mode 100644 index 000000000..76d25598b --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-create-minimal/00-assert.yaml @@ -0,0 +1,32 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-create-minimal +status: + resource: + name: endpoint-create-minimal + # TODO(scaffolding): Add all fields the resource supports + conditions: + - type: Available + status: "True" + reason: Success + - type: Progressing + status: "False" + reason: Success +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +resourceRefs: + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Endpoint + name: endpoint-create-minimal + ref: endpoint + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Service + name: endpoint-create-minimal + ref: service +assertAll: + - celExpr: "endpoint.status.id != ''" + - celExpr: "endpoint.status.resource.serviceID == service.status.id" + # TODO(scaffolding): Add more checks diff --git a/internal/controllers/endpoint/tests/endpoint-create-minimal/00-create-resource.yaml b/internal/controllers/endpoint/tests/endpoint-create-minimal/00-create-resource.yaml new file mode 100644 index 000000000..9087fb49d --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-create-minimal/00-create-resource.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Service +metadata: + name: endpoint-create-minimal +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + # TODO(scaffolding): Add the necessary fields to create the resource + resource: {} +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-create-minimal +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + # TODO(scaffolding): Only add the mandatory fields. It's possible the resource + # doesn't have mandatory fields, in that case, leave it empty. + resource: + serviceRef: endpoint-create-full diff --git a/internal/controllers/endpoint/tests/endpoint-create-minimal/00-secret.yaml b/internal/controllers/endpoint/tests/endpoint-create-minimal/00-secret.yaml new file mode 100644 index 000000000..045711ee7 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-create-minimal/00-secret.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl create secret generic openstack-clouds --from-file=clouds.yaml=${E2E_KUTTL_OSCLOUDS} ${E2E_KUTTL_CACERT_OPT} + namespaced: true diff --git a/internal/controllers/endpoint/tests/endpoint-create-minimal/01-assert.yaml b/internal/controllers/endpoint/tests/endpoint-create-minimal/01-assert.yaml new file mode 100644 index 000000000..e724dcbaa --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-create-minimal/01-assert.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +resourceRefs: + - apiVersion: v1 + kind: Secret + name: openstack-clouds + ref: secret +assertAll: + - celExpr: "secret.metadata.deletionTimestamp != 0" + - celExpr: "'openstack.k-orc.cloud/endpoint' in secret.metadata.finalizers" diff --git a/internal/controllers/endpoint/tests/endpoint-create-minimal/01-delete-secret.yaml b/internal/controllers/endpoint/tests/endpoint-create-minimal/01-delete-secret.yaml new file mode 100644 index 000000000..1620791b9 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-create-minimal/01-delete-secret.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + # We expect the deletion to hang due to the finalizer, so use --wait=false + - command: kubectl delete secret openstack-clouds --wait=false + namespaced: true diff --git a/internal/controllers/endpoint/tests/endpoint-create-minimal/README.md b/internal/controllers/endpoint/tests/endpoint-create-minimal/README.md new file mode 100644 index 000000000..b9644e32d --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-create-minimal/README.md @@ -0,0 +1,15 @@ +# Create a Endpoint with the minimum options + +## Step 00 + +Create a minimal Endpoint, that sets only the required fields, and verify that the observed state corresponds to the spec. + +Also validate that the OpenStack resource uses the name of the ORC object when it is not specified. + +## Step 01 + +Try deleting the secret and ensure that it is not deleted thanks to the finalizer. + +## Reference + +https://k-orc.cloud/development/writing-tests/#create-minimal diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/00-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/00-assert.yaml new file mode 100644 index 000000000..17743d6e9 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/00-assert.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-dependency +status: + conditions: + - type: Available + message: |- + Waiting for Service/endpoint-import-dependency to be ready + status: "False" + reason: Progressing + - type: Progressing + message: |- + Waiting for Service/endpoint-import-dependency to be ready + status: "True" + reason: Progressing diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/00-import-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/00-import-resource.yaml new file mode 100644 index 000000000..6a5c8737b --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/00-import-resource.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Service +metadata: + name: endpoint-import-dependency +spec: + cloudCredentialsRef: + cloudName: openstack + secretName: openstack-clouds + managementPolicy: unmanaged + import: + filter: + name: endpoint-import-dependency-external +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-dependency +spec: + cloudCredentialsRef: + cloudName: openstack + secretName: openstack-clouds + managementPolicy: unmanaged + import: + filter: + serviceRef: endpoint-import-dependency diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/00-secret.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/00-secret.yaml new file mode 100644 index 000000000..045711ee7 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/00-secret.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl create secret generic openstack-clouds --from-file=clouds.yaml=${E2E_KUTTL_OSCLOUDS} ${E2E_KUTTL_CACERT_OPT} + namespaced: true diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/01-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/01-assert.yaml new file mode 100644 index 000000000..438dd019a --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/01-assert.yaml @@ -0,0 +1,32 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-dependency-not-this-one +status: + conditions: + - type: Available + message: OpenStack resource is available + status: "True" + reason: Success + - type: Progressing + message: OpenStack resource is up to date + status: "False" + reason: Success +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-dependency +status: + conditions: + - type: Available + message: |- + Waiting for Service/endpoint-import-dependency to be ready + status: "False" + reason: Progressing + - type: Progressing + message: |- + Waiting for Service/endpoint-import-dependency to be ready + status: "True" + reason: Progressing diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/01-create-trap-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/01-create-trap-resource.yaml new file mode 100644 index 000000000..01f5e92f2 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/01-create-trap-resource.yaml @@ -0,0 +1,42 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Service +metadata: + name: endpoint-import-dependency-not-this-one +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + # TODO(scaffolding): Add the necessary fields to create the resource + resource: {} +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Service +metadata: + name: endpoint-import-dependency-not-this-one +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + # TODO(scaffolding): Add the necessary fields to create the resource + resource: {} +--- +# This `endpoint-import-dependency-not-this-one` should not be picked by the import filter +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-dependency-not-this-one +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + resource: + serviceRef: endpoint-import-dependency-not-this-one + serviceRef: endpoint-import-dependency-not-this-one + # TODO(scaffolding): Add the necessary fields to create the resource diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/02-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/02-assert.yaml new file mode 100644 index 000000000..76b42d4b6 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/02-assert.yaml @@ -0,0 +1,34 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +resourceRefs: + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Endpoint + name: endpoint-import-dependency + ref: endpoint1 + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Endpoint + name: endpoint-import-dependency-not-this-one + ref: endpoint2 + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Service + name: endpoint-import-dependency + ref: service +assertAll: + - celExpr: "endpoint1.status.id != endpoint2.status.id" + - celExpr: "endpoint1.status.resource.serviceID == service.status.id" +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-dependency +status: + conditions: + - type: Available + message: OpenStack resource is available + status: "True" + reason: Success + - type: Progressing + message: OpenStack resource is up to date + status: "False" + reason: Success diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/02-create-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/02-create-resource.yaml new file mode 100644 index 000000000..80e8511a5 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/02-create-resource.yaml @@ -0,0 +1,41 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Service +metadata: + name: endpoint-import-dependency-external +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + # TODO(scaffolding): Add the necessary fields to create the resource + resource: {} +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Service +metadata: + name: endpoint-import-dependency-external +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + # TODO(scaffolding): Add the necessary fields to create the resource + resource: {} +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-dependency-external +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack-admin + secretName: openstack-clouds + managementPolicy: managed + resource: + serviceRef: endpoint-import-dependency-external + serviceRef: endpoint-import-dependency-external + # TODO(scaffolding): Add the necessary fields to create the resource diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/03-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/03-assert.yaml new file mode 100644 index 000000000..dad9764bb --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/03-assert.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +commands: +- script: "! kubectl get service endpoint-import-dependency --namespace $NAMESPACE" + skipLogOutput: true diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/03-delete-import-dependencies.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/03-delete-import-dependencies.yaml new file mode 100644 index 000000000..744da0717 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/03-delete-import-dependencies.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + # We should be able to delete the import dependencies + - command: kubectl delete service endpoint-import-dependency + namespaced: true diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/04-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/04-assert.yaml new file mode 100644 index 000000000..4155ea163 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/04-assert.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +commands: +- script: "! kubectl get endpoint endpoint-import-dependency --namespace $NAMESPACE" + skipLogOutput: true diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/04-delete-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/04-delete-resource.yaml new file mode 100644 index 000000000..56a973e5b --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/04-delete-resource.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +delete: + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Endpoint + name: endpoint-import-dependency diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/README.md b/internal/controllers/endpoint/tests/endpoint-import-dependency/README.md new file mode 100644 index 000000000..934ab20fe --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/README.md @@ -0,0 +1,29 @@ +# Check dependency handling for imported Endpoint + +## Step 00 + +Import a Endpoint that references other imported resources. The referenced imported resources have no matching resources yet. +Verify the Endpoint is waiting for the dependency to be ready. + +## Step 01 + +Create a Endpoint matching the import filter, except for referenced resources, and verify that it's not being imported. + +## Step 02 + +Create the referenced resources and a Endpoint matching the import filters. + +Verify that the observed status on the imported Endpoint corresponds to the spec of the created Endpoint. + +## Step 03 + +Delete the referenced resources and check that ORC does not prevent deletion. The OpenStack resources still exist because they +were imported resources and we only deleted the ORC representation of it. + +## Step 04 + +Delete the Endpoint and validate that all resources are gone. + +## Reference + +https://k-orc.cloud/development/writing-tests/#import-dependency diff --git a/internal/controllers/endpoint/tests/endpoint-import-error/00-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import-error/00-assert.yaml new file mode 100644 index 000000000..06992d40e --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-error/00-assert.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-error-external-1 +status: + conditions: + - type: Available + message: OpenStack resource is available + status: "True" + reason: Success + - type: Progressing + message: OpenStack resource is up to date + status: "False" + reason: Success +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-error-external-2 +status: + conditions: + - type: Available + message: OpenStack resource is available + status: "True" + reason: Success + - type: Progressing + message: OpenStack resource is up to date + status: "False" + reason: Success diff --git a/internal/controllers/endpoint/tests/endpoint-import-error/00-create-resources.yaml b/internal/controllers/endpoint/tests/endpoint-import-error/00-create-resources.yaml new file mode 100644 index 000000000..7e68b2f80 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-error/00-create-resources.yaml @@ -0,0 +1,43 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Service +metadata: + name: endpoint-import-error +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + # TODO(scaffolding): Add the necessary fields to create the resource + resource: {} +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-error-external-1 +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + resource: + description: Endpoint from "import error" test + serviceRef: endpoint-import-error + # TODO(scaffolding): add any required field +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-error-external-2 +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + resource: + description: Endpoint from "import error" test + serviceRef: endpoint-import-error + # TODO(scaffolding): add any required field diff --git a/internal/controllers/endpoint/tests/endpoint-import-error/00-secret.yaml b/internal/controllers/endpoint/tests/endpoint-import-error/00-secret.yaml new file mode 100644 index 000000000..045711ee7 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-error/00-secret.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl create secret generic openstack-clouds --from-file=clouds.yaml=${E2E_KUTTL_OSCLOUDS} ${E2E_KUTTL_CACERT_OPT} + namespaced: true diff --git a/internal/controllers/endpoint/tests/endpoint-import-error/01-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import-error/01-assert.yaml new file mode 100644 index 000000000..e9751d908 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-error/01-assert.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-error +status: + conditions: + - type: Available + message: found more than one matching OpenStack resource during import + status: "False" + reason: InvalidConfiguration + - type: Progressing + message: found more than one matching OpenStack resource during import + status: "False" + reason: InvalidConfiguration diff --git a/internal/controllers/endpoint/tests/endpoint-import-error/01-import-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import-error/01-import-resource.yaml new file mode 100644 index 000000000..df0e2d3a9 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-error/01-import-resource.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-error +spec: + cloudCredentialsRef: + cloudName: openstack + secretName: openstack-clouds + managementPolicy: unmanaged + import: + filter: + description: Endpoint from "import error" test diff --git a/internal/controllers/endpoint/tests/endpoint-import-error/README.md b/internal/controllers/endpoint/tests/endpoint-import-error/README.md new file mode 100644 index 000000000..7a8e80bcf --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import-error/README.md @@ -0,0 +1,13 @@ +# Import Endpoint with more than one matching resources + +## Step 00 + +Create two Endpoints with identical specs. + +## Step 01 + +Ensure that an imported Endpoint with a filter matching the resources returns an error. + +## Reference + +https://k-orc.cloud/development/writing-tests/#import-error diff --git a/internal/controllers/endpoint/tests/endpoint-import/00-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import/00-assert.yaml new file mode 100644 index 000000000..cc87b9a8e --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import/00-assert.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import +status: + conditions: + - type: Available + message: Waiting for OpenStack resource to be created externally + status: "False" + reason: Progressing + - type: Progressing + message: Waiting for OpenStack resource to be created externally + status: "True" + reason: Progressing diff --git a/internal/controllers/endpoint/tests/endpoint-import/00-import-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import/00-import-resource.yaml new file mode 100644 index 000000000..cdfda600d --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import/00-import-resource.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import +spec: + cloudCredentialsRef: + cloudName: openstack + secretName: openstack-clouds + managementPolicy: unmanaged + import: + filter: + name: endpoint-import-external + description: Endpoint endpoint-import-external from "endpoint-import" test + # TODO(scaffolding): Add all fields supported by the filter diff --git a/internal/controllers/endpoint/tests/endpoint-import/00-secret.yaml b/internal/controllers/endpoint/tests/endpoint-import/00-secret.yaml new file mode 100644 index 000000000..045711ee7 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import/00-secret.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl create secret generic openstack-clouds --from-file=clouds.yaml=${E2E_KUTTL_OSCLOUDS} ${E2E_KUTTL_CACERT_OPT} + namespaced: true diff --git a/internal/controllers/endpoint/tests/endpoint-import/01-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import/01-assert.yaml new file mode 100644 index 000000000..63a67bdbd --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import/01-assert.yaml @@ -0,0 +1,34 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-external-not-this-one +status: + conditions: + - type: Available + message: OpenStack resource is available + status: "True" + reason: Success + - type: Progressing + message: OpenStack resource is up to date + status: "False" + reason: Success + resource: + name: endpoint-import-external-not-this-one + description: Endpoint endpoint-import-external from "endpoint-import" test + # TODO(scaffolding): Add fields necessary to match filter +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import +status: + conditions: + - type: Available + message: Waiting for OpenStack resource to be created externally + status: "False" + reason: Progressing + - type: Progressing + message: Waiting for OpenStack resource to be created externally + status: "True" + reason: Progressing diff --git a/internal/controllers/endpoint/tests/endpoint-import/01-create-trap-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import/01-create-trap-resource.yaml new file mode 100644 index 000000000..036efd781 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import/01-create-trap-resource.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Service +metadata: + name: endpoint-import-external-not-this-one +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + # TODO(scaffolding): Add the necessary fields to create the resource + resource: {} +--- +# This `endpoint-import-external-not-this-one` resource serves two purposes: +# - ensure that we can successfully create another resource which name is a substring of it (i.e. it's not being adopted) +# - ensure that importing a resource which name is a substring of it will not pick this one. +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-external-not-this-one +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + resource: + description: Endpoint endpoint-import-external from "endpoint-import" test + serviceRef: endpoint-import-external-not-this-one + # TODO(scaffolding): Add fields necessary to match filter diff --git a/internal/controllers/endpoint/tests/endpoint-import/02-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import/02-assert.yaml new file mode 100644 index 000000000..b3c7c0b04 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import/02-assert.yaml @@ -0,0 +1,33 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +resourceRefs: + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Endpoint + name: endpoint-import-external + ref: endpoint1 + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Endpoint + name: endpoint-import-external-not-this-one + ref: endpoint2 +assertAll: + - celExpr: "endpoint1.status.id != endpoint2.status.id" +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import +status: + conditions: + - type: Available + message: OpenStack resource is available + status: "True" + reason: Success + - type: Progressing + message: OpenStack resource is up to date + status: "False" + reason: Success + resource: + name: endpoint-import-external + description: Endpoint endpoint-import-external from "endpoint-import" test + # TODO(scaffolding): Add all fields the resource supports diff --git a/internal/controllers/endpoint/tests/endpoint-import/02-create-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import/02-create-resource.yaml new file mode 100644 index 000000000..5e17eec59 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import/02-create-resource.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Service +metadata: + name: endpoint-import +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + # TODO(scaffolding): Add the necessary fields to create the resource + resource: {} +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-import-external +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + resource: + description: Endpoint endpoint-import-external from "endpoint-import" test + serviceRef: endpoint-import + # TODO(scaffolding): Add fields necessary to match filter diff --git a/internal/controllers/endpoint/tests/endpoint-import/README.md b/internal/controllers/endpoint/tests/endpoint-import/README.md new file mode 100644 index 000000000..5fbb68b9a --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-import/README.md @@ -0,0 +1,18 @@ +# Import Endpoint + +## Step 00 + +Import a endpoint, matching all of the available filter's fields, and verify it is waiting for the external resource to be created. + +## Step 01 + +Create a endpoint which name is a superstring of the one specified in the import filter, and otherwise matching the filter, and verify that it's not being imported. + +## Step 02 + +Create a endpoint matching the filter and verify that the observed status on the imported endpoint corresponds to the spec of the created endpoint. +Also verify that the created endpoint didn't adopt the one which name is a superstring of it. + +## Reference + +https://k-orc.cloud/development/writing-tests/#import diff --git a/internal/controllers/endpoint/tests/endpoint-update/00-assert.yaml b/internal/controllers/endpoint/tests/endpoint-update/00-assert.yaml new file mode 100644 index 000000000..49cc482c0 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-update/00-assert.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +resourceRefs: + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Endpoint + name: endpoint-update + ref: endpoint +assertAll: + - celExpr: "!has(endpoint.status.resource.description)" +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-update +status: + resource: + name: endpoint-update + # TODO(scaffolding): Add matches for more fields + conditions: + - type: Available + status: "True" + reason: Success + - type: Progressing + status: "False" + reason: Success diff --git a/internal/controllers/endpoint/tests/endpoint-update/00-minimal-resource.yaml b/internal/controllers/endpoint/tests/endpoint-update/00-minimal-resource.yaml new file mode 100644 index 000000000..d846d67fb --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-update/00-minimal-resource.yaml @@ -0,0 +1,28 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Service +metadata: + name: endpoint-update +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + # TODO(scaffolding): Add the necessary fields to create the resource + resource: {} +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-update +spec: + cloudCredentialsRef: + # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created or updated + cloudName: openstack + secretName: openstack-clouds + managementPolicy: managed + # TODO(scaffolding): Only add the mandatory fields. It's possible the resource + # doesn't have mandatory fields, in that case, leave it empty. + resource: + serviceRef: endpoint-update diff --git a/internal/controllers/endpoint/tests/endpoint-update/00-prerequisites.yaml b/internal/controllers/endpoint/tests/endpoint-update/00-prerequisites.yaml new file mode 100644 index 000000000..045711ee7 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-update/00-prerequisites.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl create secret generic openstack-clouds --from-file=clouds.yaml=${E2E_KUTTL_OSCLOUDS} ${E2E_KUTTL_CACERT_OPT} + namespaced: true diff --git a/internal/controllers/endpoint/tests/endpoint-update/01-assert.yaml b/internal/controllers/endpoint/tests/endpoint-update/01-assert.yaml new file mode 100644 index 000000000..e526907c7 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-update/01-assert.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-update +status: + resource: + name: endpoint-update-updated + description: endpoint-update-updated + # TODO(scaffolding): match all fields that were modified + conditions: + - type: Available + status: "True" + reason: Success + - type: Progressing + status: "False" + reason: Success diff --git a/internal/controllers/endpoint/tests/endpoint-update/01-updated-resource.yaml b/internal/controllers/endpoint/tests/endpoint-update/01-updated-resource.yaml new file mode 100644 index 000000000..ea78d64af --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-update/01-updated-resource.yaml @@ -0,0 +1,10 @@ +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-update +spec: + resource: + name: endpoint-update-updated + description: endpoint-update-updated + # TODO(scaffolding): update all mutable fields diff --git a/internal/controllers/endpoint/tests/endpoint-update/02-assert.yaml b/internal/controllers/endpoint/tests/endpoint-update/02-assert.yaml new file mode 100644 index 000000000..c3e8f879e --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-update/02-assert.yaml @@ -0,0 +1,26 @@ +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +resourceRefs: + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Endpoint + name: endpoint-update + ref: endpoint +assertAll: + - celExpr: "!has(endpoint.status.resource.description)" +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Endpoint +metadata: + name: endpoint-update +status: + resource: + name: endpoint-update + # TODO(scaffolding): validate that updated fields were all reverted to their original value + conditions: + - type: Available + status: "True" + reason: Success + - type: Progressing + status: "False" + reason: Success diff --git a/internal/controllers/endpoint/tests/endpoint-update/02-reverted-resource.yaml b/internal/controllers/endpoint/tests/endpoint-update/02-reverted-resource.yaml new file mode 100644 index 000000000..2c6c253ff --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-update/02-reverted-resource.yaml @@ -0,0 +1,7 @@ +# NOTE: kuttl only does patch updates, which means we can't delete a field. +# We have to use a kubectl apply command instead. +apiVersion: kuttl.dev/v1beta1 +kind: TestStep +commands: + - command: kubectl replace -f 00-minimal-resource.yaml + namespaced: true diff --git a/internal/controllers/endpoint/tests/endpoint-update/README.md b/internal/controllers/endpoint/tests/endpoint-update/README.md new file mode 100644 index 000000000..3cf396e87 --- /dev/null +++ b/internal/controllers/endpoint/tests/endpoint-update/README.md @@ -0,0 +1,17 @@ +# Update Endpoint + +## Step 00 + +Create a Endpoint using only mandatory fields. + +## Step 01 + +Update all mutable fields. + +## Step 02 + +Revert the resource to its original value and verify the resulting object is similar to when if was first created. + +## Reference + +https://k-orc.cloud/development/writing-tests/#update diff --git a/internal/controllers/endpoint/zz_generated.adapter.go b/internal/controllers/endpoint/zz_generated.adapter.go new file mode 100644 index 000000000..934d9b7da --- /dev/null +++ b/internal/controllers/endpoint/zz_generated.adapter.go @@ -0,0 +1,88 @@ +// Code generated by resource-generator. DO NOT EDIT. +/* +Copyright 2025 The ORC 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 endpoint + +import ( + orcv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" + "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/interfaces" +) + +// Fundamental types +type ( + orcObjectT = orcv1alpha1.Endpoint + orcObjectListT = orcv1alpha1.EndpointList + resourceSpecT = orcv1alpha1.EndpointResourceSpec + filterT = orcv1alpha1.EndpointFilter +) + +// Derived types +type ( + orcObjectPT = *orcObjectT + adapterI = interfaces.APIObjectAdapter[orcObjectPT, resourceSpecT, filterT] + adapterT = endpointAdapter +) + +type endpointAdapter struct { + *orcv1alpha1.Endpoint +} + +var _ adapterI = &adapterT{} + +func (f adapterT) GetObject() orcObjectPT { + return f.Endpoint +} + +func (f adapterT) GetManagementPolicy() orcv1alpha1.ManagementPolicy { + return f.Spec.ManagementPolicy +} + +func (f adapterT) GetManagedOptions() *orcv1alpha1.ManagedOptions { + return f.Spec.ManagedOptions +} + +func (f adapterT) GetStatusID() *string { + return f.Status.ID +} + +func (f adapterT) GetResourceSpec() *resourceSpecT { + return f.Spec.Resource +} + +func (f adapterT) GetImportID() *string { + if f.Spec.Import == nil { + return nil + } + return f.Spec.Import.ID +} + +func (f adapterT) GetImportFilter() *filterT { + if f.Spec.Import == nil { + return nil + } + return f.Spec.Import.Filter +} + +// getResourceName returns the name of the OpenStack resource we should use. +// This method is not implemented as part of APIObjectAdapter as it is intended +// to be used by resource actuators, which don't use the adapter. +func getResourceName(orcObject orcObjectPT) string { + if orcObject.Spec.Resource.Name != nil { + return string(*orcObject.Spec.Resource.Name) + } + return orcObject.Name +} diff --git a/internal/controllers/endpoint/zz_generated.controller.go b/internal/controllers/endpoint/zz_generated.controller.go new file mode 100644 index 000000000..1dd55a109 --- /dev/null +++ b/internal/controllers/endpoint/zz_generated.controller.go @@ -0,0 +1,45 @@ +// Code generated by resource-generator. DO NOT EDIT. +/* +Copyright 2025 The ORC 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 endpoint + +import ( + corev1 "k8s.io/api/core/v1" + + "github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency" + orcstrings "github.com/k-orc/openstack-resource-controller/v2/internal/util/strings" +) + +var ( + // NOTE: controllerName must be defined in any controller using this template + + // finalizer is the string this controller adds to an object's Finalizers + finalizer = orcstrings.GetFinalizerName(controllerName) + + // externalObjectFieldOwner is the field owner we use when using + // server-side-apply on objects we don't control + externalObjectFieldOwner = orcstrings.GetSSAFieldOwner(controllerName) + + credentialsDependency = dependency.NewDeletionGuardDependency[*orcObjectListT, *corev1.Secret]( + "spec.cloudCredentialsRef.secretName", + func(obj orcObjectPT) []string { + return []string{obj.Spec.CloudCredentialsRef.SecretName} + }, + finalizer, externalObjectFieldOwner, + dependency.OverrideDependencyName("credentials"), + ) +) diff --git a/internal/osclients/endpoint.go b/internal/osclients/endpoint.go new file mode 100644 index 000000000..e99555396 --- /dev/null +++ b/internal/osclients/endpoint.go @@ -0,0 +1,104 @@ +/* +Copyright 2025 The ORC 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 osclients + +import ( + "context" + "fmt" + "iter" + + "github.com/gophercloud/gophercloud/v2" + "github.com/gophercloud/gophercloud/v2/openstack" + "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints" + "github.com/gophercloud/utils/v2/openstack/clientconfig" +) + +type EndpointClient interface { + ListEndpoints(ctx context.Context, listOpts endpoints.ListOptsBuilder) iter.Seq2[*endpoints.Endpoint, error] + CreateEndpoint(ctx context.Context, opts endpoints.CreateOptsBuilder) (*endpoints.Endpoint, error) + DeleteEndpoint(ctx context.Context, resourceID string) error + GetEndpoint(ctx context.Context, resourceID string) (*endpoints.Endpoint, error) + UpdateEndpoint(ctx context.Context, id string, opts endpoints.UpdateOptsBuilder) (*endpoints.Endpoint, error) +} + +type endpointClient struct{ client *gophercloud.ServiceClient } + +// NewEndpointClient returns a new OpenStack client. +func NewEndpointClient(providerClient *gophercloud.ProviderClient, providerClientOpts *clientconfig.ClientOpts) (EndpointClient, error) { + client, err := openstack.NewIdentityV3(providerClient, gophercloud.EndpointOpts{ + Region: providerClientOpts.RegionName, + Availability: clientconfig.GetEndpointType(providerClientOpts.EndpointType), + }) + + if err != nil { + return nil, fmt.Errorf("failed to create endpoint service client: %v", err) + } + + return &endpointClient{client}, nil +} + +func (c endpointClient) ListEndpoints(ctx context.Context, listOpts endpoints.ListOptsBuilder) iter.Seq2[*endpoints.Endpoint, error] { + pager := endpoints.List(c.client, listOpts) + return func(yield func(*endpoints.Endpoint, error) bool) { + _ = pager.EachPage(ctx, yieldPage(endpoints.ExtractEndpoints, yield)) + } +} + +func (c endpointClient) CreateEndpoint(ctx context.Context, opts endpoints.CreateOptsBuilder) (*endpoints.Endpoint, error) { + return endpoints.Create(ctx, c.client, opts).Extract() +} + +func (c endpointClient) DeleteEndpoint(ctx context.Context, resourceID string) error { + return endpoints.Delete(ctx, c.client, resourceID).ExtractErr() +} + +func (c endpointClient) GetEndpoint(ctx context.Context, resourceID string) (*endpoints.Endpoint, error) { + return endpoints.Get(ctx, c.client, resourceID).Extract() +} + +func (c endpointClient) UpdateEndpoint(ctx context.Context, id string, opts endpoints.UpdateOptsBuilder) (*endpoints.Endpoint, error) { + return endpoints.Update(ctx, c.client, id, opts).Extract() +} + +type endpointErrorClient struct{ error } + +// NewEndpointErrorClient returns a EndpointClient in which every method returns the given error. +func NewEndpointErrorClient(e error) EndpointClient { + return endpointErrorClient{e} +} + +func (e endpointErrorClient) ListEndpoints(_ context.Context, _ endpoints.ListOptsBuilder) iter.Seq2[*endpoints.Endpoint, error] { + return func(yield func(*endpoints.Endpoint, error) bool) { + yield(nil, e.error) + } +} + +func (e endpointErrorClient) CreateEndpoint(_ context.Context, _ endpoints.CreateOptsBuilder) (*endpoints.Endpoint, error) { + return nil, e.error +} + +func (e endpointErrorClient) DeleteEndpoint(_ context.Context, _ string) error { + return e.error +} + +func (e endpointErrorClient) GetEndpoint(_ context.Context, _ string) (*endpoints.Endpoint, error) { + return nil, e.error +} + +func (e endpointErrorClient) UpdateEndpoint(_ context.Context, _ string, _ endpoints.UpdateOptsBuilder) (*endpoints.Endpoint, error) { + return nil, e.error +} diff --git a/internal/osclients/mock/endpoint.go b/internal/osclients/mock/endpoint.go new file mode 100644 index 000000000..dafc92276 --- /dev/null +++ b/internal/osclients/mock/endpoint.go @@ -0,0 +1,131 @@ +/* +Copyright 2025 The ORC 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. +*/ +// Code generated by MockGen. DO NOT EDIT. +// Source: ../endpoint.go +// +// Generated by this command: +// +// mockgen -package mock -destination=endpoint.go -source=../endpoint.go github.com/k-orc/openstack-resource-controller/internal/osclients/mock EndpointClient +// + +// Package mock is a generated GoMock package. +package mock + +import ( + context "context" + iter "iter" + reflect "reflect" + + endpoints "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints" + gomock "go.uber.org/mock/gomock" +) + +// MockEndpointClient is a mock of EndpointClient interface. +type MockEndpointClient struct { + ctrl *gomock.Controller + recorder *MockEndpointClientMockRecorder + isgomock struct{} +} + +// MockEndpointClientMockRecorder is the mock recorder for MockEndpointClient. +type MockEndpointClientMockRecorder struct { + mock *MockEndpointClient +} + +// NewMockEndpointClient creates a new mock instance. +func NewMockEndpointClient(ctrl *gomock.Controller) *MockEndpointClient { + mock := &MockEndpointClient{ctrl: ctrl} + mock.recorder = &MockEndpointClientMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockEndpointClient) EXPECT() *MockEndpointClientMockRecorder { + return m.recorder +} + +// CreateEndpoint mocks base method. +func (m *MockEndpointClient) CreateEndpoint(ctx context.Context, opts endpoints.CreateOptsBuilder) (*endpoints.Endpoint, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "CreateEndpoint", ctx, opts) + ret0, _ := ret[0].(*endpoints.Endpoint) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// CreateEndpoint indicates an expected call of CreateEndpoint. +func (mr *MockEndpointClientMockRecorder) CreateEndpoint(ctx, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateEndpoint", reflect.TypeOf((*MockEndpointClient)(nil).CreateEndpoint), ctx, opts) +} + +// DeleteEndpoint mocks base method. +func (m *MockEndpointClient) DeleteEndpoint(ctx context.Context, resourceID string) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteEndpoint", ctx, resourceID) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteEndpoint indicates an expected call of DeleteEndpoint. +func (mr *MockEndpointClientMockRecorder) DeleteEndpoint(ctx, resourceID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteEndpoint", reflect.TypeOf((*MockEndpointClient)(nil).DeleteEndpoint), ctx, resourceID) +} + +// GetEndpoint mocks base method. +func (m *MockEndpointClient) GetEndpoint(ctx context.Context, resourceID string) (*endpoints.Endpoint, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetEndpoint", ctx, resourceID) + ret0, _ := ret[0].(*endpoints.Endpoint) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetEndpoint indicates an expected call of GetEndpoint. +func (mr *MockEndpointClientMockRecorder) GetEndpoint(ctx, resourceID any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetEndpoint", reflect.TypeOf((*MockEndpointClient)(nil).GetEndpoint), ctx, resourceID) +} + +// ListEndpoints mocks base method. +func (m *MockEndpointClient) ListEndpoints(ctx context.Context, listOpts endpoints.ListOptsBuilder) iter.Seq2[*endpoints.Endpoint, error] { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ListEndpoints", ctx, listOpts) + ret0, _ := ret[0].(iter.Seq2[*endpoints.Endpoint, error]) + return ret0 +} + +// ListEndpoints indicates an expected call of ListEndpoints. +func (mr *MockEndpointClientMockRecorder) ListEndpoints(ctx, listOpts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ListEndpoints", reflect.TypeOf((*MockEndpointClient)(nil).ListEndpoints), ctx, listOpts) +} + +// UpdateEndpoint mocks base method. +func (m *MockEndpointClient) UpdateEndpoint(ctx context.Context, id string, opts endpoints.UpdateOptsBuilder) (*endpoints.Endpoint, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "UpdateEndpoint", ctx, id, opts) + ret0, _ := ret[0].(*endpoints.Endpoint) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// UpdateEndpoint indicates an expected call of UpdateEndpoint. +func (mr *MockEndpointClientMockRecorder) UpdateEndpoint(ctx, id, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateEndpoint", reflect.TypeOf((*MockEndpointClient)(nil).UpdateEndpoint), ctx, id, opts) +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpoint.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpoint.go new file mode 100644 index 000000000..a099f728f --- /dev/null +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpoint.go @@ -0,0 +1,281 @@ +/* +Copyright 2025 The ORC 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + apiv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" + internal "github.com/k-orc/openstack-resource-controller/v2/pkg/clients/applyconfiguration/internal" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + managedfields "k8s.io/apimachinery/pkg/util/managedfields" + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// EndpointApplyConfiguration represents a declarative configuration of the Endpoint type for use +// with apply. +type EndpointApplyConfiguration struct { + v1.TypeMetaApplyConfiguration `json:",inline"` + *v1.ObjectMetaApplyConfiguration `json:"metadata,omitempty"` + Spec *EndpointSpecApplyConfiguration `json:"spec,omitempty"` + Status *EndpointStatusApplyConfiguration `json:"status,omitempty"` +} + +// Endpoint constructs a declarative configuration of the Endpoint type for use with +// apply. +func Endpoint(name, namespace string) *EndpointApplyConfiguration { + b := &EndpointApplyConfiguration{} + b.WithName(name) + b.WithNamespace(namespace) + b.WithKind("Endpoint") + b.WithAPIVersion("openstack.k-orc.cloud/v1alpha1") + return b +} + +// ExtractEndpoint extracts the applied configuration owned by fieldManager from +// endpoint. If no managedFields are found in endpoint for fieldManager, a +// EndpointApplyConfiguration is returned with only the Name, Namespace (if applicable), +// APIVersion and Kind populated. It is possible that no managed fields were found for because other +// field managers have taken ownership of all the fields previously owned by fieldManager, or because +// the fieldManager never owned fields any fields. +// endpoint must be a unmodified Endpoint API object that was retrieved from the Kubernetes API. +// ExtractEndpoint provides a way to perform a extract/modify-in-place/apply workflow. +// Note that an extracted apply configuration will contain fewer fields than what the fieldManager previously +// applied if another fieldManager has updated or force applied any of the previously applied fields. +// Experimental! +func ExtractEndpoint(endpoint *apiv1alpha1.Endpoint, fieldManager string) (*EndpointApplyConfiguration, error) { + return extractEndpoint(endpoint, fieldManager, "") +} + +// ExtractEndpointStatus is the same as ExtractEndpoint except +// that it extracts the status subresource applied configuration. +// Experimental! +func ExtractEndpointStatus(endpoint *apiv1alpha1.Endpoint, fieldManager string) (*EndpointApplyConfiguration, error) { + return extractEndpoint(endpoint, fieldManager, "status") +} + +func extractEndpoint(endpoint *apiv1alpha1.Endpoint, fieldManager string, subresource string) (*EndpointApplyConfiguration, error) { + b := &EndpointApplyConfiguration{} + err := managedfields.ExtractInto(endpoint, internal.Parser().Type("com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.Endpoint"), fieldManager, b, subresource) + if err != nil { + return nil, err + } + b.WithName(endpoint.Name) + b.WithNamespace(endpoint.Namespace) + + b.WithKind("Endpoint") + b.WithAPIVersion("openstack.k-orc.cloud/v1alpha1") + return b, nil +} +func (b EndpointApplyConfiguration) IsApplyConfiguration() {} + +// WithKind sets the Kind field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Kind field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithKind(value string) *EndpointApplyConfiguration { + b.TypeMetaApplyConfiguration.Kind = &value + return b +} + +// WithAPIVersion sets the APIVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the APIVersion field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithAPIVersion(value string) *EndpointApplyConfiguration { + b.TypeMetaApplyConfiguration.APIVersion = &value + return b +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithName(value string) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Name = &value + return b +} + +// WithGenerateName sets the GenerateName field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the GenerateName field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithGenerateName(value string) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.GenerateName = &value + return b +} + +// WithNamespace sets the Namespace field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Namespace field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithNamespace(value string) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Namespace = &value + return b +} + +// WithUID sets the UID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the UID field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithUID(value types.UID) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.UID = &value + return b +} + +// WithResourceVersion sets the ResourceVersion field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ResourceVersion field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithResourceVersion(value string) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.ResourceVersion = &value + return b +} + +// WithGeneration sets the Generation field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Generation field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithGeneration(value int64) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.Generation = &value + return b +} + +// WithCreationTimestamp sets the CreationTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CreationTimestamp field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithCreationTimestamp(value metav1.Time) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.CreationTimestamp = &value + return b +} + +// WithDeletionTimestamp sets the DeletionTimestamp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionTimestamp field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithDeletionTimestamp(value metav1.Time) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionTimestamp = &value + return b +} + +// WithDeletionGracePeriodSeconds sets the DeletionGracePeriodSeconds field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the DeletionGracePeriodSeconds field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithDeletionGracePeriodSeconds(value int64) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + b.ObjectMetaApplyConfiguration.DeletionGracePeriodSeconds = &value + return b +} + +// WithLabels puts the entries into the Labels field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Labels field, +// overwriting an existing map entries in Labels field with the same key. +func (b *EndpointApplyConfiguration) WithLabels(entries map[string]string) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Labels == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Labels = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Labels[k] = v + } + return b +} + +// WithAnnotations puts the entries into the Annotations field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, the entries provided by each call will be put on the Annotations field, +// overwriting an existing map entries in Annotations field with the same key. +func (b *EndpointApplyConfiguration) WithAnnotations(entries map[string]string) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + if b.ObjectMetaApplyConfiguration.Annotations == nil && len(entries) > 0 { + b.ObjectMetaApplyConfiguration.Annotations = make(map[string]string, len(entries)) + } + for k, v := range entries { + b.ObjectMetaApplyConfiguration.Annotations[k] = v + } + return b +} + +// WithOwnerReferences adds the given value to the OwnerReferences field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the OwnerReferences field. +func (b *EndpointApplyConfiguration) WithOwnerReferences(values ...*v1.OwnerReferenceApplyConfiguration) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + if values[i] == nil { + panic("nil value passed to WithOwnerReferences") + } + b.ObjectMetaApplyConfiguration.OwnerReferences = append(b.ObjectMetaApplyConfiguration.OwnerReferences, *values[i]) + } + return b +} + +// WithFinalizers adds the given value to the Finalizers field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Finalizers field. +func (b *EndpointApplyConfiguration) WithFinalizers(values ...string) *EndpointApplyConfiguration { + b.ensureObjectMetaApplyConfigurationExists() + for i := range values { + b.ObjectMetaApplyConfiguration.Finalizers = append(b.ObjectMetaApplyConfiguration.Finalizers, values[i]) + } + return b +} + +func (b *EndpointApplyConfiguration) ensureObjectMetaApplyConfigurationExists() { + if b.ObjectMetaApplyConfiguration == nil { + b.ObjectMetaApplyConfiguration = &v1.ObjectMetaApplyConfiguration{} + } +} + +// WithSpec sets the Spec field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Spec field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithSpec(value *EndpointSpecApplyConfiguration) *EndpointApplyConfiguration { + b.Spec = value + return b +} + +// WithStatus sets the Status field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Status field is set to the value of the last call. +func (b *EndpointApplyConfiguration) WithStatus(value *EndpointStatusApplyConfiguration) *EndpointApplyConfiguration { + b.Status = value + return b +} + +// GetKind retrieves the value of the Kind field in the declarative configuration. +func (b *EndpointApplyConfiguration) GetKind() *string { + return b.TypeMetaApplyConfiguration.Kind +} + +// GetAPIVersion retrieves the value of the APIVersion field in the declarative configuration. +func (b *EndpointApplyConfiguration) GetAPIVersion() *string { + return b.TypeMetaApplyConfiguration.APIVersion +} + +// GetName retrieves the value of the Name field in the declarative configuration. +func (b *EndpointApplyConfiguration) GetName() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Name +} + +// GetNamespace retrieves the value of the Namespace field in the declarative configuration. +func (b *EndpointApplyConfiguration) GetNamespace() *string { + b.ensureObjectMetaApplyConfigurationExists() + return b.ObjectMetaApplyConfiguration.Namespace +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointfilter.go new file mode 100644 index 000000000..0908e2c55 --- /dev/null +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointfilter.go @@ -0,0 +1,61 @@ +/* +Copyright 2025 The ORC 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + apiv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" +) + +// EndpointFilterApplyConfiguration represents a declarative configuration of the EndpointFilter type for use +// with apply. +type EndpointFilterApplyConfiguration struct { + ServiceRef *apiv1alpha1.KubernetesNameRef `json:"serviceRef,omitempty"` + Interface *string `json:"interface,omitempty"` + URL *string `json:"url,omitempty"` +} + +// EndpointFilterApplyConfiguration constructs a declarative configuration of the EndpointFilter type for use with +// apply. +func EndpointFilter() *EndpointFilterApplyConfiguration { + return &EndpointFilterApplyConfiguration{} +} + +// WithServiceRef sets the ServiceRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ServiceRef field is set to the value of the last call. +func (b *EndpointFilterApplyConfiguration) WithServiceRef(value apiv1alpha1.KubernetesNameRef) *EndpointFilterApplyConfiguration { + b.ServiceRef = &value + return b +} + +// WithInterface sets the Interface field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Interface field is set to the value of the last call. +func (b *EndpointFilterApplyConfiguration) WithInterface(value string) *EndpointFilterApplyConfiguration { + b.Interface = &value + return b +} + +// WithURL sets the URL field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the URL field is set to the value of the last call. +func (b *EndpointFilterApplyConfiguration) WithURL(value string) *EndpointFilterApplyConfiguration { + b.URL = &value + return b +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointimport.go new file mode 100644 index 000000000..e20a99cd7 --- /dev/null +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointimport.go @@ -0,0 +1,48 @@ +/* +Copyright 2025 The ORC 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// EndpointImportApplyConfiguration represents a declarative configuration of the EndpointImport type for use +// with apply. +type EndpointImportApplyConfiguration struct { + ID *string `json:"id,omitempty"` + Filter *EndpointFilterApplyConfiguration `json:"filter,omitempty"` +} + +// EndpointImportApplyConfiguration constructs a declarative configuration of the EndpointImport type for use with +// apply. +func EndpointImport() *EndpointImportApplyConfiguration { + return &EndpointImportApplyConfiguration{} +} + +// WithID sets the ID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ID field is set to the value of the last call. +func (b *EndpointImportApplyConfiguration) WithID(value string) *EndpointImportApplyConfiguration { + b.ID = &value + return b +} + +// WithFilter sets the Filter field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Filter field is set to the value of the last call. +func (b *EndpointImportApplyConfiguration) WithFilter(value *EndpointFilterApplyConfiguration) *EndpointImportApplyConfiguration { + b.Filter = value + return b +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcespec.go new file mode 100644 index 000000000..b9f157902 --- /dev/null +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcespec.go @@ -0,0 +1,79 @@ +/* +Copyright 2025 The ORC 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + apiv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" +) + +// EndpointResourceSpecApplyConfiguration represents a declarative configuration of the EndpointResourceSpec type for use +// with apply. +type EndpointResourceSpecApplyConfiguration struct { + Name *apiv1alpha1.OpenStackName `json:"name,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Interface *string `json:"interface,omitempty"` + URL *string `json:"url,omitempty"` + ServiceRef *apiv1alpha1.KubernetesNameRef `json:"serviceRef,omitempty"` +} + +// EndpointResourceSpecApplyConfiguration constructs a declarative configuration of the EndpointResourceSpec type for use with +// apply. +func EndpointResourceSpec() *EndpointResourceSpecApplyConfiguration { + return &EndpointResourceSpecApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *EndpointResourceSpecApplyConfiguration) WithName(value apiv1alpha1.OpenStackName) *EndpointResourceSpecApplyConfiguration { + b.Name = &value + return b +} + +// WithEnabled sets the Enabled field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Enabled field is set to the value of the last call. +func (b *EndpointResourceSpecApplyConfiguration) WithEnabled(value bool) *EndpointResourceSpecApplyConfiguration { + b.Enabled = &value + return b +} + +// WithInterface sets the Interface field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Interface field is set to the value of the last call. +func (b *EndpointResourceSpecApplyConfiguration) WithInterface(value string) *EndpointResourceSpecApplyConfiguration { + b.Interface = &value + return b +} + +// WithURL sets the URL field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the URL field is set to the value of the last call. +func (b *EndpointResourceSpecApplyConfiguration) WithURL(value string) *EndpointResourceSpecApplyConfiguration { + b.URL = &value + return b +} + +// WithServiceRef sets the ServiceRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ServiceRef field is set to the value of the last call. +func (b *EndpointResourceSpecApplyConfiguration) WithServiceRef(value apiv1alpha1.KubernetesNameRef) *EndpointResourceSpecApplyConfiguration { + b.ServiceRef = &value + return b +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcestatus.go new file mode 100644 index 000000000..8a0b7c87c --- /dev/null +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcestatus.go @@ -0,0 +1,75 @@ +/* +Copyright 2025 The ORC 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// EndpointResourceStatusApplyConfiguration represents a declarative configuration of the EndpointResourceStatus type for use +// with apply. +type EndpointResourceStatusApplyConfiguration struct { + Name *string `json:"name,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Interface *string `json:"interface,omitempty"` + URL *string `json:"url,omitempty"` + ServiceID *string `json:"serviceID,omitempty"` +} + +// EndpointResourceStatusApplyConfiguration constructs a declarative configuration of the EndpointResourceStatus type for use with +// apply. +func EndpointResourceStatus() *EndpointResourceStatusApplyConfiguration { + return &EndpointResourceStatusApplyConfiguration{} +} + +// WithName sets the Name field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Name field is set to the value of the last call. +func (b *EndpointResourceStatusApplyConfiguration) WithName(value string) *EndpointResourceStatusApplyConfiguration { + b.Name = &value + return b +} + +// WithEnabled sets the Enabled field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Enabled field is set to the value of the last call. +func (b *EndpointResourceStatusApplyConfiguration) WithEnabled(value bool) *EndpointResourceStatusApplyConfiguration { + b.Enabled = &value + return b +} + +// WithInterface sets the Interface field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Interface field is set to the value of the last call. +func (b *EndpointResourceStatusApplyConfiguration) WithInterface(value string) *EndpointResourceStatusApplyConfiguration { + b.Interface = &value + return b +} + +// WithURL sets the URL field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the URL field is set to the value of the last call. +func (b *EndpointResourceStatusApplyConfiguration) WithURL(value string) *EndpointResourceStatusApplyConfiguration { + b.URL = &value + return b +} + +// WithServiceID sets the ServiceID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ServiceID field is set to the value of the last call. +func (b *EndpointResourceStatusApplyConfiguration) WithServiceID(value string) *EndpointResourceStatusApplyConfiguration { + b.ServiceID = &value + return b +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointspec.go new file mode 100644 index 000000000..fbe73d129 --- /dev/null +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointspec.go @@ -0,0 +1,79 @@ +/* +Copyright 2025 The ORC 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + apiv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" +) + +// EndpointSpecApplyConfiguration represents a declarative configuration of the EndpointSpec type for use +// with apply. +type EndpointSpecApplyConfiguration struct { + Import *EndpointImportApplyConfiguration `json:"import,omitempty"` + Resource *EndpointResourceSpecApplyConfiguration `json:"resource,omitempty"` + ManagementPolicy *apiv1alpha1.ManagementPolicy `json:"managementPolicy,omitempty"` + ManagedOptions *ManagedOptionsApplyConfiguration `json:"managedOptions,omitempty"` + CloudCredentialsRef *CloudCredentialsReferenceApplyConfiguration `json:"cloudCredentialsRef,omitempty"` +} + +// EndpointSpecApplyConfiguration constructs a declarative configuration of the EndpointSpec type for use with +// apply. +func EndpointSpec() *EndpointSpecApplyConfiguration { + return &EndpointSpecApplyConfiguration{} +} + +// WithImport sets the Import field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Import field is set to the value of the last call. +func (b *EndpointSpecApplyConfiguration) WithImport(value *EndpointImportApplyConfiguration) *EndpointSpecApplyConfiguration { + b.Import = value + return b +} + +// WithResource sets the Resource field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resource field is set to the value of the last call. +func (b *EndpointSpecApplyConfiguration) WithResource(value *EndpointResourceSpecApplyConfiguration) *EndpointSpecApplyConfiguration { + b.Resource = value + return b +} + +// WithManagementPolicy sets the ManagementPolicy field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ManagementPolicy field is set to the value of the last call. +func (b *EndpointSpecApplyConfiguration) WithManagementPolicy(value apiv1alpha1.ManagementPolicy) *EndpointSpecApplyConfiguration { + b.ManagementPolicy = &value + return b +} + +// WithManagedOptions sets the ManagedOptions field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ManagedOptions field is set to the value of the last call. +func (b *EndpointSpecApplyConfiguration) WithManagedOptions(value *ManagedOptionsApplyConfiguration) *EndpointSpecApplyConfiguration { + b.ManagedOptions = value + return b +} + +// WithCloudCredentialsRef sets the CloudCredentialsRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the CloudCredentialsRef field is set to the value of the last call. +func (b *EndpointSpecApplyConfiguration) WithCloudCredentialsRef(value *CloudCredentialsReferenceApplyConfiguration) *EndpointSpecApplyConfiguration { + b.CloudCredentialsRef = value + return b +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointstatus.go new file mode 100644 index 000000000..ab14837ef --- /dev/null +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointstatus.go @@ -0,0 +1,66 @@ +/* +Copyright 2025 The ORC 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + v1 "k8s.io/client-go/applyconfigurations/meta/v1" +) + +// EndpointStatusApplyConfiguration represents a declarative configuration of the EndpointStatus type for use +// with apply. +type EndpointStatusApplyConfiguration struct { + Conditions []v1.ConditionApplyConfiguration `json:"conditions,omitempty"` + ID *string `json:"id,omitempty"` + Resource *EndpointResourceStatusApplyConfiguration `json:"resource,omitempty"` +} + +// EndpointStatusApplyConfiguration constructs a declarative configuration of the EndpointStatus type for use with +// apply. +func EndpointStatus() *EndpointStatusApplyConfiguration { + return &EndpointStatusApplyConfiguration{} +} + +// WithConditions adds the given value to the Conditions field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Conditions field. +func (b *EndpointStatusApplyConfiguration) WithConditions(values ...*v1.ConditionApplyConfiguration) *EndpointStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithConditions") + } + b.Conditions = append(b.Conditions, *values[i]) + } + return b +} + +// WithID sets the ID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ID field is set to the value of the last call. +func (b *EndpointStatusApplyConfiguration) WithID(value string) *EndpointStatusApplyConfiguration { + b.ID = &value + return b +} + +// WithResource sets the Resource field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Resource field is set to the value of the last call. +func (b *EndpointStatusApplyConfiguration) WithResource(value *EndpointResourceStatusApplyConfiguration) *EndpointStatusApplyConfiguration { + b.Resource = value + return b +} diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/endpoint.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/endpoint.go new file mode 100644 index 000000000..8c0f3c58b --- /dev/null +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/endpoint.go @@ -0,0 +1,74 @@ +/* +Copyright 2025 The ORC 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + context "context" + + apiv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" + applyconfigurationapiv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/pkg/clients/applyconfiguration/api/v1alpha1" + scheme "github.com/k-orc/openstack-resource-controller/v2/pkg/clients/clientset/clientset/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + gentype "k8s.io/client-go/gentype" +) + +// EndpointsGetter has a method to return a EndpointInterface. +// A group's client should implement this interface. +type EndpointsGetter interface { + Endpoints(namespace string) EndpointInterface +} + +// EndpointInterface has methods to work with Endpoint resources. +type EndpointInterface interface { + Create(ctx context.Context, endpoint *apiv1alpha1.Endpoint, opts v1.CreateOptions) (*apiv1alpha1.Endpoint, error) + Update(ctx context.Context, endpoint *apiv1alpha1.Endpoint, opts v1.UpdateOptions) (*apiv1alpha1.Endpoint, error) + // Add a +genclient:noStatus comment above the type to avoid generating UpdateStatus(). + UpdateStatus(ctx context.Context, endpoint *apiv1alpha1.Endpoint, opts v1.UpdateOptions) (*apiv1alpha1.Endpoint, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*apiv1alpha1.Endpoint, error) + List(ctx context.Context, opts v1.ListOptions) (*apiv1alpha1.EndpointList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *apiv1alpha1.Endpoint, err error) + Apply(ctx context.Context, endpoint *applyconfigurationapiv1alpha1.EndpointApplyConfiguration, opts v1.ApplyOptions) (result *apiv1alpha1.Endpoint, err error) + // Add a +genclient:noStatus comment above the type to avoid generating ApplyStatus(). + ApplyStatus(ctx context.Context, endpoint *applyconfigurationapiv1alpha1.EndpointApplyConfiguration, opts v1.ApplyOptions) (result *apiv1alpha1.Endpoint, err error) + EndpointExpansion +} + +// endpoints implements EndpointInterface +type endpoints struct { + *gentype.ClientWithListAndApply[*apiv1alpha1.Endpoint, *apiv1alpha1.EndpointList, *applyconfigurationapiv1alpha1.EndpointApplyConfiguration] +} + +// newEndpoints returns a Endpoints +func newEndpoints(c *OpenstackV1alpha1Client, namespace string) *endpoints { + return &endpoints{ + gentype.NewClientWithListAndApply[*apiv1alpha1.Endpoint, *apiv1alpha1.EndpointList, *applyconfigurationapiv1alpha1.EndpointApplyConfiguration]( + "endpoints", + c.RESTClient(), + scheme.ParameterCodec, + namespace, + func() *apiv1alpha1.Endpoint { return &apiv1alpha1.Endpoint{} }, + func() *apiv1alpha1.EndpointList { return &apiv1alpha1.EndpointList{} }, + ), + } +} diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_endpoint.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_endpoint.go new file mode 100644 index 000000000..bc2842cde --- /dev/null +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_endpoint.go @@ -0,0 +1,51 @@ +/* +Copyright 2025 The ORC 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. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + v1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" + apiv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/pkg/clients/applyconfiguration/api/v1alpha1" + typedapiv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/pkg/clients/clientset/clientset/typed/api/v1alpha1" + gentype "k8s.io/client-go/gentype" +) + +// fakeEndpoints implements EndpointInterface +type fakeEndpoints struct { + *gentype.FakeClientWithListAndApply[*v1alpha1.Endpoint, *v1alpha1.EndpointList, *apiv1alpha1.EndpointApplyConfiguration] + Fake *FakeOpenstackV1alpha1 +} + +func newFakeEndpoints(fake *FakeOpenstackV1alpha1, namespace string) typedapiv1alpha1.EndpointInterface { + return &fakeEndpoints{ + gentype.NewFakeClientWithListAndApply[*v1alpha1.Endpoint, *v1alpha1.EndpointList, *apiv1alpha1.EndpointApplyConfiguration]( + fake.Fake, + namespace, + v1alpha1.SchemeGroupVersion.WithResource("endpoints"), + v1alpha1.SchemeGroupVersion.WithKind("Endpoint"), + func() *v1alpha1.Endpoint { return &v1alpha1.Endpoint{} }, + func() *v1alpha1.EndpointList { return &v1alpha1.EndpointList{} }, + func(dst, src *v1alpha1.EndpointList) { dst.ListMeta = src.ListMeta }, + func(list *v1alpha1.EndpointList) []*v1alpha1.Endpoint { return gentype.ToPointerSlice(list.Items) }, + func(list *v1alpha1.EndpointList, items []*v1alpha1.Endpoint) { + list.Items = gentype.FromPointerSlice(items) + }, + ), + fake, + } +} diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/endpoint.go b/pkg/clients/informers/externalversions/api/v1alpha1/endpoint.go new file mode 100644 index 000000000..496b05405 --- /dev/null +++ b/pkg/clients/informers/externalversions/api/v1alpha1/endpoint.go @@ -0,0 +1,102 @@ +/* +Copyright 2025 The ORC 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. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + context "context" + time "time" + + v2apiv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" + clientset "github.com/k-orc/openstack-resource-controller/v2/pkg/clients/clientset/clientset" + internalinterfaces "github.com/k-orc/openstack-resource-controller/v2/pkg/clients/informers/externalversions/internalinterfaces" + apiv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/pkg/clients/listers/api/v1alpha1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// EndpointInformer provides access to a shared informer and lister for +// Endpoints. +type EndpointInformer interface { + Informer() cache.SharedIndexInformer + Lister() apiv1alpha1.EndpointLister +} + +type endpointInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewEndpointInformer constructs a new informer for Endpoint type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewEndpointInformer(client clientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredEndpointInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredEndpointInformer constructs a new informer for Endpoint type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredEndpointInformer(client clientset.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.OpenstackV1alpha1().Endpoints(namespace).List(context.Background(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.OpenstackV1alpha1().Endpoints(namespace).Watch(context.Background(), options) + }, + ListWithContextFunc: func(ctx context.Context, options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.OpenstackV1alpha1().Endpoints(namespace).List(ctx, options) + }, + WatchFuncWithContext: func(ctx context.Context, options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.OpenstackV1alpha1().Endpoints(namespace).Watch(ctx, options) + }, + }, + &v2apiv1alpha1.Endpoint{}, + resyncPeriod, + indexers, + ) +} + +func (f *endpointInformer) defaultInformer(client clientset.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredEndpointInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *endpointInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&v2apiv1alpha1.Endpoint{}, f.defaultInformer) +} + +func (f *endpointInformer) Lister() apiv1alpha1.EndpointLister { + return apiv1alpha1.NewEndpointLister(f.Informer().GetIndexer()) +} diff --git a/pkg/clients/listers/api/v1alpha1/endpoint.go b/pkg/clients/listers/api/v1alpha1/endpoint.go new file mode 100644 index 000000000..427f09149 --- /dev/null +++ b/pkg/clients/listers/api/v1alpha1/endpoint.go @@ -0,0 +1,70 @@ +/* +Copyright 2025 The ORC 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. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1alpha1 + +import ( + apiv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" + labels "k8s.io/apimachinery/pkg/labels" + listers "k8s.io/client-go/listers" + cache "k8s.io/client-go/tools/cache" +) + +// EndpointLister helps list Endpoints. +// All objects returned here must be treated as read-only. +type EndpointLister interface { + // List lists all Endpoints in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*apiv1alpha1.Endpoint, err error) + // Endpoints returns an object that can list and get Endpoints. + Endpoints(namespace string) EndpointNamespaceLister + EndpointListerExpansion +} + +// endpointLister implements the EndpointLister interface. +type endpointLister struct { + listers.ResourceIndexer[*apiv1alpha1.Endpoint] +} + +// NewEndpointLister returns a new EndpointLister. +func NewEndpointLister(indexer cache.Indexer) EndpointLister { + return &endpointLister{listers.New[*apiv1alpha1.Endpoint](indexer, apiv1alpha1.Resource("endpoint"))} +} + +// Endpoints returns an object that can list and get Endpoints. +func (s *endpointLister) Endpoints(namespace string) EndpointNamespaceLister { + return endpointNamespaceLister{listers.NewNamespaced[*apiv1alpha1.Endpoint](s.ResourceIndexer, namespace)} +} + +// EndpointNamespaceLister helps list and get Endpoints. +// All objects returned here must be treated as read-only. +type EndpointNamespaceLister interface { + // List lists all Endpoints in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*apiv1alpha1.Endpoint, err error) + // Get retrieves the Endpoint from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*apiv1alpha1.Endpoint, error) + EndpointNamespaceListerExpansion +} + +// endpointNamespaceLister implements the EndpointNamespaceLister +// interface. +type endpointNamespaceLister struct { + listers.ResourceIndexer[*apiv1alpha1.Endpoint] +} From 2783f0e4d98cdcfdef591af55dfcd3e7924c28af Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Wed, 17 Dec 2025 11:09:17 -0300 Subject: [PATCH 2/9] keystone: endpoint controller implementation Signed-off-by: Winicius Silva --- PROJECT | 8 + README.md | 2 +- api/v1alpha1/endpoint_types.go | 60 +-- api/v1alpha1/zz_generated.deepcopy.go | 212 ++++++++++ cmd/manager/main.go | 2 + cmd/models-schema/zz_generated.openapi.go | 369 ++++++++++++++++++ cmd/resource-generator/main.go | 3 + .../openstack.k-orc.cloud_endpoints.yaml | 11 +- config/crd/kustomization.yaml | 1 + .../bases/orc.clusterserviceversion.yaml | 5 + config/rbac/role.yaml | 2 + config/samples/kustomization.yaml | 1 + .../samples/openstack_v1alpha1_endpoint.yaml | 9 +- internal/controllers/endpoint/actuator.go | 97 +++-- .../controllers/endpoint/actuator_test.go | 41 +- internal/controllers/endpoint/status.go | 10 +- .../tests/endpoint-create-full/00-assert.yaml | 6 +- .../00-create-resource.yaml | 17 +- .../endpoint-create-minimal/00-assert.yaml | 5 +- .../00-create-resource.yaml | 16 +- .../00-import-resource.yaml | 6 +- .../01-create-trap-resource.yaml | 27 +- .../02-create-resource.yaml | 25 +- .../03-delete-import-dependencies.yaml | 2 +- .../00-create-resources.yaml | 21 +- .../01-import-resource.yaml | 5 +- .../endpoint-import/00-import-resource.yaml | 20 +- .../tests/endpoint-import/01-assert.yaml | 4 +- .../01-create-trap-resource.yaml | 15 +- .../tests/endpoint-import/02-assert.yaml | 9 +- .../endpoint-import/02-create-resource.yaml | 20 +- .../tests/endpoint-update/00-assert.yaml | 28 +- .../endpoint-update/00-minimal-resource.yaml | 14 +- .../tests/endpoint-update/01-assert.yaml | 5 +- .../endpoint-update/01-updated-resource.yaml | 7 +- .../tests/endpoint-update/02-assert.yaml | 10 +- internal/controllers/service/actuator_test.go | 2 +- internal/osclients/mock/doc.go | 3 + internal/scope/mock.go | 7 + internal/scope/provider.go | 4 + internal/scope/scope.go | 1 + kuttl-test.yaml | 1 + .../api/v1alpha1/endpointfilter.go | 18 +- .../applyconfiguration/internal/internal.go | 115 ++++++ pkg/clients/applyconfiguration/utils.go | 14 + .../typed/api/v1alpha1/api_client.go | 5 + .../api/v1alpha1/fake/fake_api_client.go | 4 + .../typed/api/v1alpha1/generated_expansion.go | 2 + .../api/v1alpha1/interface.go | 7 + .../informers/externalversions/generic.go | 2 + .../api/v1alpha1/expansion_generated.go | 8 + website/docs/crd-reference.md | 143 +++++++ 52 files changed, 1181 insertions(+), 250 deletions(-) diff --git a/PROJECT b/PROJECT index 8d6e2c12d..23bc71037 100644 --- a/PROJECT +++ b/PROJECT @@ -16,6 +16,14 @@ resources: kind: Domain path: github.com/k-orc/openstack-resource-controller/api/v1alpha1 version: v1alpha1 +- api: + crdVersion: v1 + namespaced: true + domain: k-orc.cloud + group: openstack + kind: Endpoint + path: github.com/k-orc/openstack-resource-controller/api/v1alpha1 + version: v1alpha1 - api: crdVersion: v1 namespaced: true diff --git a/README.md b/README.md index 26c737373..dd158f75a 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,7 @@ kubectl delete -f $ORC_RELEASE | **controller** | **1.x** | **2.x** | **main** | |:---------------------------:|:-------:|:-------:|:--------:| | domain | | ✔ | ✔ | +| endpoint | | ◐ | ◐ | | flavor | | ✔ | ✔ | | floating ip | | ◐ | ◐ | | group | | ✔ | ✔ | @@ -87,7 +88,6 @@ kubectl delete -f $ORC_RELEASE | volume type | | ◐ | ◐ | - ✔: mostly implemented ◐: partially implemented diff --git a/api/v1alpha1/endpoint_types.go b/api/v1alpha1/endpoint_types.go index 39271d1c2..01e512e37 100644 --- a/api/v1alpha1/endpoint_types.go +++ b/api/v1alpha1/endpoint_types.go @@ -23,46 +23,43 @@ type EndpointResourceSpec struct { // +optional Name *OpenStackName `json:"name,omitempty"` - // description is a human-readable description for the resource. - // +kubebuilder:validation:MinLength:=1 - // +kubebuilder:validation:MaxLength:=255 + // enabled indicates whether the endpoint is enabled or not. + // +kubebuilder:default:=true // +optional - Description *string `json:"description,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + + // interface indicates the visibility of the endpoint. + // +kubebuilder:validation:Enum:=admin;internal;public + // +required + Interface string `json:"interface,omitempty"` + + // url is the endpoint URL. + // +kubebuilder:validation:MaxLength=1024 + // +required + URL string `json:"url"` // serviceRef is a reference to the ORC Service which this resource is associated with. // +required // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="serviceRef is immutable" ServiceRef KubernetesNameRef `json:"serviceRef,omitempty"` - - // TODO(scaffolding): Add more types. - // To see what is supported, you can take inspiration from the CreateOpts structure from - // github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints - // - // Until you have implemented mutability for the field, you must add a CEL validation - // preventing the field being modified: - // `// +kubebuilder:validation:XValidation:rule="self == oldSelf",message=" is immutable"` } // EndpointFilter defines an existing resource by its properties // +kubebuilder:validation:MinProperties:=1 type EndpointFilter struct { - // name of the existing resource - // +optional - Name *OpenStackName `json:"name,omitempty"` - - // description of the existing resource - // +kubebuilder:validation:MinLength:=1 - // +kubebuilder:validation:MaxLength:=255 + // interface of the existing endpoint. + // +kubebuilder:validation:Enum:=admin;internal;public // +optional - Description *string `json:"description,omitempty"` + Interface string `json:"interface,omitempty"` // serviceRef is a reference to the ORC Service which this resource is associated with. // +optional ServiceRef *KubernetesNameRef `json:"serviceRef,omitempty"` - // TODO(scaffolding): Add more types. - // To see what is supported, you can take inspiration from the ListOpts structure from - // github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints + // url is the URL of the existing endpoint. + // +kubebuilder:validation:MaxLength=1024 + // +optional + URL string `json:"url,omitempty"` } // EndpointResourceStatus represents the observed state of the resource. @@ -72,17 +69,22 @@ type EndpointResourceStatus struct { // +optional Name string `json:"name,omitempty"` - // description is a human-readable description for the resource. + // enabled indicates whether the endpoint is enabled or not. + // +optional + Enabled *bool `json:"enabled,omitempty"` + + // interface indicates the visibility of the endpoint. + // +kubebuilder:validation:Enum:=admin;internal;public + // +optional + Interface string `json:"interface,omitempty"` + + // url is the endpoint URL. // +kubebuilder:validation:MaxLength=1024 // +optional - Description string `json:"description,omitempty"` + URL string `json:"url,omitempty"` // serviceID is the ID of the Service to which the resource is associated. // +kubebuilder:validation:MaxLength=1024 // +optional ServiceID string `json:"serviceID,omitempty"` - - // TODO(scaffolding): Add more types. - // To see what is supported, you can take inspiration from the Endpoint structure from - // github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 67bfeab8a..0d8d337e9 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -347,6 +347,218 @@ func (in *DomainStatus) DeepCopy() *DomainStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Endpoint) DeepCopyInto(out *Endpoint) { + *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 Endpoint. +func (in *Endpoint) DeepCopy() *Endpoint { + if in == nil { + return nil + } + out := new(Endpoint) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *Endpoint) 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 *EndpointFilter) DeepCopyInto(out *EndpointFilter) { + *out = *in + if in.ServiceRef != nil { + in, out := &in.ServiceRef, &out.ServiceRef + *out = new(KubernetesNameRef) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointFilter. +func (in *EndpointFilter) DeepCopy() *EndpointFilter { + if in == nil { + return nil + } + out := new(EndpointFilter) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EndpointImport) DeepCopyInto(out *EndpointImport) { + *out = *in + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.Filter != nil { + in, out := &in.Filter, &out.Filter + *out = new(EndpointFilter) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointImport. +func (in *EndpointImport) DeepCopy() *EndpointImport { + if in == nil { + return nil + } + out := new(EndpointImport) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EndpointList) DeepCopyInto(out *EndpointList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]Endpoint, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointList. +func (in *EndpointList) DeepCopy() *EndpointList { + if in == nil { + return nil + } + out := new(EndpointList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *EndpointList) 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 *EndpointResourceSpec) DeepCopyInto(out *EndpointResourceSpec) { + *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(OpenStackName) + **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 EndpointResourceSpec. +func (in *EndpointResourceSpec) DeepCopy() *EndpointResourceSpec { + if in == nil { + return nil + } + out := new(EndpointResourceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EndpointResourceStatus) DeepCopyInto(out *EndpointResourceStatus) { + *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 EndpointResourceStatus. +func (in *EndpointResourceStatus) DeepCopy() *EndpointResourceStatus { + if in == nil { + return nil + } + out := new(EndpointResourceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EndpointSpec) DeepCopyInto(out *EndpointSpec) { + *out = *in + if in.Import != nil { + in, out := &in.Import, &out.Import + *out = new(EndpointImport) + (*in).DeepCopyInto(*out) + } + if in.Resource != nil { + in, out := &in.Resource, &out.Resource + *out = new(EndpointResourceSpec) + (*in).DeepCopyInto(*out) + } + if in.ManagedOptions != nil { + in, out := &in.ManagedOptions, &out.ManagedOptions + *out = new(ManagedOptions) + **out = **in + } + out.CloudCredentialsRef = in.CloudCredentialsRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointSpec. +func (in *EndpointSpec) DeepCopy() *EndpointSpec { + if in == nil { + return nil + } + out := new(EndpointSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EndpointStatus) DeepCopyInto(out *EndpointStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(string) + **out = **in + } + if in.Resource != nil { + in, out := &in.Resource, &out.Resource + *out = new(EndpointResourceStatus) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EndpointStatus. +func (in *EndpointStatus) DeepCopy() *EndpointStatus { + if in == nil { + return nil + } + out := new(EndpointStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ExternalGateway) DeepCopyInto(out *ExternalGateway) { *out = *in diff --git a/cmd/manager/main.go b/cmd/manager/main.go index 293aa2bab..50346c14a 100644 --- a/cmd/manager/main.go +++ b/cmd/manager/main.go @@ -28,6 +28,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/log/zap" "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/domain" + "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/endpoint" "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/flavor" "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/floatingip" "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/interfaces" @@ -107,6 +108,7 @@ func main() { scopeFactory := scope.NewFactory(orcOpts.ScopeCacheMaxSize, caCerts) controllers := []interfaces.Controller{ + endpoint.New(scopeFactory), image.New(scopeFactory), network.New(scopeFactory), subnet.New(scopeFactory), diff --git a/cmd/models-schema/zz_generated.openapi.go b/cmd/models-schema/zz_generated.openapi.go index 5b739dfef..9799c6d2e 100644 --- a/cmd/models-schema/zz_generated.openapi.go +++ b/cmd/models-schema/zz_generated.openapi.go @@ -44,6 +44,14 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.DomainResourceStatus": schema_openstack_resource_controller_v2_api_v1alpha1_DomainResourceStatus(ref), "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.DomainSpec": schema_openstack_resource_controller_v2_api_v1alpha1_DomainSpec(ref), "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.DomainStatus": schema_openstack_resource_controller_v2_api_v1alpha1_DomainStatus(ref), + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.Endpoint": schema_openstack_resource_controller_v2_api_v1alpha1_Endpoint(ref), + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointFilter": schema_openstack_resource_controller_v2_api_v1alpha1_EndpointFilter(ref), + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointImport": schema_openstack_resource_controller_v2_api_v1alpha1_EndpointImport(ref), + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointList": schema_openstack_resource_controller_v2_api_v1alpha1_EndpointList(ref), + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointResourceSpec": schema_openstack_resource_controller_v2_api_v1alpha1_EndpointResourceSpec(ref), + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointResourceStatus": schema_openstack_resource_controller_v2_api_v1alpha1_EndpointResourceStatus(ref), + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointSpec": schema_openstack_resource_controller_v2_api_v1alpha1_EndpointSpec(ref), + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointStatus": schema_openstack_resource_controller_v2_api_v1alpha1_EndpointStatus(ref), "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ExternalGateway": schema_openstack_resource_controller_v2_api_v1alpha1_ExternalGateway(ref), "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ExternalGatewayStatus": schema_openstack_resource_controller_v2_api_v1alpha1_ExternalGatewayStatus(ref), "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.FilterByKeystoneTags": schema_openstack_resource_controller_v2_api_v1alpha1_FilterByKeystoneTags(ref), @@ -998,6 +1006,367 @@ func schema_openstack_resource_controller_v2_api_v1alpha1_DomainStatus(ref commo } } +func schema_openstack_resource_controller_v2_api_v1alpha1_Endpoint(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "Endpoint is the Schema for an ORC resource.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + 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{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + 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{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "metadata contains the object metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Description: "spec specifies the desired state of the resource.", + Default: map[string]interface{}{}, + Ref: ref("github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Description: "status defines the observed state of the resource.", + Default: map[string]interface{}{}, + Ref: ref("github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointStatus"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointSpec", "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_openstack_resource_controller_v2_api_v1alpha1_EndpointFilter(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "EndpointFilter defines an existing resource by its properties", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "interface": { + SchemaProps: spec.SchemaProps{ + Description: "interface of the existing endpoint.", + Type: []string{"string"}, + Format: "", + }, + }, + "serviceRef": { + SchemaProps: spec.SchemaProps{ + Description: "serviceRef is a reference to the ORC Service which this resource is associated with.", + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Description: "url is the URL of the existing endpoint.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + +func schema_openstack_resource_controller_v2_api_v1alpha1_EndpointImport(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "EndpointImport specifies an existing resource which will be imported instead of creating a new one", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "id": { + SchemaProps: spec.SchemaProps{ + Description: "id contains the unique identifier of an existing OpenStack resource. Note that when specifying an import by ID, the resource MUST already exist. The ORC object will enter an error state if the resource does not exist.", + Type: []string{"string"}, + Format: "", + }, + }, + "filter": { + SchemaProps: spec.SchemaProps{ + Description: "filter contains a resource query which is expected to return a single result. The controller will continue to retry if filter returns no results. If filter returns multiple results the controller will set an error state and will not continue to retry.", + Ref: ref("github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointFilter"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointFilter"}, + } +} + +func schema_openstack_resource_controller_v2_api_v1alpha1_EndpointList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "EndpointList contains a list of Endpoint.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + 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{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + 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{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "metadata contains the list metadata", + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Description: "items contains a list of Endpoint.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.Endpoint"), + }, + }, + }, + }, + }, + }, + Required: []string{"items"}, + }, + }, + Dependencies: []string{ + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.Endpoint", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_openstack_resource_controller_v2_api_v1alpha1_EndpointResourceSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "EndpointResourceSpec contains the desired state of the resource.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "name will be the name of the created resource. If not specified, the name of the ORC object will be used.", + Type: []string{"string"}, + Format: "", + }, + }, + "enabled": { + SchemaProps: spec.SchemaProps{ + Description: "enabled indicates whether the endpoint is enabled or not.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "interface": { + SchemaProps: spec.SchemaProps{ + Description: "interface indicates the visibility of the endpoint.", + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Description: "url is the endpoint URL.", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "serviceRef": { + SchemaProps: spec.SchemaProps{ + Description: "serviceRef is a reference to the ORC Service which this resource is associated with.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"interface", "url", "serviceRef"}, + }, + }, + } +} + +func schema_openstack_resource_controller_v2_api_v1alpha1_EndpointResourceStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "EndpointResourceStatus represents the observed state of the resource.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "name is a Human-readable name for the resource. Might not be unique.", + Type: []string{"string"}, + Format: "", + }, + }, + "enabled": { + SchemaProps: spec.SchemaProps{ + Description: "enabled indicates whether the endpoint is enabled or not.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "interface": { + SchemaProps: spec.SchemaProps{ + Description: "interface indicates the visibility of the endpoint.", + Type: []string{"string"}, + Format: "", + }, + }, + "url": { + SchemaProps: spec.SchemaProps{ + Description: "url is the endpoint URL.", + Type: []string{"string"}, + Format: "", + }, + }, + "serviceID": { + SchemaProps: spec.SchemaProps{ + Description: "serviceID is the ID of the Service to which the resource is associated.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + +func schema_openstack_resource_controller_v2_api_v1alpha1_EndpointSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "EndpointSpec defines the desired state of an ORC object.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "import": { + SchemaProps: spec.SchemaProps{ + Description: "import refers to an existing OpenStack resource which will be imported instead of creating a new one.", + Ref: ref("github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointImport"), + }, + }, + "resource": { + SchemaProps: spec.SchemaProps{ + Description: "resource specifies the desired state of the resource.\n\nresource may not be specified if the management policy is `unmanaged`.\n\nresource must be specified if the management policy is `managed`.", + Ref: ref("github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointResourceSpec"), + }, + }, + "managementPolicy": { + SchemaProps: spec.SchemaProps{ + Description: "managementPolicy defines how ORC will treat the object. Valid values are `managed`: ORC will create, update, and delete the resource; `unmanaged`: ORC will import an existing resource, and will not apply updates to it or delete it.", + Type: []string{"string"}, + Format: "", + }, + }, + "managedOptions": { + SchemaProps: spec.SchemaProps{ + Description: "managedOptions specifies options which may be applied to managed objects.", + Ref: ref("github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ManagedOptions"), + }, + }, + "cloudCredentialsRef": { + SchemaProps: spec.SchemaProps{ + Description: "cloudCredentialsRef points to a secret containing OpenStack credentials", + Default: map[string]interface{}{}, + Ref: ref("github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.CloudCredentialsReference"), + }, + }, + }, + Required: []string{"cloudCredentialsRef"}, + }, + }, + Dependencies: []string{ + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.CloudCredentialsReference", "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointImport", "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointResourceSpec", "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ManagedOptions"}, + } +} + +func schema_openstack_resource_controller_v2_api_v1alpha1_EndpointStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "EndpointStatus defines the observed state of an ORC resource.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "conditions": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-map-keys": []interface{}{ + "type", + }, + "x-kubernetes-list-type": "map", + "x-kubernetes-patch-merge-key": "type", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "conditions represents the observed status of the object. Known .status.conditions.type are: \"Available\", \"Progressing\"\n\nAvailable represents the availability of the OpenStack resource. If it is true then the resource is ready for use.\n\nProgressing indicates whether the controller is still attempting to reconcile the current state of the OpenStack resource to the desired state. Progressing will be False either because the desired state has been achieved, or because some terminal error prevents it from ever being achieved and the controller is no longer attempting to reconcile. If Progressing is True, an observer waiting on the resource should continue to wait.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"), + }, + }, + }, + }, + }, + "id": { + SchemaProps: spec.SchemaProps{ + Description: "id is the unique identifier of the OpenStack resource.", + Type: []string{"string"}, + Format: "", + }, + }, + "resource": { + SchemaProps: spec.SchemaProps{ + Description: "resource contains the observed state of the OpenStack resource.", + Ref: ref("github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointResourceStatus"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.EndpointResourceStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.Condition"}, + } +} + func schema_openstack_resource_controller_v2_api_v1alpha1_ExternalGateway(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/cmd/resource-generator/main.go b/cmd/resource-generator/main.go index 6848b155f..7b401f0cb 100644 --- a/cmd/resource-generator/main.go +++ b/cmd/resource-generator/main.go @@ -162,6 +162,9 @@ var resources []templateFields = []templateFields{ { Name: "Group", }, + { + Name: "Endpoint", + }, } // These resources won't be generated diff --git a/config/crd/bases/openstack.k-orc.cloud_endpoints.yaml b/config/crd/bases/openstack.k-orc.cloud_endpoints.yaml index 34a49522b..c2dbddb3d 100644 --- a/config/crd/bases/openstack.k-orc.cloud_endpoints.yaml +++ b/config/crd/bases/openstack.k-orc.cloud_endpoints.yaml @@ -93,15 +93,20 @@ spec: properties: interface: description: interface of the existing endpoint. + enum: + - admin + - internal + - public type: string serviceRef: - description: serviceRef is a reference to which the endpoint - belongs. + description: serviceRef is a reference to the ORC Service + which this resource is associated with. maxLength: 253 minLength: 1 type: string url: description: url is the URL of the existing endpoint. + maxLength: 1024 type: string type: object id: @@ -181,6 +186,7 @@ spec: rule: self == oldSelf url: description: url is the endpoint URL. + maxLength: 1024 type: string required: - interface @@ -312,6 +318,7 @@ spec: type: string url: description: url is the endpoint URL. + maxLength: 1024 type: string type: object type: object diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 33b8c85e2..47c09ccec 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -4,6 +4,7 @@ # It should be run by config/default resources: - bases/openstack.k-orc.cloud_domains.yaml +- bases/openstack.k-orc.cloud_endpoints.yaml - bases/openstack.k-orc.cloud_flavors.yaml - bases/openstack.k-orc.cloud_floatingips.yaml - bases/openstack.k-orc.cloud_groups.yaml diff --git a/config/manifests/bases/orc.clusterserviceversion.yaml b/config/manifests/bases/orc.clusterserviceversion.yaml index 0c5f1c0ea..0b7164e78 100644 --- a/config/manifests/bases/orc.clusterserviceversion.yaml +++ b/config/manifests/bases/orc.clusterserviceversion.yaml @@ -24,6 +24,11 @@ spec: kind: Domain name: domains.openstack.k-orc.cloud version: v1alpha1 + - description: Endpoint is the Schema for an ORC resource. + displayName: Endpoint + kind: Endpoint + name: endpoints.openstack.k-orc.cloud + version: v1alpha1 - description: Flavor is the Schema for an ORC resource. displayName: Flavor kind: Flavor diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 5a0a7443b..a2b54d6b0 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -18,6 +18,7 @@ rules: - openstack.k-orc.cloud resources: - domains + - endpoints - flavors - floatingips - groups @@ -48,6 +49,7 @@ rules: - openstack.k-orc.cloud resources: - domains/status + - endpoints/status - flavors/status - floatingips/status - groups/status diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index dac467c69..476b934cb 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -2,6 +2,7 @@ ## Append samples of your project ## resources: - openstack_v1alpha1_domain.yaml +- openstack_v1alpha1_endpoint.yaml - openstack_v1alpha1_flavor.yaml - openstack_v1alpha1_floatingip.yaml - openstack_v1alpha1_group.yaml diff --git a/config/samples/openstack_v1alpha1_endpoint.yaml b/config/samples/openstack_v1alpha1_endpoint.yaml index a45971790..783789298 100644 --- a/config/samples/openstack_v1alpha1_endpoint.yaml +++ b/config/samples/openstack_v1alpha1_endpoint.yaml @@ -5,10 +5,11 @@ metadata: name: endpoint-sample spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed resource: - description: Sample Endpoint - # TODO(scaffolding): Add all fields the resource supports + interface: internal + url: "https://example.com" + serviceRef: service-sample + diff --git a/internal/controllers/endpoint/actuator.go b/internal/controllers/endpoint/actuator.go index 7416577a2..1dae97108 100644 --- a/internal/controllers/endpoint/actuator.go +++ b/internal/controllers/endpoint/actuator.go @@ -18,8 +18,10 @@ package endpoint import ( "context" + "fmt" "iter" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -71,22 +73,30 @@ func (actuator endpointActuator) ListOSResourcesForAdoption(ctx context.Context, return nil, false } - // TODO(scaffolding) If you need to filter resources on fields that the List() function - // of gophercloud does not support, it's possible to perform client-side filtering. - // Check osclients.ResourceFilter + service, _ := serviceDependency.GetDependency( + ctx, actuator.k8sClient, orcObject, func(dep *orcv1alpha1.Service) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + + if service == nil { + return nil, false + } + + var filters []osclients.ResourceFilter[osResourceT] + filters = append(filters, func(e *endpoints.Endpoint) bool { + return e.URL == resourceSpec.URL + }) listOpts := endpoints.ListOpts{ - Name: getResourceName(orcObject), - Description: ptr.Deref(resourceSpec.Description, ""), + Availability: gophercloud.Availability(resourceSpec.Interface), + ServiceID: ptr.Deref(service.Status.ID, ""), } - return actuator.osClient.ListEndpoints(ctx, listOpts), true + return actuator.listOsResources(ctx, listOpts, filters), true } func (actuator endpointActuator) ListOSResourcesForImport(ctx context.Context, obj orcObjectPT, filter filterT) (iter.Seq2[*osResourceT, error], progress.ReconcileStatus) { - // TODO(scaffolding) If you need to filter resources on fields that the List() function - // of gophercloud does not support, it's possible to perform client-side filtering. - // Check osclients.ResourceFilter var reconcileStatus progress.ReconcileStatus service := &orcv1alpha1.Service{} @@ -112,14 +122,24 @@ func (actuator endpointActuator) ListOSResourcesForImport(ctx context.Context, o return nil, reconcileStatus } + var resourceFilters []osclients.ResourceFilter[osResourceT] + if filter.URL != "" { + resourceFilters = append(resourceFilters, func(e *endpoints.Endpoint) bool { + return e.URL == filter.URL + }) + } + listOpts := endpoints.ListOpts{ - Name: string(ptr.Deref(filter.Name, "")), - Description: string(ptr.Deref(filter.Description, "")), - Service: ptr.Deref(service.Status.ID, ""), - // TODO(scaffolding): Add more import filters + ServiceID: ptr.Deref(service.Status.ID, ""), + Availability: gophercloud.Availability(filter.Interface), } - return actuator.osClient.ListEndpoints(ctx, listOpts), nil + return actuator.listOsResources(ctx, listOpts, resourceFilters), nil +} + +func (actuator endpointActuator) listOsResources(ctx context.Context, listOpts endpoints.ListOpts, filter []osclients.ResourceFilter[osResourceT]) iter.Seq2[*osResourceT, error] { + endpoints := actuator.osClient.ListEndpoints(ctx, listOpts) + return osclients.Filter(endpoints, filter...) } func (actuator endpointActuator) CreateResource(ctx context.Context, obj orcObjectPT) (*osResourceT, progress.ReconcileStatus) { @@ -133,23 +153,24 @@ func (actuator endpointActuator) CreateResource(ctx context.Context, obj orcObje var reconcileStatus progress.ReconcileStatus var serviceID string - service, serviceDepRS := serviceDependency.GetDependency( - ctx, actuator.k8sClient, obj, func(dep *orcv1alpha1.Service) bool { - return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil - }, - ) - reconcileStatus = reconcileStatus.WithReconcileStatus(serviceDepRS) - if service != nil { - serviceID = ptr.Deref(service.Status.ID, "") - } + service, serviceDepRS := serviceDependency.GetDependency( + ctx, actuator.k8sClient, obj, func(dep *orcv1alpha1.Service) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + + reconcileStatus = reconcileStatus.WithReconcileStatus(serviceDepRS) + if service != nil { + serviceID = ptr.Deref(service.Status.ID, "") + } if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { return nil, reconcileStatus } createOpts := endpoints.CreateOpts{ - Name: getResourceName(obj), - Description: ptr.Deref(resource.Description, ""), - ServiceID: serviceID, - // TODO(scaffolding): Add more fields + Name: getResourceName(obj), + ServiceID: serviceID, + Availability: gophercloud.Availability(resource.Interface), + URL: resource.URL, } osResource, err := actuator.osClient.CreateEndpoint(ctx, createOpts) @@ -180,9 +201,8 @@ func (actuator endpointActuator) updateResource(ctx context.Context, obj orcObje updateOpts := endpoints.UpdateOpts{} handleNameUpdate(&updateOpts, obj, osResource) - handleDescriptionUpdate(&updateOpts, resource, osResource) - - // TODO(scaffolding): add handler for all fields supporting mutability + handleURLUpdate(&updateOpts, resource, osResource) + handleInterfaceUpdate(&updateOpts, resource, osResource) needsUpdate, err := needsUpdate(updateOpts) if err != nil { @@ -225,14 +245,21 @@ func needsUpdate(updateOpts endpoints.UpdateOpts) (bool, error) { func handleNameUpdate(updateOpts *endpoints.UpdateOpts, obj orcObjectPT, osResource *osResourceT) { name := getResourceName(obj) if osResource.Name != name { - updateOpts.Name = &name + updateOpts.Name = name + } +} + +func handleURLUpdate(updateOpts *endpoints.UpdateOpts, resource *resourceSpecT, osResource *osResourceT) { + url := resource.URL + if osResource.URL != url { + updateOpts.URL = url } } -func handleDescriptionUpdate(updateOpts *endpoints.UpdateOpts, resource *resourceSpecT, osResource *osResourceT) { - description := ptr.Deref(resource.Description, "") - if osResource.Description != description { - updateOpts.Description = &description +func handleInterfaceUpdate(updateOpts *endpoints.UpdateOpts, resource *resourceSpecT, osResource *osResourceT) { + endpointInterface := gophercloud.Availability(resource.Interface) + if osResource.Availability != endpointInterface { + updateOpts.Availability = endpointInterface } } diff --git a/internal/controllers/endpoint/actuator_test.go b/internal/controllers/endpoint/actuator_test.go index ed7fdce2c..d322f0ca4 100644 --- a/internal/controllers/endpoint/actuator_test.go +++ b/internal/controllers/endpoint/actuator_test.go @@ -19,6 +19,7 @@ package endpoint import ( "testing" + "github.com/gophercloud/gophercloud/v2" "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/endpoints" orcv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" "k8s.io/utils/ptr" @@ -37,7 +38,7 @@ func TestNeedsUpdate(t *testing.T) { }, { name: "Updated opts", - updateOpts: endpoints.UpdateOpts{Name: ptr.To("updated")}, + updateOpts: endpoints.UpdateOpts{URL: "http://updated.com"}, expectChange: true, }, } @@ -52,31 +53,25 @@ func TestNeedsUpdate(t *testing.T) { } } -func TestHandleNameUpdate(t *testing.T) { - ptrToName := ptr.To[orcv1alpha1.OpenStackName] +func TestHandleInterfaceUpdate(t *testing.T) { testCases := []struct { name string - newValue *orcv1alpha1.OpenStackName + newValue *string existingValue string expectChange bool }{ - {name: "Identical", newValue: ptrToName("name"), existingValue: "name", expectChange: false}, - {name: "Different", newValue: ptrToName("new-name"), existingValue: "name", expectChange: true}, - {name: "No value provided, existing is identical to object name", newValue: nil, existingValue: "object-name", expectChange: false}, - {name: "No value provided, existing is different from object name", newValue: nil, existingValue: "different-from-object-name", expectChange: true}, + {name: "Identical", newValue: ptr.To("internal"), existingValue: "internal", expectChange: false}, + {name: "Different", newValue: ptr.To("public"), existingValue: "internal", expectChange: true}, + {name: "No value provided, existing is kept", newValue: nil, existingValue: "internal", expectChange: false}, } for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { - resource := &orcv1alpha1.Endpoint{} - resource.Name = "object-name" - resource.Spec = orcv1alpha1.EndpointSpec{ - Resource: &orcv1alpha1.EndpointResourceSpec{Name: tt.newValue}, - } - osResource := &osResourceT{Name: tt.existingValue} + resourceSpec := &orcv1alpha1.EndpointResourceSpec{Interface: ptr.Deref(tt.newValue, "")} + osResource := &osResourceT{Availability: gophercloud.Availability(tt.existingValue)} updateOpts := endpoints.UpdateOpts{} - handleNameUpdate(&updateOpts, resource, osResource) + handleInterfaceUpdate(&updateOpts, resourceSpec, osResource) got, _ := needsUpdate(updateOpts) if got != tt.expectChange { @@ -87,27 +82,25 @@ func TestHandleNameUpdate(t *testing.T) { } } -func TestHandleDescriptionUpdate(t *testing.T) { - ptrToDescription := ptr.To[string] +func TestHandleURLUpdate(t *testing.T) { testCases := []struct { name string newValue *string existingValue string expectChange bool }{ - {name: "Identical", newValue: ptrToDescription("desc"), existingValue: "desc", expectChange: false}, - {name: "Different", newValue: ptrToDescription("new-desc"), existingValue: "desc", expectChange: true}, - {name: "No value provided, existing is set", newValue: nil, existingValue: "desc", expectChange: true}, - {name: "No value provided, existing is empty", newValue: nil, existingValue: "", expectChange: false}, + {name: "Identical", newValue: ptr.To("http://same.com"), existingValue: "http://same.com", expectChange: false}, + {name: "Different", newValue: ptr.To("http://different.com"), existingValue: "http://same.com", expectChange: true}, + {name: "No value provided, existing is kept", newValue: nil, existingValue: "http://same.com", expectChange: false}, } for _, tt := range testCases { t.Run(tt.name, func(t *testing.T) { - resource := &orcv1alpha1.EndpointResourceSpec{Description: tt.newValue} - osResource := &osResourceT{Description: tt.existingValue} + resourceSpec := &orcv1alpha1.EndpointResourceSpec{URL: ptr.Deref(tt.newValue, "")} + osResource := &osResourceT{URL: tt.existingValue} updateOpts := endpoints.UpdateOpts{} - handleDescriptionUpdate(&updateOpts, resource, osResource) + handleURLUpdate(&updateOpts, resourceSpec, osResource) got, _ := needsUpdate(updateOpts) if got != tt.expectChange { diff --git a/internal/controllers/endpoint/status.go b/internal/controllers/endpoint/status.go index e4e4a104f..22003bb8c 100644 --- a/internal/controllers/endpoint/status.go +++ b/internal/controllers/endpoint/status.go @@ -51,14 +51,10 @@ func (endpointStatusWriter) ResourceAvailableStatus(orcObject *orcv1alpha1.Endpo func (endpointStatusWriter) ApplyResourceStatus(log logr.Logger, osResource *osResourceT, statusApply *statusApplyT) { resourceStatus := orcapplyconfigv1alpha1.EndpointResourceStatus(). WithServiceID(osResource.ServiceID). + WithEnabled(osResource.Enabled). + WithInterface(string(osResource.Availability)). + WithURL(osResource.URL). WithName(osResource.Name) - // TODO(scaffolding): add all of the fields supported in the EndpointResourceStatus struct - // If a zero-value isn't expected in the response, place it behind a conditional - - if osResource.Description != "" { - resourceStatus.WithDescription(osResource.Description) - } - statusApply.WithResource(resourceStatus) } diff --git a/internal/controllers/endpoint/tests/endpoint-create-full/00-assert.yaml b/internal/controllers/endpoint/tests/endpoint-create-full/00-assert.yaml index 881c9a9f4..3507b634b 100644 --- a/internal/controllers/endpoint/tests/endpoint-create-full/00-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-create-full/00-assert.yaml @@ -6,8 +6,9 @@ metadata: status: resource: name: endpoint-create-full-override - description: Endpoint from "create full" test - # TODO(scaffolding): Add all fields the resource supports + interface: internal + url: https://example.com + #enabled: false conditions: - type: Available status: "True" @@ -30,4 +31,3 @@ resourceRefs: assertAll: - celExpr: "endpoint.status.id != ''" - celExpr: "endpoint.status.resource.serviceID == service.status.id" - # TODO(scaffolding): Add more checks diff --git a/internal/controllers/endpoint/tests/endpoint-create-full/00-create-resource.yaml b/internal/controllers/endpoint/tests/endpoint-create-full/00-create-resource.yaml index ee7772a11..d65438be4 100644 --- a/internal/controllers/endpoint/tests/endpoint-create-full/00-create-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-create-full/00-create-resource.yaml @@ -5,12 +5,11 @@ metadata: name: endpoint-create-full spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed - # TODO(scaffolding): Add the necessary fields to create the resource - resource: {} + resource: + type: endpoint-test --- apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Endpoint @@ -18,12 +17,14 @@ metadata: name: endpoint-create-full spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed resource: name: endpoint-create-full-override - description: Endpoint from "create full" test serviceRef: endpoint-create-full - # TODO(scaffolding): Add all fields the resource supports + interface: internal + url: https://example.com + # TODO(winiciusallan): make this field available after + # the next gophercloud minor. + #enabled: false diff --git a/internal/controllers/endpoint/tests/endpoint-create-minimal/00-assert.yaml b/internal/controllers/endpoint/tests/endpoint-create-minimal/00-assert.yaml index 76d25598b..28806601c 100644 --- a/internal/controllers/endpoint/tests/endpoint-create-minimal/00-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-create-minimal/00-assert.yaml @@ -6,7 +6,9 @@ metadata: status: resource: name: endpoint-create-minimal - # TODO(scaffolding): Add all fields the resource supports + url: http://example.com + interface: internal + enabled: true conditions: - type: Available status: "True" @@ -29,4 +31,3 @@ resourceRefs: assertAll: - celExpr: "endpoint.status.id != ''" - celExpr: "endpoint.status.resource.serviceID == service.status.id" - # TODO(scaffolding): Add more checks diff --git a/internal/controllers/endpoint/tests/endpoint-create-minimal/00-create-resource.yaml b/internal/controllers/endpoint/tests/endpoint-create-minimal/00-create-resource.yaml index 9087fb49d..48b59dc12 100644 --- a/internal/controllers/endpoint/tests/endpoint-create-minimal/00-create-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-create-minimal/00-create-resource.yaml @@ -5,12 +5,11 @@ metadata: name: endpoint-create-minimal spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed - # TODO(scaffolding): Add the necessary fields to create the resource - resource: {} + resource: + type: endpoint-test --- apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Endpoint @@ -18,11 +17,10 @@ metadata: name: endpoint-create-minimal spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed - # TODO(scaffolding): Only add the mandatory fields. It's possible the resource - # doesn't have mandatory fields, in that case, leave it empty. resource: - serviceRef: endpoint-create-full + serviceRef: endpoint-create-minimal + interface: internal + url: http://example.com diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/00-import-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/00-import-resource.yaml index 6a5c8737b..76cddcd65 100644 --- a/internal/controllers/endpoint/tests/endpoint-import-dependency/00-import-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/00-import-resource.yaml @@ -5,7 +5,7 @@ metadata: name: endpoint-import-dependency spec: cloudCredentialsRef: - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: unmanaged import: @@ -18,9 +18,11 @@ metadata: name: endpoint-import-dependency spec: cloudCredentialsRef: - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: unmanaged import: filter: serviceRef: endpoint-import-dependency + interface: internal + url: http://example.com diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/01-create-trap-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/01-create-trap-resource.yaml index 01f5e92f2..a7c71eceb 100644 --- a/internal/controllers/endpoint/tests/endpoint-import-dependency/01-create-trap-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/01-create-trap-resource.yaml @@ -5,25 +5,11 @@ metadata: name: endpoint-import-dependency-not-this-one spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed - # TODO(scaffolding): Add the necessary fields to create the resource - resource: {} ---- -apiVersion: openstack.k-orc.cloud/v1alpha1 -kind: Service -metadata: - name: endpoint-import-dependency-not-this-one -spec: - cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack - secretName: openstack-clouds - managementPolicy: managed - # TODO(scaffolding): Add the necessary fields to create the resource - resource: {} + resource: + type: endpoint-import-dependency-not-this-one --- # This `endpoint-import-dependency-not-this-one` should not be picked by the import filter apiVersion: openstack.k-orc.cloud/v1alpha1 @@ -32,11 +18,10 @@ metadata: name: endpoint-import-dependency-not-this-one spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed resource: serviceRef: endpoint-import-dependency-not-this-one - serviceRef: endpoint-import-dependency-not-this-one - # TODO(scaffolding): Add the necessary fields to create the resource + interface: internal + url: http://example.com diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/02-create-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/02-create-resource.yaml index 80e8511a5..65786fa03 100644 --- a/internal/controllers/endpoint/tests/endpoint-import-dependency/02-create-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/02-create-resource.yaml @@ -5,25 +5,11 @@ metadata: name: endpoint-import-dependency-external spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack - secretName: openstack-clouds - managementPolicy: managed - # TODO(scaffolding): Add the necessary fields to create the resource - resource: {} ---- -apiVersion: openstack.k-orc.cloud/v1alpha1 -kind: Service -metadata: - name: endpoint-import-dependency-external -spec: - cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed - # TODO(scaffolding): Add the necessary fields to create the resource - resource: {} + resource: + type: endpoint-import-dependency-external --- apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Endpoint @@ -31,11 +17,10 @@ metadata: name: endpoint-import-dependency-external spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed resource: serviceRef: endpoint-import-dependency-external - serviceRef: endpoint-import-dependency-external - # TODO(scaffolding): Add the necessary fields to create the resource + interface: internal + url: http://example.com diff --git a/internal/controllers/endpoint/tests/endpoint-import-dependency/03-delete-import-dependencies.yaml b/internal/controllers/endpoint/tests/endpoint-import-dependency/03-delete-import-dependencies.yaml index 744da0717..a102aa7e2 100644 --- a/internal/controllers/endpoint/tests/endpoint-import-dependency/03-delete-import-dependencies.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import-dependency/03-delete-import-dependencies.yaml @@ -3,5 +3,5 @@ apiVersion: kuttl.dev/v1beta1 kind: TestStep commands: # We should be able to delete the import dependencies - - command: kubectl delete service endpoint-import-dependency + - command: kubectl delete services.openstack.k-orc.cloud endpoint-import-dependency namespaced: true diff --git a/internal/controllers/endpoint/tests/endpoint-import-error/00-create-resources.yaml b/internal/controllers/endpoint/tests/endpoint-import-error/00-create-resources.yaml index 7e68b2f80..43afeab6f 100644 --- a/internal/controllers/endpoint/tests/endpoint-import-error/00-create-resources.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import-error/00-create-resources.yaml @@ -5,12 +5,11 @@ metadata: name: endpoint-import-error spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed - # TODO(scaffolding): Add the necessary fields to create the resource - resource: {} + resource: + type: endpoint-import-error --- apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Endpoint @@ -18,14 +17,13 @@ metadata: name: endpoint-import-error-external-1 spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed resource: - description: Endpoint from "import error" test serviceRef: endpoint-import-error - # TODO(scaffolding): add any required field + interface: internal + url: http://example1.com --- apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Endpoint @@ -33,11 +31,10 @@ metadata: name: endpoint-import-error-external-2 spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed resource: - description: Endpoint from "import error" test serviceRef: endpoint-import-error - # TODO(scaffolding): add any required field + interface: internal + url: http://example2.com diff --git a/internal/controllers/endpoint/tests/endpoint-import-error/01-import-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import-error/01-import-resource.yaml index df0e2d3a9..0b106e2cd 100644 --- a/internal/controllers/endpoint/tests/endpoint-import-error/01-import-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import-error/01-import-resource.yaml @@ -5,9 +5,10 @@ metadata: name: endpoint-import-error spec: cloudCredentialsRef: - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: unmanaged import: filter: - description: Endpoint from "import error" test + serviceRef: endpoint-import-error + interface: internal diff --git a/internal/controllers/endpoint/tests/endpoint-import/00-import-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import/00-import-resource.yaml index cdfda600d..df38e9315 100644 --- a/internal/controllers/endpoint/tests/endpoint-import/00-import-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import/00-import-resource.yaml @@ -1,15 +1,27 @@ --- apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Service +metadata: + name: endpoint-import +spec: + cloudCredentialsRef: + cloudName: openstack-admin + secretName: openstack-clouds + managementPolicy: managed + resource: + type: endpoint-import +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Endpoint metadata: name: endpoint-import spec: cloudCredentialsRef: - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: unmanaged import: filter: - name: endpoint-import-external - description: Endpoint endpoint-import-external from "endpoint-import" test - # TODO(scaffolding): Add all fields supported by the filter + serviceRef: endpoint-import + interface: internal + url: http://example.com diff --git a/internal/controllers/endpoint/tests/endpoint-import/01-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import/01-assert.yaml index 63a67bdbd..9d6a646c4 100644 --- a/internal/controllers/endpoint/tests/endpoint-import/01-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import/01-assert.yaml @@ -15,8 +15,8 @@ status: reason: Success resource: name: endpoint-import-external-not-this-one - description: Endpoint endpoint-import-external from "endpoint-import" test - # TODO(scaffolding): Add fields necessary to match filter + interface: internal + url: http://example.com --- apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Endpoint diff --git a/internal/controllers/endpoint/tests/endpoint-import/01-create-trap-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import/01-create-trap-resource.yaml index 036efd781..2e41c1cff 100644 --- a/internal/controllers/endpoint/tests/endpoint-import/01-create-trap-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import/01-create-trap-resource.yaml @@ -5,12 +5,11 @@ metadata: name: endpoint-import-external-not-this-one spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed - # TODO(scaffolding): Add the necessary fields to create the resource - resource: {} + resource: + type: endpoint-import-external-not-this-one --- # This `endpoint-import-external-not-this-one` resource serves two purposes: # - ensure that we can successfully create another resource which name is a substring of it (i.e. it's not being adopted) @@ -21,11 +20,11 @@ metadata: name: endpoint-import-external-not-this-one spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed resource: - description: Endpoint endpoint-import-external from "endpoint-import" test serviceRef: endpoint-import-external-not-this-one - # TODO(scaffolding): Add fields necessary to match filter + interface: internal + url: http://example.com + diff --git a/internal/controllers/endpoint/tests/endpoint-import/02-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import/02-assert.yaml index b3c7c0b04..a66d66a46 100644 --- a/internal/controllers/endpoint/tests/endpoint-import/02-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import/02-assert.yaml @@ -10,6 +10,10 @@ resourceRefs: kind: Endpoint name: endpoint-import-external-not-this-one ref: endpoint2 + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Service + name: endpoint-import + ref: service assertAll: - celExpr: "endpoint1.status.id != endpoint2.status.id" --- @@ -29,5 +33,6 @@ status: reason: Success resource: name: endpoint-import-external - description: Endpoint endpoint-import-external from "endpoint-import" test - # TODO(scaffolding): Add all fields the resource supports + interface: internal + url: http://example.com + #enabled: true diff --git a/internal/controllers/endpoint/tests/endpoint-import/02-create-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import/02-create-resource.yaml index 5e17eec59..5b67ce9d5 100644 --- a/internal/controllers/endpoint/tests/endpoint-import/02-create-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import/02-create-resource.yaml @@ -1,28 +1,14 @@ --- apiVersion: openstack.k-orc.cloud/v1alpha1 -kind: Service -metadata: - name: endpoint-import -spec: - cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack - secretName: openstack-clouds - managementPolicy: managed - # TODO(scaffolding): Add the necessary fields to create the resource - resource: {} ---- -apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Endpoint metadata: name: endpoint-import-external spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed resource: - description: Endpoint endpoint-import-external from "endpoint-import" test serviceRef: endpoint-import - # TODO(scaffolding): Add fields necessary to match filter + interface: internal + url: http://example.com diff --git a/internal/controllers/endpoint/tests/endpoint-update/00-assert.yaml b/internal/controllers/endpoint/tests/endpoint-update/00-assert.yaml index 49cc482c0..76532138b 100644 --- a/internal/controllers/endpoint/tests/endpoint-update/00-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-update/00-assert.yaml @@ -1,14 +1,4 @@ --- -apiVersion: kuttl.dev/v1beta1 -kind: TestAssert -resourceRefs: - - apiVersion: openstack.k-orc.cloud/v1alpha1 - kind: Endpoint - name: endpoint-update - ref: endpoint -assertAll: - - celExpr: "!has(endpoint.status.resource.description)" ---- apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Endpoint metadata: @@ -16,7 +6,9 @@ metadata: status: resource: name: endpoint-update - # TODO(scaffolding): Add matches for more fields + interface: internal + url: http://example.com + enabled: true conditions: - type: Available status: "True" @@ -24,3 +16,17 @@ status: - type: Progressing status: "False" reason: Success +--- +apiVersion: kuttl.dev/v1beta1 +kind: TestAssert +resourceRefs: + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Endpoint + name: endpoint-update + ref: endpoint + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Service + name: endpoint-update + ref: service +assertAll: + - celExpr: "endpoint.status.resource.serviceID == service.status.id" diff --git a/internal/controllers/endpoint/tests/endpoint-update/00-minimal-resource.yaml b/internal/controllers/endpoint/tests/endpoint-update/00-minimal-resource.yaml index d846d67fb..cfa64972e 100644 --- a/internal/controllers/endpoint/tests/endpoint-update/00-minimal-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-update/00-minimal-resource.yaml @@ -5,12 +5,11 @@ metadata: name: endpoint-update spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed - # TODO(scaffolding): Add the necessary fields to create the resource - resource: {} + resource: + type: endpoint-test-update --- apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Endpoint @@ -18,11 +17,10 @@ metadata: name: endpoint-update spec: cloudCredentialsRef: - # TODO(scaffolding): Use openstack-admin if the resouce needs admin credentials to be created or updated - cloudName: openstack + cloudName: openstack-admin secretName: openstack-clouds managementPolicy: managed - # TODO(scaffolding): Only add the mandatory fields. It's possible the resource - # doesn't have mandatory fields, in that case, leave it empty. resource: serviceRef: endpoint-update + interface: internal + url: http://example.com diff --git a/internal/controllers/endpoint/tests/endpoint-update/01-assert.yaml b/internal/controllers/endpoint/tests/endpoint-update/01-assert.yaml index e526907c7..94ced3887 100644 --- a/internal/controllers/endpoint/tests/endpoint-update/01-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-update/01-assert.yaml @@ -6,8 +6,9 @@ metadata: status: resource: name: endpoint-update-updated - description: endpoint-update-updated - # TODO(scaffolding): match all fields that were modified + interface: public + url: http://example.com/updated + #enabled: true conditions: - type: Available status: "True" diff --git a/internal/controllers/endpoint/tests/endpoint-update/01-updated-resource.yaml b/internal/controllers/endpoint/tests/endpoint-update/01-updated-resource.yaml index ea78d64af..bd1374ea5 100644 --- a/internal/controllers/endpoint/tests/endpoint-update/01-updated-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-update/01-updated-resource.yaml @@ -6,5 +6,8 @@ metadata: spec: resource: name: endpoint-update-updated - description: endpoint-update-updated - # TODO(scaffolding): update all mutable fields + interface: public + url: http://example.com/updated + # TODO(winiciusallan): change it later. + #enabled: true + diff --git a/internal/controllers/endpoint/tests/endpoint-update/02-assert.yaml b/internal/controllers/endpoint/tests/endpoint-update/02-assert.yaml index c3e8f879e..64ee33bd4 100644 --- a/internal/controllers/endpoint/tests/endpoint-update/02-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-update/02-assert.yaml @@ -6,8 +6,12 @@ resourceRefs: kind: Endpoint name: endpoint-update ref: endpoint + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: Service + name: endpoint-update + ref: service assertAll: - - celExpr: "!has(endpoint.status.resource.description)" + - celExpr: "endpoint.status.resource.serviceID == service.status.id" --- apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Endpoint @@ -16,7 +20,9 @@ metadata: status: resource: name: endpoint-update - # TODO(scaffolding): validate that updated fields were all reverted to their original value + interface: internal + url: http://example.com + #enabled: true conditions: - type: Available status: "True" diff --git a/internal/controllers/service/actuator_test.go b/internal/controllers/service/actuator_test.go index 980cd269f..0980a53cf 100644 --- a/internal/controllers/service/actuator_test.go +++ b/internal/controllers/service/actuator_test.go @@ -146,7 +146,7 @@ func TestHandleDescriptionUpdate(t *testing.T) { }{ {name: "Identical", newValue: ptr.To("same-description"), existingValue: "same-description", expectChange: false}, {name: "Different", newValue: ptr.To("new-description"), existingValue: "same-description", expectChange: true}, - {name: "No value provided, existing is set", newValue: nil, existingValue: "description", expectChange: true}, + {name: "No value provided, existing is keept", newValue: nil, existingValue: "description", expectChange: true}, } for _, tt := range testCases { diff --git a/internal/osclients/mock/doc.go b/internal/osclients/mock/doc.go index 47292b65f..84971e17a 100644 --- a/internal/osclients/mock/doc.go +++ b/internal/osclients/mock/doc.go @@ -38,6 +38,9 @@ import ( //go:generate mockgen -package mock -destination=domain.go -source=../domain.go github.com/k-orc/openstack-resource-controller/internal/osclients/mock DomainClient //go:generate /usr/bin/env bash -c "cat ../../../hack/boilerplate.go.txt domain.go > _domain.go && mv _domain.go domain.go" +//go:generate mockgen -package mock -destination=endpoint.go -source=../endpoint.go github.com/k-orc/openstack-resource-controller/internal/osclients/mock EndpointClient +//go:generate /usr/bin/env bash -c "cat ../../../hack/boilerplate.go.txt endpoint.go > _endpoint.go && mv _endpoint.go endpoint.go" + //go:generate mockgen -package mock -destination=group.go -source=../group.go github.com/k-orc/openstack-resource-controller/internal/osclients/mock GroupClient //go:generate /usr/bin/env bash -c "cat ../../../hack/boilerplate.go.txt group.go > _group.go && mv _group.go group.go" diff --git a/internal/scope/mock.go b/internal/scope/mock.go index ef959fae5..9cc49cd03 100644 --- a/internal/scope/mock.go +++ b/internal/scope/mock.go @@ -36,6 +36,7 @@ import ( type MockScopeFactory struct { ComputeClient *mock.MockComputeClient DomainClient *mock.MockDomainClient + EndpointClient *mock.MockEndpointClient GroupClient *mock.MockGroupClient IdentityClient *mock.MockIdentityClient ImageClient *mock.MockImageClient @@ -52,6 +53,7 @@ type MockScopeFactory struct { func NewMockScopeFactory(mockCtrl *gomock.Controller) *MockScopeFactory { computeClient := mock.NewMockComputeClient(mockCtrl) domainClient := mock.NewMockDomainClient(mockCtrl) + endpointClient := mock.NewMockEndpointClient(mockCtrl) groupClient := mock.NewMockGroupClient(mockCtrl) identityClient := mock.NewMockIdentityClient(mockCtrl) imageClient := mock.NewMockImageClient(mockCtrl) @@ -65,6 +67,7 @@ func NewMockScopeFactory(mockCtrl *gomock.Controller) *MockScopeFactory { return &MockScopeFactory{ ComputeClient: computeClient, DomainClient: domainClient, + EndpointClient: endpointClient, GroupClient: groupClient, IdentityClient: identityClient, ImageClient: imageClient, @@ -132,6 +135,10 @@ func (f *MockScopeFactory) NewRoleClient() (osclients.RoleClient, error) { return f.RoleClient, nil } +func (f *MockScopeFactory) NewEndpointClient() (osclients.EndpointClient, error) { + return f.EndpointClient, nil +} + func (f *MockScopeFactory) ExtractToken() (*tokens.Token, error) { return &tokens.Token{ExpiresAt: time.Now().Add(24 * time.Hour)}, nil } diff --git a/internal/scope/provider.go b/internal/scope/provider.go index 65670ba60..d9853e381 100644 --- a/internal/scope/provider.go +++ b/internal/scope/provider.go @@ -169,6 +169,10 @@ func (s *providerScope) NewServiceClient() (clients.ServiceClient, error) { return clients.NewServiceClient(s.providerClient, s.providerClientOpts) } +func (s *providerScope) NewEndpointClient() (clients.EndpointClient, error) { + return clients.NewEndpointClient(s.providerClient, s.providerClientOpts) +} + func (s *providerScope) NewKeyPairClient() (clients.KeyPairClient, error) { return clients.NewKeyPairClient(s.providerClient, s.providerClientOpts) } diff --git a/internal/scope/scope.go b/internal/scope/scope.go index 7da50dc8f..8baa7f404 100644 --- a/internal/scope/scope.go +++ b/internal/scope/scope.go @@ -50,6 +50,7 @@ type Factory interface { type Scope interface { NewComputeClient() (osclients.ComputeClient, error) NewDomainClient() (osclients.DomainClient, error) + NewEndpointClient() (osclients.EndpointClient, error) NewGroupClient() (osclients.GroupClient, error) NewIdentityClient() (osclients.IdentityClient, error) NewImageClient() (osclients.ImageClient, error) diff --git a/kuttl-test.yaml b/kuttl-test.yaml index d499782e6..9f74099f0 100644 --- a/kuttl-test.yaml +++ b/kuttl-test.yaml @@ -3,6 +3,7 @@ apiVersion: kuttl.dev/v1beta1 kind: TestSuite testDirs: - ./internal/controllers/domain/tests/ +- ./internal/controllers/endpoint/tests/ - ./internal/controllers/flavor/tests/ - ./internal/controllers/floatingip/tests/ - ./internal/controllers/group/tests/ diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointfilter.go index 0908e2c55..3cf7c6000 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/endpointfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointfilter.go @@ -25,8 +25,8 @@ import ( // EndpointFilterApplyConfiguration represents a declarative configuration of the EndpointFilter type for use // with apply. type EndpointFilterApplyConfiguration struct { - ServiceRef *apiv1alpha1.KubernetesNameRef `json:"serviceRef,omitempty"` Interface *string `json:"interface,omitempty"` + ServiceRef *apiv1alpha1.KubernetesNameRef `json:"serviceRef,omitempty"` URL *string `json:"url,omitempty"` } @@ -36,14 +36,6 @@ func EndpointFilter() *EndpointFilterApplyConfiguration { return &EndpointFilterApplyConfiguration{} } -// WithServiceRef sets the ServiceRef field in the declarative configuration to the given value -// and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the ServiceRef field is set to the value of the last call. -func (b *EndpointFilterApplyConfiguration) WithServiceRef(value apiv1alpha1.KubernetesNameRef) *EndpointFilterApplyConfiguration { - b.ServiceRef = &value - return b -} - // WithInterface sets the Interface field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the Interface field is set to the value of the last call. @@ -52,6 +44,14 @@ func (b *EndpointFilterApplyConfiguration) WithInterface(value string) *Endpoint return b } +// WithServiceRef sets the ServiceRef field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ServiceRef field is set to the value of the last call. +func (b *EndpointFilterApplyConfiguration) WithServiceRef(value apiv1alpha1.KubernetesNameRef) *EndpointFilterApplyConfiguration { + b.ServiceRef = &value + return b +} + // WithURL sets the URL field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the URL field is set to the value of the last call. diff --git a/pkg/clients/applyconfiguration/internal/internal.go b/pkg/clients/applyconfiguration/internal/internal.go index 92ad4e797..4cd388895 100644 --- a/pkg/clients/applyconfiguration/internal/internal.go +++ b/pkg/clients/applyconfiguration/internal/internal.go @@ -192,6 +192,121 @@ var schemaYAML = typed.YAMLObject(`types: - name: resource type: namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.DomainResourceStatus +- name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.Endpoint + map: + fields: + - name: apiVersion + type: + scalar: string + - name: kind + type: + scalar: string + - name: metadata + type: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta + default: {} + - name: spec + type: + namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointSpec + default: {} + - name: status + type: + namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointStatus + default: {} +- name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointFilter + map: + fields: + - name: interface + type: + scalar: string + - name: serviceRef + type: + scalar: string + - name: url + type: + scalar: string +- name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointImport + map: + fields: + - name: filter + type: + namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointFilter + - name: id + type: + scalar: string +- name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointResourceSpec + map: + fields: + - name: enabled + type: + scalar: boolean + - name: interface + type: + scalar: string + - name: name + type: + scalar: string + - name: serviceRef + type: + scalar: string + - name: url + type: + scalar: string + default: "" +- name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointResourceStatus + map: + fields: + - name: enabled + type: + scalar: boolean + - name: interface + type: + scalar: string + - name: name + type: + scalar: string + - name: serviceID + type: + scalar: string + - name: url + type: + scalar: string +- name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointSpec + map: + fields: + - name: cloudCredentialsRef + type: + namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.CloudCredentialsReference + default: {} + - name: import + type: + namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointImport + - name: managedOptions + type: + namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.ManagedOptions + - name: managementPolicy + type: + scalar: string + - name: resource + type: + namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointResourceSpec +- name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointStatus + map: + fields: + - name: conditions + type: + list: + elementType: + namedType: io.k8s.apimachinery.pkg.apis.meta.v1.Condition + elementRelationship: associative + keys: + - type + - name: id + type: + scalar: string + - name: resource + type: + namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointResourceStatus - name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.ExternalGateway map: fields: diff --git a/pkg/clients/applyconfiguration/utils.go b/pkg/clients/applyconfiguration/utils.go index e3166fefe..ed751fc92 100644 --- a/pkg/clients/applyconfiguration/utils.go +++ b/pkg/clients/applyconfiguration/utils.go @@ -58,6 +58,20 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &apiv1alpha1.DomainSpecApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("DomainStatus"): return &apiv1alpha1.DomainStatusApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("Endpoint"): + return &apiv1alpha1.EndpointApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("EndpointFilter"): + return &apiv1alpha1.EndpointFilterApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("EndpointImport"): + return &apiv1alpha1.EndpointImportApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("EndpointResourceSpec"): + return &apiv1alpha1.EndpointResourceSpecApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("EndpointResourceStatus"): + return &apiv1alpha1.EndpointResourceStatusApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("EndpointSpec"): + return &apiv1alpha1.EndpointSpecApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("EndpointStatus"): + return &apiv1alpha1.EndpointStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("ExternalGateway"): return &apiv1alpha1.ExternalGatewayApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("ExternalGatewayStatus"): diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/api_client.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/api_client.go index 4d2f93b0d..09c39d525 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/api_client.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/api_client.go @@ -29,6 +29,7 @@ import ( type OpenstackV1alpha1Interface interface { RESTClient() rest.Interface DomainsGetter + EndpointsGetter FlavorsGetter FloatingIPsGetter GroupsGetter @@ -58,6 +59,10 @@ func (c *OpenstackV1alpha1Client) Domains(namespace string) DomainInterface { return newDomains(c, namespace) } +func (c *OpenstackV1alpha1Client) Endpoints(namespace string) EndpointInterface { + return newEndpoints(c, namespace) +} + func (c *OpenstackV1alpha1Client) Flavors(namespace string) FlavorInterface { return newFlavors(c, namespace) } diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_api_client.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_api_client.go index 44feeb45c..dfe83cdee 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_api_client.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_api_client.go @@ -32,6 +32,10 @@ func (c *FakeOpenstackV1alpha1) Domains(namespace string) v1alpha1.DomainInterfa return newFakeDomains(c, namespace) } +func (c *FakeOpenstackV1alpha1) Endpoints(namespace string) v1alpha1.EndpointInterface { + return newFakeEndpoints(c, namespace) +} + func (c *FakeOpenstackV1alpha1) Flavors(namespace string) v1alpha1.FlavorInterface { return newFakeFlavors(c, namespace) } diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/generated_expansion.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/generated_expansion.go index 56550a99f..a2aff2eff 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/generated_expansion.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/generated_expansion.go @@ -20,6 +20,8 @@ package v1alpha1 type DomainExpansion interface{} +type EndpointExpansion interface{} + type FlavorExpansion interface{} type FloatingIPExpansion interface{} diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/interface.go b/pkg/clients/informers/externalversions/api/v1alpha1/interface.go index 1b4497815..801c38e89 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/interface.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/interface.go @@ -26,6 +26,8 @@ import ( type Interface interface { // Domains returns a DomainInformer. Domains() DomainInformer + // Endpoints returns a EndpointInformer. + Endpoints() EndpointInformer // Flavors returns a FlavorInformer. Flavors() FlavorInformer // FloatingIPs returns a FloatingIPInformer. @@ -80,6 +82,11 @@ func (v *version) Domains() DomainInformer { return &domainInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } +// Endpoints returns a EndpointInformer. +func (v *version) Endpoints() EndpointInformer { + return &endpointInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // Flavors returns a FlavorInformer. func (v *version) Flavors() FlavorInformer { return &flavorInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/pkg/clients/informers/externalversions/generic.go b/pkg/clients/informers/externalversions/generic.go index 30911d11f..1ad4042c4 100644 --- a/pkg/clients/informers/externalversions/generic.go +++ b/pkg/clients/informers/externalversions/generic.go @@ -55,6 +55,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource // Group=openstack.k-orc.cloud, Version=v1alpha1 case v1alpha1.SchemeGroupVersion.WithResource("domains"): return &genericInformer{resource: resource.GroupResource(), informer: f.Openstack().V1alpha1().Domains().Informer()}, nil + case v1alpha1.SchemeGroupVersion.WithResource("endpoints"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Openstack().V1alpha1().Endpoints().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("flavors"): return &genericInformer{resource: resource.GroupResource(), informer: f.Openstack().V1alpha1().Flavors().Informer()}, nil case v1alpha1.SchemeGroupVersion.WithResource("floatingips"): diff --git a/pkg/clients/listers/api/v1alpha1/expansion_generated.go b/pkg/clients/listers/api/v1alpha1/expansion_generated.go index ba2888731..357c7d560 100644 --- a/pkg/clients/listers/api/v1alpha1/expansion_generated.go +++ b/pkg/clients/listers/api/v1alpha1/expansion_generated.go @@ -26,6 +26,14 @@ type DomainListerExpansion interface{} // DomainNamespaceLister. type DomainNamespaceListerExpansion interface{} +// EndpointListerExpansion allows custom methods to be added to +// EndpointLister. +type EndpointListerExpansion interface{} + +// EndpointNamespaceListerExpansion allows custom methods to be added to +// EndpointNamespaceLister. +type EndpointNamespaceListerExpansion interface{} + // FlavorListerExpansion allows custom methods to be added to // FlavorLister. type FlavorListerExpansion interface{} diff --git a/website/docs/crd-reference.md b/website/docs/crd-reference.md index 36f357a3c..131d2a64d 100644 --- a/website/docs/crd-reference.md +++ b/website/docs/crd-reference.md @@ -11,6 +11,7 @@ Package v1alpha1 contains API Schema definitions for the openstack v1alpha1 API ### Resource Types - [Domain](#domain) +- [Endpoint](#endpoint) - [Flavor](#flavor) - [FloatingIP](#floatingip) - [Group](#group) @@ -164,6 +165,7 @@ CloudCredentialsReference is a reference to a secret containing OpenStack creden _Appears in:_ - [DomainSpec](#domainspec) +- [EndpointSpec](#endpointspec) - [FlavorSpec](#flavorspec) - [FloatingIPSpec](#floatingipspec) - [GroupSpec](#groupspec) @@ -335,6 +337,142 @@ _Appears in:_ | `resource` _[DomainResourceStatus](#domainresourcestatus)_ | resource contains the observed state of the OpenStack resource. | | | +#### Endpoint + + + +Endpoint is the Schema for an ORC resource. + + + + + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `apiVersion` _string_ | `openstack.k-orc.cloud/v1alpha1` | | | +| `kind` _string_ | `Endpoint` | | | +| `metadata` _[ObjectMeta](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#objectmeta-v1-meta)_ | Refer to Kubernetes API documentation for fields of `metadata`. | | | +| `spec` _[EndpointSpec](#endpointspec)_ | spec specifies the desired state of the resource. | | | +| `status` _[EndpointStatus](#endpointstatus)_ | status defines the observed state of the resource. | | | + + +#### EndpointFilter + + + +EndpointFilter defines an existing resource by its properties + +_Validation:_ +- MinProperties: 1 + +_Appears in:_ +- [EndpointImport](#endpointimport) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `interface` _string_ | interface of the existing endpoint. | | Enum: [admin internal public]
| +| `serviceRef` _[KubernetesNameRef](#kubernetesnameref)_ | serviceRef is a reference to the ORC Service which this resource is associated with. | | MaxLength: 253
MinLength: 1
| +| `url` _string_ | url is the URL of the existing endpoint. | | MaxLength: 1024
| + + +#### EndpointImport + + + +EndpointImport specifies an existing resource which will be imported instead of +creating a new one + +_Validation:_ +- MaxProperties: 1 +- MinProperties: 1 + +_Appears in:_ +- [EndpointSpec](#endpointspec) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `id` _string_ | id contains the unique identifier of an existing OpenStack resource. Note
that when specifying an import by ID, the resource MUST already exist.
The ORC object will enter an error state if the resource does not exist. | | Format: uuid
| +| `filter` _[EndpointFilter](#endpointfilter)_ | filter contains a resource query which is expected to return a single
result. The controller will continue to retry if filter returns no
results. If filter returns multiple results the controller will set an
error state and will not continue to retry. | | MinProperties: 1
| + + +#### EndpointResourceSpec + + + +EndpointResourceSpec contains the desired state of the resource. + + + +_Appears in:_ +- [EndpointSpec](#endpointspec) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `name` _[OpenStackName](#openstackname)_ | name will be the name of the created resource. If not specified, the
name of the ORC object will be used. | | MaxLength: 255
MinLength: 1
Pattern: `^[^,]+$`
| +| `enabled` _boolean_ | enabled indicates whether the endpoint is enabled or not. | true | | +| `interface` _string_ | interface indicates the visibility of the endpoint. | | Enum: [admin internal public]
| +| `url` _string_ | url is the endpoint URL. | | MaxLength: 1024
| +| `serviceRef` _[KubernetesNameRef](#kubernetesnameref)_ | serviceRef is a reference to the ORC Service which this resource is associated with. | | MaxLength: 253
MinLength: 1
| + + +#### EndpointResourceStatus + + + +EndpointResourceStatus represents the observed state of the resource. + + + +_Appears in:_ +- [EndpointStatus](#endpointstatus) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `name` _string_ | name is a Human-readable name for the resource. Might not be unique. | | MaxLength: 1024
| +| `enabled` _boolean_ | enabled indicates whether the endpoint is enabled or not. | | | +| `interface` _string_ | interface indicates the visibility of the endpoint. | | Enum: [admin internal public]
| +| `url` _string_ | url is the endpoint URL. | | MaxLength: 1024
| +| `serviceID` _string_ | serviceID is the ID of the Service to which the resource is associated. | | MaxLength: 1024
| + + +#### EndpointSpec + + + +EndpointSpec defines the desired state of an ORC object. + + + +_Appears in:_ +- [Endpoint](#endpoint) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `import` _[EndpointImport](#endpointimport)_ | import refers to an existing OpenStack resource which will be imported instead of
creating a new one. | | MaxProperties: 1
MinProperties: 1
| +| `resource` _[EndpointResourceSpec](#endpointresourcespec)_ | resource specifies the desired state of the resource.
resource may not be specified if the management policy is `unmanaged`.
resource must be specified if the management policy is `managed`. | | | +| `managementPolicy` _[ManagementPolicy](#managementpolicy)_ | managementPolicy defines how ORC will treat the object. Valid values are
`managed`: ORC will create, update, and delete the resource; `unmanaged`:
ORC will import an existing resource, and will not apply updates to it or
delete it. | managed | Enum: [managed unmanaged]
| +| `managedOptions` _[ManagedOptions](#managedoptions)_ | managedOptions specifies options which may be applied to managed objects. | | | +| `cloudCredentialsRef` _[CloudCredentialsReference](#cloudcredentialsreference)_ | cloudCredentialsRef points to a secret containing OpenStack credentials | | | + + +#### EndpointStatus + + + +EndpointStatus defines the observed state of an ORC resource. + + + +_Appears in:_ +- [Endpoint](#endpoint) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `conditions` _[Condition](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#condition-v1-meta) array_ | conditions represents the observed status of the object.
Known .status.conditions.type are: "Available", "Progressing"
Available represents the availability of the OpenStack resource. If it is
true then the resource is ready for use.
Progressing indicates whether the controller is still attempting to
reconcile the current state of the OpenStack resource to the desired
state. Progressing will be False either because the desired state has
been achieved, or because some terminal error prevents it from ever being
achieved and the controller is no longer attempting to reconcile. If
Progressing is True, an observer waiting on the resource should continue
to wait. | | MaxItems: 32
| +| `id` _string_ | id is the unique identifier of the OpenStack resource. | | | +| `resource` _[EndpointResourceStatus](#endpointresourcestatus)_ | resource contains the observed state of the OpenStack resource. | | | + + #### Ethertype _Underlying type:_ _string_ @@ -1611,6 +1749,8 @@ _Validation:_ _Appears in:_ - [Address](#address) +- [EndpointFilter](#endpointfilter) +- [EndpointResourceSpec](#endpointresourcespec) - [ExternalGateway](#externalgateway) - [FloatingIPFilter](#floatingipfilter) - [FloatingIPResourceSpec](#floatingipresourcespec) @@ -1677,6 +1817,7 @@ _Appears in:_ _Appears in:_ - [DomainSpec](#domainspec) +- [EndpointSpec](#endpointspec) - [FlavorSpec](#flavorspec) - [FloatingIPSpec](#floatingipspec) - [GroupSpec](#groupspec) @@ -1711,6 +1852,7 @@ _Validation:_ _Appears in:_ - [DomainSpec](#domainspec) +- [EndpointSpec](#endpointspec) - [FlavorSpec](#flavorspec) - [FloatingIPSpec](#floatingipspec) - [GroupSpec](#groupspec) @@ -2003,6 +2145,7 @@ _Validation:_ - Pattern: `^[^,]+$` _Appears in:_ +- [EndpointResourceSpec](#endpointresourcespec) - [FlavorFilter](#flavorfilter) - [FlavorResourceSpec](#flavorresourcespec) - [ImageFilter](#imagefilter) From afefbc4e7c7f041d7358d36bb725384381777f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Wed, 17 Dec 2025 16:45:49 +0100 Subject: [PATCH 3/9] README: fix broken link to dev docs Also add redirects for pages we moved to that we don't break bookmarks. --- README.md | 2 +- website/mkdocs.yml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index dd158f75a..93119e063 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ We welcome contributions of all kinds! Whether you’re fixing bugs, adding new * Fork the repository. * Create a new branch for your changes. * Setup a [local development environment](https://k-orc.cloud/development/quickstart/). -* Read the [developers guide](https://k-orc.cloud/development/). +* Read the [developers guide](https://k-orc.cloud/development/overview/). * Make your changes and test thoroughly. * Submit a pull request with a clear description of your changes. diff --git a/website/mkdocs.yml b/website/mkdocs.yml index aefff1439..e71fbe9e9 100644 --- a/website/mkdocs.yml +++ b/website/mkdocs.yml @@ -62,6 +62,11 @@ plugins: - redirects: redirect_maps: 'getting_started.md': 'getting-started.md' + 'development/index.md': 'development/overview.md' + 'development/controller-design.md': 'development/controller-implementation.md' + 'development/design-decisions.md': 'development/architecture.md' + 'development/coding-convention.md': 'development/coding-standards.md' + 'development/api-contracts.md': 'development/api-design.md' markdown_extensions: - admonition - attr_list From f79aa050827d4a06705d79fb088616fd26e20b29 Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Wed, 17 Dec 2025 16:54:25 -0300 Subject: [PATCH 4/9] port: add adminStateUp field Signed-off-by: Winicius Silva --- api/v1alpha1/port_types.go | 11 ++++++ api/v1alpha1/zz_generated.deepcopy.go | 10 ++++++ cmd/models-schema/zz_generated.openapi.go | 14 ++++++++ .../bases/openstack.k-orc.cloud_ports.yaml | 11 ++++++ internal/controllers/port/actuator.go | 36 ++++++++++++------- internal/controllers/port/actuator_test.go | 28 +++++++++++++++ internal/controllers/port/status.go | 3 +- .../tests/port-create-full/00-assert.yaml | 2 +- .../port-create-full/00-create-resource.yaml | 1 + .../tests/port-import/00-import-resource.yaml | 1 + .../port-import/01-create-trap-resource.yaml | 1 + .../port/tests/port-import/02-assert.yaml | 1 + .../tests/port-import/02-create-resource.yaml | 1 + .../api/v1alpha1/portfilter.go | 9 +++++ .../api/v1alpha1/portresourcespec.go | 9 +++++ .../applyconfiguration/internal/internal.go | 6 ++++ website/docs/crd-reference.md | 2 ++ 17 files changed, 132 insertions(+), 14 deletions(-) diff --git a/api/v1alpha1/port_types.go b/api/v1alpha1/port_types.go index 0c3594ac5..868748c17 100644 --- a/api/v1alpha1/port_types.go +++ b/api/v1alpha1/port_types.go @@ -36,6 +36,11 @@ type PortFilter struct { // +optional ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"` + // adminStateUp is the administrative state of the port, + // which is up (true) or down (false). + // +optional + AdminStateUp *bool `json:"adminStateUp,omitempty"` + FilterByNeutronTags `json:",inline"` } @@ -126,6 +131,12 @@ type PortResourceSpec struct { // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="addresses is immutable" Addresses []Address `json:"addresses,omitempty"` + // adminStateUp is the administrative state of the port, + // which is up (true) or down (false). The default value is true. + // +kubebuilder:default:=true + // +optional + AdminStateUp *bool `json:"adminStateUp,omitempty"` + // securityGroupRefs are the names of the security groups associated // with this port. // +kubebuilder:validation:MaxItems:=64 diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 0d8d337e9..a73d4ff57 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -2589,6 +2589,11 @@ func (in *PortFilter) DeepCopyInto(out *PortFilter) { *out = new(KubernetesNameRef) **out = **in } + if in.AdminStateUp != nil { + in, out := &in.AdminStateUp, &out.AdminStateUp + *out = new(bool) + **out = **in + } in.FilterByNeutronTags.DeepCopyInto(&out.FilterByNeutronTags) } @@ -2721,6 +2726,11 @@ func (in *PortResourceSpec) DeepCopyInto(out *PortResourceSpec) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.AdminStateUp != nil { + in, out := &in.AdminStateUp, &out.AdminStateUp + *out = new(bool) + **out = **in + } if in.SecurityGroupRefs != nil { in, out := &in.SecurityGroupRefs, &out.SecurityGroupRefs *out = make([]OpenStackName, len(*in)) diff --git a/cmd/models-schema/zz_generated.openapi.go b/cmd/models-schema/zz_generated.openapi.go index 9799c6d2e..6ffa5e66b 100644 --- a/cmd/models-schema/zz_generated.openapi.go +++ b/cmd/models-schema/zz_generated.openapi.go @@ -4902,6 +4902,13 @@ func schema_openstack_resource_controller_v2_api_v1alpha1_PortFilter(ref common. Format: "", }, }, + "adminStateUp": { + SchemaProps: spec.SchemaProps{ + Description: "adminStateUp is the administrative state of the port, which is up (true) or down (false).", + Type: []string{"boolean"}, + Format: "", + }, + }, "tags": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ @@ -5209,6 +5216,13 @@ func schema_openstack_resource_controller_v2_api_v1alpha1_PortResourceSpec(ref c }, }, }, + "adminStateUp": { + SchemaProps: spec.SchemaProps{ + Description: "adminStateUp is the administrative state of the port, which is up (true) or down (false). The default value is true.", + Type: []string{"boolean"}, + Format: "", + }, + }, "securityGroupRefs": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ diff --git a/config/crd/bases/openstack.k-orc.cloud_ports.yaml b/config/crd/bases/openstack.k-orc.cloud_ports.yaml index 985ed8683..64c66bbf5 100644 --- a/config/crd/bases/openstack.k-orc.cloud_ports.yaml +++ b/config/crd/bases/openstack.k-orc.cloud_ports.yaml @@ -95,6 +95,11 @@ spec: error state and will not continue to retry. minProperties: 1 properties: + adminStateUp: + description: |- + adminStateUp is the administrative state of the port, + which is up (true) or down (false). + type: boolean description: description: description of the existing resource maxLength: 255 @@ -251,6 +256,12 @@ spec: x-kubernetes-validations: - message: addresses is immutable rule: self == oldSelf + adminStateUp: + default: true + description: |- + adminStateUp is the administrative state of the port, + which is up (true) or down (false). The default value is true. + type: boolean allowedAddressPairs: description: allowedAddressPairs are allowed addresses associated with this port. diff --git a/internal/controllers/port/actuator.go b/internal/controllers/port/actuator.go index dc30b26a5..570645623 100644 --- a/internal/controllers/port/actuator.go +++ b/internal/controllers/port/actuator.go @@ -132,14 +132,15 @@ func (actuator portActuator) ListOSResourcesForImport(ctx context.Context, obj o } listOpts := ports.ListOpts{ - Name: string(ptr.Deref(filter.Name, "")), - Description: string(ptr.Deref(filter.Description, "")), - NetworkID: ptr.Deref(network.Status.ID, ""), - ProjectID: ptr.Deref(project.Status.ID, ""), - Tags: tags.Join(filter.Tags), - TagsAny: tags.Join(filter.TagsAny), - NotTags: tags.Join(filter.NotTags), - NotTagsAny: tags.Join(filter.NotTagsAny), + Name: string(ptr.Deref(filter.Name, "")), + Description: string(ptr.Deref(filter.Description, "")), + NetworkID: ptr.Deref(network.Status.ID, ""), + ProjectID: ptr.Deref(project.Status.ID, ""), + Tags: tags.Join(filter.Tags), + TagsAny: tags.Join(filter.TagsAny), + NotTags: tags.Join(filter.NotTags), + NotTagsAny: tags.Join(filter.NotTagsAny), + AdminStateUp: filter.AdminStateUp, } return actuator.osClient.ListPort(ctx, listOpts), nil @@ -191,10 +192,11 @@ func (actuator portActuator) CreateResource(ctx context.Context, obj *orcv1alpha } createOpts := ports.CreateOpts{ - NetworkID: *network.Status.ID, - Name: getResourceName(obj), - Description: string(ptr.Deref(resource.Description, "")), - ProjectID: projectID, + NetworkID: *network.Status.ID, + Name: getResourceName(obj), + Description: string(ptr.Deref(resource.Description, "")), + ProjectID: projectID, + AdminStateUp: resource.AdminStateUp, } if len(resource.AllowedAddressPairs) > 0 { @@ -361,6 +363,7 @@ func (actuator portActuator) updateResource(ctx context.Context, obj orcObjectPT handleDescriptionUpdate(baseUpdateOpts, resource, osResource) handleAllowedAddressPairsUpdate(baseUpdateOpts, resource, osResource) handleSecurityGroupRefsUpdate(baseUpdateOpts, resource, osResource, secGroupMap) + handleAdminStateUpUpdate(baseUpdateOpts, resource, osResource) updateOpts = baseUpdateOpts } @@ -527,6 +530,15 @@ func handlePortSecurityUpdate(updateOpts ports.UpdateOptsBuilder, resource *reso return updateOpts } +func handleAdminStateUpUpdate(updateOpts *ports.UpdateOpts, resource *resourceSpecT, osResouce *osResourceT) { + adminStateUp := resource.AdminStateUp + if adminStateUp != nil { + if *adminStateUp != osResouce.AdminStateUp { + updateOpts.AdminStateUp = adminStateUp + } + } +} + type portHelperFactory struct{} var _ helperFactory = portHelperFactory{} diff --git a/internal/controllers/port/actuator_test.go b/internal/controllers/port/actuator_test.go index 06db089ba..81a2a7cc6 100644 --- a/internal/controllers/port/actuator_test.go +++ b/internal/controllers/port/actuator_test.go @@ -407,3 +407,31 @@ func TestHandlePortSecurityUpdate(t *testing.T) { }) } } + +func TestHandleAdminStateUpUpdate(t *testing.T) { + testCases := []struct { + name string + newValue *bool + existingValue bool + expectChange bool + }{ + {name: "Enabled when already enabled", newValue: ptr.To(true), existingValue: true, expectChange: false}, + {name: "Enabled when was disabled", newValue: ptr.To(true), existingValue: false, expectChange: true}, + {name: "Keep the existing value if newValue is not set", newValue: nil, existingValue: true, expectChange: false}, + } + + for _, tt := range testCases { + t.Run(tt.name, func(t *testing.T) { + resource := &orcv1alpha1.PortResourceSpec{AdminStateUp: tt.newValue} + osResource := &osclients.PortExt{Port: ports.Port{AdminStateUp: tt.existingValue}} + updateOpts := &ports.UpdateOpts{} + + handleAdminStateUpUpdate(updateOpts, resource, osResource) + + got, _ := needsUpdate(updateOpts) + if got != tt.expectChange { + t.Errorf("expected needsUpdate=%v, got %v", tt.expectChange, got) + } + }) + } +} diff --git a/internal/controllers/port/status.go b/internal/controllers/port/status.go index e193b9fb1..d740caac0 100644 --- a/internal/controllers/port/status.go +++ b/internal/controllers/port/status.go @@ -72,7 +72,8 @@ func (portStatusWriter) ApplyResourceStatus(log logr.Logger, osResource *osResou WithPortSecurityEnabled(osResource.PortSecurityEnabled). WithRevisionNumber(int64(osResource.RevisionNumber)). WithCreatedAt(metav1.NewTime(osResource.CreatedAt)). - WithUpdatedAt(metav1.NewTime(osResource.UpdatedAt)) + WithUpdatedAt(metav1.NewTime(osResource.UpdatedAt)). + WithAdminStateUp(osResource.AdminStateUp) if osResource.Description != "" { resourceStatus.WithDescription(osResource.Description) diff --git a/internal/controllers/port/tests/port-create-full/00-assert.yaml b/internal/controllers/port/tests/port-create-full/00-assert.yaml index b8340a6fe..3f2ea0750 100644 --- a/internal/controllers/port/tests/port-create-full/00-assert.yaml +++ b/internal/controllers/port/tests/port-create-full/00-assert.yaml @@ -7,7 +7,7 @@ status: resource: name: port-create-full-override description: Port from "create full" test - adminStateUp: true + adminStateUp: false allowedAddressPairs: - ip: 192.168.122.14 mac: 92:42:9c:13:98:82 diff --git a/internal/controllers/port/tests/port-create-full/00-create-resource.yaml b/internal/controllers/port/tests/port-create-full/00-create-resource.yaml index df01e9cf7..31174591f 100644 --- a/internal/controllers/port/tests/port-create-full/00-create-resource.yaml +++ b/internal/controllers/port/tests/port-create-full/00-create-resource.yaml @@ -69,6 +69,7 @@ spec: resource: name: port-create-full-override description: Port from "create full" test + adminStateUp: false networkRef: port-create-full allowedAddressPairs: - ip: "192.168.122.14" diff --git a/internal/controllers/port/tests/port-import/00-import-resource.yaml b/internal/controllers/port/tests/port-import/00-import-resource.yaml index 550d674eb..bed7543ba 100644 --- a/internal/controllers/port/tests/port-import/00-import-resource.yaml +++ b/internal/controllers/port/tests/port-import/00-import-resource.yaml @@ -12,5 +12,6 @@ spec: filter: name: port-import-external description: Port from "port-import" test + adminStateUp: false tags: - tag1 diff --git a/internal/controllers/port/tests/port-import/01-create-trap-resource.yaml b/internal/controllers/port/tests/port-import/01-create-trap-resource.yaml index 1169caea0..6700ffff1 100644 --- a/internal/controllers/port/tests/port-import/01-create-trap-resource.yaml +++ b/internal/controllers/port/tests/port-import/01-create-trap-resource.yaml @@ -14,5 +14,6 @@ spec: resource: networkRef: port-import description: Port from "port-import" test + adminStateUp: false tags: - tag1 diff --git a/internal/controllers/port/tests/port-import/02-assert.yaml b/internal/controllers/port/tests/port-import/02-assert.yaml index 1d1486451..ff0745560 100644 --- a/internal/controllers/port/tests/port-import/02-assert.yaml +++ b/internal/controllers/port/tests/port-import/02-assert.yaml @@ -30,5 +30,6 @@ status: resource: name: port-import-external description: Port from "port-import" test + adminStateUp: false tags: - tag1 diff --git a/internal/controllers/port/tests/port-import/02-create-resource.yaml b/internal/controllers/port/tests/port-import/02-create-resource.yaml index 1aa71a126..838d1d0d6 100644 --- a/internal/controllers/port/tests/port-import/02-create-resource.yaml +++ b/internal/controllers/port/tests/port-import/02-create-resource.yaml @@ -11,5 +11,6 @@ spec: resource: networkRef: port-import description: Port from "port-import" test + adminStateUp: false tags: - tag1 diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/portfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/portfilter.go index 58a38868e..e1732f652 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portfilter.go @@ -29,6 +29,7 @@ type PortFilterApplyConfiguration struct { Description *apiv1alpha1.NeutronDescription `json:"description,omitempty"` NetworkRef *apiv1alpha1.KubernetesNameRef `json:"networkRef,omitempty"` ProjectRef *apiv1alpha1.KubernetesNameRef `json:"projectRef,omitempty"` + AdminStateUp *bool `json:"adminStateUp,omitempty"` FilterByNeutronTagsApplyConfiguration `json:",inline"` } @@ -70,6 +71,14 @@ func (b *PortFilterApplyConfiguration) WithProjectRef(value apiv1alpha1.Kubernet return b } +// WithAdminStateUp sets the AdminStateUp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AdminStateUp field is set to the value of the last call. +func (b *PortFilterApplyConfiguration) WithAdminStateUp(value bool) *PortFilterApplyConfiguration { + b.AdminStateUp = &value + return b +} + // WithTags adds the given value to the Tags field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Tags field. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go index 74d7edd1e..67351b05c 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go @@ -31,6 +31,7 @@ type PortResourceSpecApplyConfiguration struct { Tags []apiv1alpha1.NeutronTag `json:"tags,omitempty"` AllowedAddressPairs []AllowedAddressPairApplyConfiguration `json:"allowedAddressPairs,omitempty"` Addresses []AddressApplyConfiguration `json:"addresses,omitempty"` + AdminStateUp *bool `json:"adminStateUp,omitempty"` SecurityGroupRefs []apiv1alpha1.OpenStackName `json:"securityGroupRefs,omitempty"` VNICType *string `json:"vnicType,omitempty"` PortSecurity *apiv1alpha1.PortSecurityState `json:"portSecurity,omitempty"` @@ -103,6 +104,14 @@ func (b *PortResourceSpecApplyConfiguration) WithAddresses(values ...*AddressApp return b } +// WithAdminStateUp sets the AdminStateUp field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the AdminStateUp field is set to the value of the last call. +func (b *PortResourceSpecApplyConfiguration) WithAdminStateUp(value bool) *PortResourceSpecApplyConfiguration { + b.AdminStateUp = &value + return b +} + // WithSecurityGroupRefs adds the given value to the SecurityGroupRefs field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the SecurityGroupRefs field. diff --git a/pkg/clients/applyconfiguration/internal/internal.go b/pkg/clients/applyconfiguration/internal/internal.go index 4cd388895..b912b87af 100644 --- a/pkg/clients/applyconfiguration/internal/internal.go +++ b/pkg/clients/applyconfiguration/internal/internal.go @@ -1353,6 +1353,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.PortFilter map: fields: + - name: adminStateUp + type: + scalar: boolean - name: description type: scalar: string @@ -1430,6 +1433,9 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.Address elementRelationship: atomic + - name: adminStateUp + type: + scalar: boolean - name: allowedAddressPairs type: list: diff --git a/website/docs/crd-reference.md b/website/docs/crd-reference.md index 131d2a64d..9ad716855 100644 --- a/website/docs/crd-reference.md +++ b/website/docs/crd-reference.md @@ -2212,6 +2212,7 @@ _Appears in:_ | `description` _[NeutronDescription](#neutrondescription)_ | description of the existing resource | | MaxLength: 255
MinLength: 1
| | `networkRef` _[KubernetesNameRef](#kubernetesnameref)_ | networkRef is a reference to the ORC Network which this port is associated with. | | MaxLength: 253
MinLength: 1
| | `projectRef` _[KubernetesNameRef](#kubernetesnameref)_ | projectRef is a reference to the ORC Project this resource is associated with.
Typically, only used by admin. | | MaxLength: 253
MinLength: 1
| +| `adminStateUp` _boolean_ | adminStateUp is the administrative state of the port,
which is up (true) or down (false). | | | | `tags` _[NeutronTag](#neutrontag) array_ | tags is a list of tags to filter by. If specified, the resource must
have all of the tags specified to be included in the result. | | MaxItems: 64
MaxLength: 255
MinLength: 1
| | `tagsAny` _[NeutronTag](#neutrontag) array_ | tagsAny is a list of tags to filter by. If specified, the resource
must have at least one of the tags specified to be included in the
result. | | MaxItems: 64
MaxLength: 255
MinLength: 1
| | `notTags` _[NeutronTag](#neutrontag) array_ | notTags is a list of tags to filter by. If specified, resources which
contain all of the given tags will be excluded from the result. | | MaxItems: 64
MaxLength: 255
MinLength: 1
| @@ -2306,6 +2307,7 @@ _Appears in:_ | `tags` _[NeutronTag](#neutrontag) array_ | tags is a list of tags which will be applied to the port. | | MaxItems: 64
MaxLength: 255
MinLength: 1
| | `allowedAddressPairs` _[AllowedAddressPair](#allowedaddresspair) array_ | allowedAddressPairs are allowed addresses associated with this port. | | MaxItems: 128
| | `addresses` _[Address](#address) array_ | addresses are the IP addresses for the port. | | MaxItems: 128
| +| `adminStateUp` _boolean_ | adminStateUp is the administrative state of the port,
which is up (true) or down (false). The default value is true. | true | | | `securityGroupRefs` _[OpenStackName](#openstackname) array_ | securityGroupRefs are the names of the security groups associated
with this port. | | MaxItems: 64
MaxLength: 255
MinLength: 1
Pattern: `^[^,]+$`
| | `vnicType` _string_ | vnicType specifies the type of vNIC which this port should be
attached to. This is used to determine which mechanism driver(s) to
be used to bind the port. The valid values are normal, macvtap,
direct, baremetal, direct-physical, virtio-forwarder, smart-nic and
remote-managed, although these values will not be validated in this
API to ensure compatibility with future neutron changes or custom
implementations. What type of vNIC is actually available depends on
deployments. If not specified, the Neutron default value is used. | | MaxLength: 64
| | `portSecurity` _[PortSecurityState](#portsecuritystate)_ | portSecurity controls port security for this port.
When set to Enabled, port security is enabled.
When set to Disabled, port security is disabled and SecurityGroupRefs must be empty.
When set to Inherit (default), it takes the value from the network level. | Inherit | Enum: [Enabled Disabled Inherit]
| From ace25127845edbaf6bda0485115685b523aca989 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Andr=C3=A9?= Date: Fri, 2 Jan 2026 12:20:46 +0100 Subject: [PATCH 5/9] Get orc resources via their full names This avoids issues when the resource name conflicts with existing resources and we can't use shortcuts in kubectl commands (e.g. service or role). --- .../data/tests/dependency/02-delete-dependencies.yaml.template | 2 +- .../data/tests/dependency/03-assert.yaml.template | 2 +- .../data/tests/import-dependency/03-assert.yaml.template | 2 +- .../03-delete-import-dependencies.yaml.template | 2 +- .../data/tests/import-dependency/04-assert.yaml.template | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/cmd/scaffold-controller/data/tests/dependency/02-delete-dependencies.yaml.template b/cmd/scaffold-controller/data/tests/dependency/02-delete-dependencies.yaml.template index 6afc372ef..a5e38546d 100644 --- a/cmd/scaffold-controller/data/tests/dependency/02-delete-dependencies.yaml.template +++ b/cmd/scaffold-controller/data/tests/dependency/02-delete-dependencies.yaml.template @@ -5,7 +5,7 @@ kind: TestStep commands: # We expect the deletion to hang due to the finalizer, so use --wait=false {{- range .AllCreateDependencies }} - - command: kubectl delete {{ . | lower }} {{ $packageName }}-dependency --wait=false + - command: kubectl delete {{ . | lower }}.openstack.k-orc.cloud {{ $packageName }}-dependency --wait=false namespaced: true {{- end }} - command: kubectl delete secret {{ $packageName }}-dependency --wait=false diff --git a/cmd/scaffold-controller/data/tests/dependency/03-assert.yaml.template b/cmd/scaffold-controller/data/tests/dependency/03-assert.yaml.template index fa188a9d1..aa96bb1aa 100644 --- a/cmd/scaffold-controller/data/tests/dependency/03-assert.yaml.template +++ b/cmd/scaffold-controller/data/tests/dependency/03-assert.yaml.template @@ -5,7 +5,7 @@ kind: TestAssert commands: # Dependencies that were prevented deletion before should now be gone {{- range .AllCreateDependencies }} -- script: "! kubectl get {{ . | lower }} {{ $packageName }}-dependency --namespace $NAMESPACE" +- script: "! kubectl get {{ . | lower }}.openstack.k-orc.cloud {{ $packageName }}-dependency --namespace $NAMESPACE" skipLogOutput: true {{- end }} - script: "! kubectl get secret {{ $packageName }}-dependency --namespace $NAMESPACE" diff --git a/cmd/scaffold-controller/data/tests/import-dependency/03-assert.yaml.template b/cmd/scaffold-controller/data/tests/import-dependency/03-assert.yaml.template index c4c2e4879..0f1e4487a 100644 --- a/cmd/scaffold-controller/data/tests/import-dependency/03-assert.yaml.template +++ b/cmd/scaffold-controller/data/tests/import-dependency/03-assert.yaml.template @@ -4,6 +4,6 @@ apiVersion: kuttl.dev/v1beta1 kind: TestAssert commands: {{- range .ImportDependencies }} -- script: "! kubectl get {{ . | lower }} {{ $packageName }}-import-dependency --namespace $NAMESPACE" +- script: "! kubectl get {{ . | lower }}.openstack.k-orc.cloud {{ $packageName }}-import-dependency --namespace $NAMESPACE" skipLogOutput: true {{- end }} diff --git a/cmd/scaffold-controller/data/tests/import-dependency/03-delete-import-dependencies.yaml.template b/cmd/scaffold-controller/data/tests/import-dependency/03-delete-import-dependencies.yaml.template index 45c3d2658..184f2f866 100644 --- a/cmd/scaffold-controller/data/tests/import-dependency/03-delete-import-dependencies.yaml.template +++ b/cmd/scaffold-controller/data/tests/import-dependency/03-delete-import-dependencies.yaml.template @@ -5,6 +5,6 @@ kind: TestStep commands: # We should be able to delete the import dependencies {{- range .ImportDependencies }} - - command: kubectl delete {{ . | lower }} {{ $packageName }}-import-dependency + - command: kubectl delete {{ . | lower }}.openstack.k-orc.cloud {{ $packageName }}-import-dependency namespaced: true {{- end }} diff --git a/cmd/scaffold-controller/data/tests/import-dependency/04-assert.yaml.template b/cmd/scaffold-controller/data/tests/import-dependency/04-assert.yaml.template index e7f733ae9..cab39b2e5 100644 --- a/cmd/scaffold-controller/data/tests/import-dependency/04-assert.yaml.template +++ b/cmd/scaffold-controller/data/tests/import-dependency/04-assert.yaml.template @@ -2,5 +2,5 @@ apiVersion: kuttl.dev/v1beta1 kind: TestAssert commands: -- script: "! kubectl get {{ .PackageName }} {{ .PackageName }}-import-dependency --namespace $NAMESPACE" +- script: "! kubectl get {{ .PackageName }}.openstack.k-orc.cloud {{ .PackageName }}-import-dependency --namespace $NAMESPACE" skipLogOutput: true From 03823af229e171a63d8936801d5a6c3644f29b20 Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Thu, 18 Dec 2025 11:59:59 -0300 Subject: [PATCH 6/9] port: add macaddress field Signed-off-by: Winicius Silva --- api/v1alpha1/port_types.go | 10 ++++++++++ cmd/models-schema/zz_generated.openapi.go | 14 ++++++++++++++ config/crd/bases/openstack.k-orc.cloud_ports.yaml | 8 ++++++++ internal/controllers/port/actuator.go | 2 ++ internal/controllers/port/status.go | 3 ++- .../port/tests/port-create-full/00-assert.yaml | 2 +- .../tests/port-create-full/00-create-resource.yaml | 1 + .../port/tests/port-import/00-import-resource.yaml | 1 + .../port/tests/port-import/02-assert.yaml | 1 + .../port/tests/port-import/02-create-resource.yaml | 1 + .../applyconfiguration/api/v1alpha1/portfilter.go | 9 +++++++++ .../api/v1alpha1/portresourcespec.go | 9 +++++++++ .../applyconfiguration/internal/internal.go | 6 ++++++ website/docs/crd-reference.md | 2 ++ 14 files changed, 67 insertions(+), 2 deletions(-) diff --git a/api/v1alpha1/port_types.go b/api/v1alpha1/port_types.go index 868748c17..22ca3ed77 100644 --- a/api/v1alpha1/port_types.go +++ b/api/v1alpha1/port_types.go @@ -41,6 +41,11 @@ type PortFilter struct { // +optional AdminStateUp *bool `json:"adminStateUp,omitempty"` + // macAddress is the MAC address of the port. + // +kubebuilder:validation:MaxLength=32 + // +optional + MACAddress string `json:"macAddress,omitempty"` + FilterByNeutronTags `json:",inline"` } @@ -170,6 +175,11 @@ type PortResourceSpec struct { // +optional // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="projectRef is immutable" ProjectRef *KubernetesNameRef `json:"projectRef,omitempty"` + + // macAddress is the MAC address of the port. + // +kubebuilder:validation:MaxLength=32 + // +optional + MACAddress string `json:"macAddress,omitempty"` } type PortResourceStatus struct { diff --git a/cmd/models-schema/zz_generated.openapi.go b/cmd/models-schema/zz_generated.openapi.go index 6ffa5e66b..224c2f403 100644 --- a/cmd/models-schema/zz_generated.openapi.go +++ b/cmd/models-schema/zz_generated.openapi.go @@ -4909,6 +4909,13 @@ func schema_openstack_resource_controller_v2_api_v1alpha1_PortFilter(ref common. Format: "", }, }, + "macAddress": { + SchemaProps: spec.SchemaProps{ + Description: "macAddress is the MAC address of the port.", + Type: []string{"string"}, + Format: "", + }, + }, "tags": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ @@ -5264,6 +5271,13 @@ func schema_openstack_resource_controller_v2_api_v1alpha1_PortResourceSpec(ref c Format: "", }, }, + "macAddress": { + SchemaProps: spec.SchemaProps{ + Description: "macAddress is the MAC address of the port.", + Type: []string{"string"}, + Format: "", + }, + }, }, Required: []string{"networkRef"}, }, diff --git a/config/crd/bases/openstack.k-orc.cloud_ports.yaml b/config/crd/bases/openstack.k-orc.cloud_ports.yaml index 64c66bbf5..6b96e097a 100644 --- a/config/crd/bases/openstack.k-orc.cloud_ports.yaml +++ b/config/crd/bases/openstack.k-orc.cloud_ports.yaml @@ -105,6 +105,10 @@ spec: maxLength: 255 minLength: 1 type: string + macAddress: + description: macAddress is the MAC address of the port. + maxLength: 32 + type: string name: description: name of the existing resource maxLength: 255 @@ -294,6 +298,10 @@ spec: maxLength: 255 minLength: 1 type: string + macAddress: + description: macAddress is the MAC address of the port. + maxLength: 32 + type: string name: description: name is a human-readable name of the port. If not set, the object's name will be used. diff --git a/internal/controllers/port/actuator.go b/internal/controllers/port/actuator.go index 570645623..61c23c7b5 100644 --- a/internal/controllers/port/actuator.go +++ b/internal/controllers/port/actuator.go @@ -141,6 +141,7 @@ func (actuator portActuator) ListOSResourcesForImport(ctx context.Context, obj o NotTags: tags.Join(filter.NotTags), NotTagsAny: tags.Join(filter.NotTagsAny), AdminStateUp: filter.AdminStateUp, + MACAddress: filter.MACAddress, } return actuator.osClient.ListPort(ctx, listOpts), nil @@ -197,6 +198,7 @@ func (actuator portActuator) CreateResource(ctx context.Context, obj *orcv1alpha Description: string(ptr.Deref(resource.Description, "")), ProjectID: projectID, AdminStateUp: resource.AdminStateUp, + MACAddress: resource.MACAddress, } if len(resource.AllowedAddressPairs) > 0 { diff --git a/internal/controllers/port/status.go b/internal/controllers/port/status.go index d740caac0..0a15c7a60 100644 --- a/internal/controllers/port/status.go +++ b/internal/controllers/port/status.go @@ -73,7 +73,8 @@ func (portStatusWriter) ApplyResourceStatus(log logr.Logger, osResource *osResou WithRevisionNumber(int64(osResource.RevisionNumber)). WithCreatedAt(metav1.NewTime(osResource.CreatedAt)). WithUpdatedAt(metav1.NewTime(osResource.UpdatedAt)). - WithAdminStateUp(osResource.AdminStateUp) + WithAdminStateUp(osResource.AdminStateUp). + WithMACAddress(osResource.MACAddress) if osResource.Description != "" { resourceStatus.WithDescription(osResource.Description) diff --git a/internal/controllers/port/tests/port-create-full/00-assert.yaml b/internal/controllers/port/tests/port-create-full/00-assert.yaml index 3f2ea0750..3c866dbb6 100644 --- a/internal/controllers/port/tests/port-create-full/00-assert.yaml +++ b/internal/controllers/port/tests/port-create-full/00-assert.yaml @@ -15,6 +15,7 @@ status: propagateUplinkStatus: false status: DOWN vnicType: direct + macAddress: fa:16:3e:23:fd:d7 tags: - tag1 --- @@ -41,7 +42,6 @@ assertAll: - celExpr: "port.status.id != ''" - celExpr: "port.status.resource.createdAt != ''" - celExpr: "port.status.resource.updatedAt != ''" - - celExpr: "port.status.resource.macAddress != ''" - celExpr: "port.status.resource.revisionNumber > 0" - celExpr: "port.status.resource.fixedIPs[0].subnetID == subnet.status.id" - celExpr: "port.status.resource.fixedIPs[0].ip == '192.168.155.122'" diff --git a/internal/controllers/port/tests/port-create-full/00-create-resource.yaml b/internal/controllers/port/tests/port-create-full/00-create-resource.yaml index 31174591f..1721a83a1 100644 --- a/internal/controllers/port/tests/port-create-full/00-create-resource.yaml +++ b/internal/controllers/port/tests/port-create-full/00-create-resource.yaml @@ -84,3 +84,4 @@ spec: portSecurity: Enabled vnicType: direct projectRef: port-create-full + macAddress: fa:16:3e:23:fd:d7 diff --git a/internal/controllers/port/tests/port-import/00-import-resource.yaml b/internal/controllers/port/tests/port-import/00-import-resource.yaml index bed7543ba..0b58377dc 100644 --- a/internal/controllers/port/tests/port-import/00-import-resource.yaml +++ b/internal/controllers/port/tests/port-import/00-import-resource.yaml @@ -13,5 +13,6 @@ spec: name: port-import-external description: Port from "port-import" test adminStateUp: false + macAddress: fa:16:3e:23:fd:d7 tags: - tag1 diff --git a/internal/controllers/port/tests/port-import/02-assert.yaml b/internal/controllers/port/tests/port-import/02-assert.yaml index ff0745560..3ef560d86 100644 --- a/internal/controllers/port/tests/port-import/02-assert.yaml +++ b/internal/controllers/port/tests/port-import/02-assert.yaml @@ -31,5 +31,6 @@ status: name: port-import-external description: Port from "port-import" test adminStateUp: false + macAddress: fa:16:3e:23:fd:d7 tags: - tag1 diff --git a/internal/controllers/port/tests/port-import/02-create-resource.yaml b/internal/controllers/port/tests/port-import/02-create-resource.yaml index 838d1d0d6..bbd3842bb 100644 --- a/internal/controllers/port/tests/port-import/02-create-resource.yaml +++ b/internal/controllers/port/tests/port-import/02-create-resource.yaml @@ -12,5 +12,6 @@ spec: networkRef: port-import description: Port from "port-import" test adminStateUp: false + macAddress: fa:16:3e:23:fd:d7 tags: - tag1 diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/portfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/portfilter.go index e1732f652..ab6d6e18d 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portfilter.go @@ -30,6 +30,7 @@ type PortFilterApplyConfiguration struct { NetworkRef *apiv1alpha1.KubernetesNameRef `json:"networkRef,omitempty"` ProjectRef *apiv1alpha1.KubernetesNameRef `json:"projectRef,omitempty"` AdminStateUp *bool `json:"adminStateUp,omitempty"` + MACAddress *string `json:"macAddress,omitempty"` FilterByNeutronTagsApplyConfiguration `json:",inline"` } @@ -79,6 +80,14 @@ func (b *PortFilterApplyConfiguration) WithAdminStateUp(value bool) *PortFilterA return b } +// WithMACAddress sets the MACAddress field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MACAddress field is set to the value of the last call. +func (b *PortFilterApplyConfiguration) WithMACAddress(value string) *PortFilterApplyConfiguration { + b.MACAddress = &value + return b +} + // WithTags adds the given value to the Tags field in the declarative configuration // and returns the receiver, so that objects can be build by chaining "With" function invocations. // If called multiple times, values provided by each call will be appended to the Tags field. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go index 67351b05c..ac7d4ed07 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go @@ -36,6 +36,7 @@ type PortResourceSpecApplyConfiguration struct { VNICType *string `json:"vnicType,omitempty"` PortSecurity *apiv1alpha1.PortSecurityState `json:"portSecurity,omitempty"` ProjectRef *apiv1alpha1.KubernetesNameRef `json:"projectRef,omitempty"` + MACAddress *string `json:"macAddress,omitempty"` } // PortResourceSpecApplyConfiguration constructs a declarative configuration of the PortResourceSpec type for use with @@ -145,3 +146,11 @@ func (b *PortResourceSpecApplyConfiguration) WithProjectRef(value apiv1alpha1.Ku b.ProjectRef = &value return b } + +// WithMACAddress sets the MACAddress field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the MACAddress field is set to the value of the last call. +func (b *PortResourceSpecApplyConfiguration) WithMACAddress(value string) *PortResourceSpecApplyConfiguration { + b.MACAddress = &value + return b +} diff --git a/pkg/clients/applyconfiguration/internal/internal.go b/pkg/clients/applyconfiguration/internal/internal.go index b912b87af..b1b784c8e 100644 --- a/pkg/clients/applyconfiguration/internal/internal.go +++ b/pkg/clients/applyconfiguration/internal/internal.go @@ -1359,6 +1359,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: description type: scalar: string + - name: macAddress + type: + scalar: string - name: name type: scalar: string @@ -1445,6 +1448,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: description type: scalar: string + - name: macAddress + type: + scalar: string - name: name type: scalar: string diff --git a/website/docs/crd-reference.md b/website/docs/crd-reference.md index 9ad716855..56034cb4b 100644 --- a/website/docs/crd-reference.md +++ b/website/docs/crd-reference.md @@ -2213,6 +2213,7 @@ _Appears in:_ | `networkRef` _[KubernetesNameRef](#kubernetesnameref)_ | networkRef is a reference to the ORC Network which this port is associated with. | | MaxLength: 253
MinLength: 1
| | `projectRef` _[KubernetesNameRef](#kubernetesnameref)_ | projectRef is a reference to the ORC Project this resource is associated with.
Typically, only used by admin. | | MaxLength: 253
MinLength: 1
| | `adminStateUp` _boolean_ | adminStateUp is the administrative state of the port,
which is up (true) or down (false). | | | +| `macAddress` _string_ | macAddress is the MAC address of the port. | | MaxLength: 32
| | `tags` _[NeutronTag](#neutrontag) array_ | tags is a list of tags to filter by. If specified, the resource must
have all of the tags specified to be included in the result. | | MaxItems: 64
MaxLength: 255
MinLength: 1
| | `tagsAny` _[NeutronTag](#neutrontag) array_ | tagsAny is a list of tags to filter by. If specified, the resource
must have at least one of the tags specified to be included in the
result. | | MaxItems: 64
MaxLength: 255
MinLength: 1
| | `notTags` _[NeutronTag](#neutrontag) array_ | notTags is a list of tags to filter by. If specified, resources which
contain all of the given tags will be excluded from the result. | | MaxItems: 64
MaxLength: 255
MinLength: 1
| @@ -2312,6 +2313,7 @@ _Appears in:_ | `vnicType` _string_ | vnicType specifies the type of vNIC which this port should be
attached to. This is used to determine which mechanism driver(s) to
be used to bind the port. The valid values are normal, macvtap,
direct, baremetal, direct-physical, virtio-forwarder, smart-nic and
remote-managed, although these values will not be validated in this
API to ensure compatibility with future neutron changes or custom
implementations. What type of vNIC is actually available depends on
deployments. If not specified, the Neutron default value is used. | | MaxLength: 64
| | `portSecurity` _[PortSecurityState](#portsecuritystate)_ | portSecurity controls port security for this port.
When set to Enabled, port security is enabled.
When set to Disabled, port security is disabled and SecurityGroupRefs must be empty.
When set to Inherit (default), it takes the value from the network level. | Inherit | Enum: [Enabled Disabled Inherit]
| | `projectRef` _[KubernetesNameRef](#kubernetesnameref)_ | projectRef is a reference to the ORC Project this resource is associated with.
Typically, only used by admin. | | MaxLength: 253
MinLength: 1
| +| `macAddress` _string_ | macAddress is the MAC address of the port. | | MaxLength: 32
| #### PortResourceStatus From 95e605b6c86eaba46e7ad6e69edccbd19e46b53d Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Fri, 2 Jan 2026 20:47:24 -0300 Subject: [PATCH 7/9] remove duplicated MACAddress and AdminStateUp status writing --- internal/controllers/port/status.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/internal/controllers/port/status.go b/internal/controllers/port/status.go index 0a15c7a60..e193b9fb1 100644 --- a/internal/controllers/port/status.go +++ b/internal/controllers/port/status.go @@ -72,9 +72,7 @@ func (portStatusWriter) ApplyResourceStatus(log logr.Logger, osResource *osResou WithPortSecurityEnabled(osResource.PortSecurityEnabled). WithRevisionNumber(int64(osResource.RevisionNumber)). WithCreatedAt(metav1.NewTime(osResource.CreatedAt)). - WithUpdatedAt(metav1.NewTime(osResource.UpdatedAt)). - WithAdminStateUp(osResource.AdminStateUp). - WithMACAddress(osResource.MACAddress) + WithUpdatedAt(metav1.NewTime(osResource.UpdatedAt)) if osResource.Description != "" { resourceStatus.WithDescription(osResource.Description) From 8712a020d28a47af7ae8160ede0d2bd32cd9dc98 Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Wed, 7 Jan 2026 10:08:20 -0300 Subject: [PATCH 8/9] bump: gophercloud to v2.10.0 --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 0562d961f..419ce1cbe 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.24.0 require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/go-logr/logr v1.4.3 - github.com/gophercloud/gophercloud/v2 v2.9.0 + github.com/gophercloud/gophercloud/v2 v2.10.0 github.com/gophercloud/utils/v2 v2.0.0-20241220104409-2e0af06694a1 github.com/onsi/ginkgo/v2 v2.27.3 github.com/onsi/gomega v1.38.3 diff --git a/go.sum b/go.sum index 0d31f1ca9..985aa862c 100644 --- a/go.sum +++ b/go.sum @@ -76,8 +76,8 @@ github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/gophercloud/gophercloud/v2 v2.9.0 h1:Y9OMrwKF9EDERcHFSOTpf/6XGoAI0yOxmsLmQki4LPM= -github.com/gophercloud/gophercloud/v2 v2.9.0/go.mod h1:Ki/ILhYZr/5EPebrPL9Ej+tUg4lqx71/YH2JWVeU+Qk= +github.com/gophercloud/gophercloud/v2 v2.10.0 h1:NRadC0aHNvy4iMoFXj5AFiPmut/Sj3hAPAo9B59VMGc= +github.com/gophercloud/gophercloud/v2 v2.10.0/go.mod h1:Ki/ILhYZr/5EPebrPL9Ej+tUg4lqx71/YH2JWVeU+Qk= github.com/gophercloud/utils/v2 v2.0.0-20241220104409-2e0af06694a1 h1:LS70kbNdqoalMwLXEzP9Xb/cYv9UCzWioXaOynxrytc= github.com/gophercloud/utils/v2 v2.0.0-20241220104409-2e0af06694a1/go.mod h1:qDhuzCRKi90/Yyl/yEqkg8+qABEvK44LhP0D3GWKGtY= github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.3 h1:5ZPtiqj0JL5oKWmcsq4VMaAW5ukBEgSGXEN89zeH1Jo= From 50f22184d5e325b432ae0572d4891356edac821b Mon Sep 17 00:00:00 2001 From: Winicius Silva Date: Wed, 7 Jan 2026 14:29:02 -0300 Subject: [PATCH 9/9] change: drop name field, add description and enabled --- README.md | 2 +- api/v1alpha1/endpoint_types.go | 18 ++- api/v1alpha1/port_types.go | 10 ++ api/v1alpha1/server_types.go | 51 +++++++ api/v1alpha1/zz_generated.deepcopy.go | 60 ++++++-- api/v1alpha1/zz_generated.domain-resource.go | 2 +- .../zz_generated.endpoint-resource.go | 2 +- api/v1alpha1/zz_generated.flavor-resource.go | 2 +- .../zz_generated.floatingip-resource.go | 2 +- api/v1alpha1/zz_generated.group-resource.go | 2 +- api/v1alpha1/zz_generated.image-resource.go | 2 +- api/v1alpha1/zz_generated.keypair-resource.go | 2 +- api/v1alpha1/zz_generated.network-resource.go | 2 +- api/v1alpha1/zz_generated.port-resource.go | 2 +- api/v1alpha1/zz_generated.project-resource.go | 2 +- api/v1alpha1/zz_generated.role-resource.go | 2 +- api/v1alpha1/zz_generated.router-resource.go | 2 +- .../zz_generated.securitygroup-resource.go | 2 +- api/v1alpha1/zz_generated.server-resource.go | 2 +- .../zz_generated.servergroup-resource.go | 2 +- api/v1alpha1/zz_generated.service-resource.go | 2 +- api/v1alpha1/zz_generated.subnet-resource.go | 2 +- api/v1alpha1/zz_generated.volume-resource.go | 2 +- .../zz_generated.volumetype-resource.go | 2 +- cmd/models-schema/zz_generated.openapi.go | 137 ++++++++++++++++- cmd/resource-generator/data/adapter.template | 2 +- cmd/resource-generator/data/api.template | 2 +- .../data/controller.template | 2 +- .../internal-osclients-mock-doc.go.template | 2 +- cmd/resource-generator/main.go | 9 +- .../data/api/types.go.template | 2 +- .../data/client/client.go.template | 2 +- .../data/controller/actuator.go.template | 36 ++--- .../data/controller/actuator_test.go.template | 2 +- .../data/controller/controller.go.template | 2 +- .../data/controller/status.go.template | 2 +- cmd/scaffold-controller/main.go | 3 - .../openstack.k-orc.cloud_endpoints.yaml | 30 ++-- .../bases/openstack.k-orc.cloud_ports.yaml | 8 + .../bases/openstack.k-orc.cloud_servers.yaml | 56 +++++++ config/samples/openstack_v1alpha1_server.yaml | 6 + hack/boilerplate.go.txt | 2 +- .../domain/zz_generated.adapter.go | 2 +- .../domain/zz_generated.controller.go | 2 +- internal/controllers/endpoint/actuator.go | 24 +-- internal/controllers/endpoint/status.go | 7 +- .../tests/endpoint-create-full/00-assert.yaml | 5 +- .../00-create-resource.yaml | 6 +- .../endpoint-create-minimal/00-assert.yaml | 2 +- .../endpoint-import/00-import-resource.yaml | 1 + .../tests/endpoint-import/01-assert.yaml | 1 - .../tests/endpoint-import/02-assert.yaml | 3 +- .../endpoint-import/02-create-resource.yaml | 1 + .../tests/endpoint-update/00-assert.yaml | 5 +- .../endpoint-update/00-minimal-resource.yaml | 3 + .../tests/endpoint-update/01-assert.yaml | 3 +- .../endpoint-update/01-updated-resource.yaml | 5 +- .../tests/endpoint-update/02-assert.yaml | 5 +- .../endpoint/zz_generated.adapter.go | 12 +- .../endpoint/zz_generated.controller.go | 2 +- .../flavor/zz_generated.adapter.go | 2 +- .../flavor/zz_generated.controller.go | 2 +- internal/controllers/floatingip/actuator.go | 82 +++------- .../floatingip/zz_generated.adapter.go | 2 +- .../floatingip/zz_generated.controller.go | 2 +- internal/controllers/group/actuator.go | 28 +--- .../controllers/group/zz_generated.adapter.go | 2 +- .../group/zz_generated.controller.go | 2 +- .../controllers/image/zz_generated.adapter.go | 2 +- .../image/zz_generated.controller.go | 2 +- .../keypair/zz_generated.adapter.go | 2 +- .../keypair/zz_generated.controller.go | 2 +- internal/controllers/network/actuator.go | 28 +--- .../network/zz_generated.adapter.go | 2 +- .../network/zz_generated.controller.go | 2 +- internal/controllers/port/actuator.go | 63 ++++---- internal/controllers/port/status.go | 3 +- .../tests/port-create-full/00-assert.yaml | 3 +- .../port-create-full/00-create-resource.yaml | 3 +- .../port/tests/port-update/00-assert.yaml | 30 ++++ .../port-update/00-minimal-resource.yaml | 14 ++ .../port/tests/port-update/01-assert.yaml | 17 ++- .../port-update/01-updated-resource.yaml | 14 +- .../port-update/02-reverted-resource.yaml | 2 +- .../controllers/port/zz_generated.adapter.go | 2 +- .../port/zz_generated.controller.go | 2 +- .../project/zz_generated.adapter.go | 2 +- .../project/zz_generated.controller.go | 2 +- internal/controllers/role/actuator.go | 28 +--- .../controllers/role/zz_generated.adapter.go | 2 +- .../role/zz_generated.controller.go | 2 +- internal/controllers/router/actuator.go | 28 +--- .../router/zz_generated.adapter.go | 2 +- .../router/zz_generated.controller.go | 2 +- .../controllers/securitygroup/actuator.go | 27 +--- .../securitygroup/zz_generated.adapter.go | 2 +- .../securitygroup/zz_generated.controller.go | 2 +- internal/controllers/server/actuator.go | 143 +++++++++--------- internal/controllers/server/status.go | 12 +- .../tests/server-create-full/00-assert.yaml | 6 + .../00-create-resource.yaml | 6 + .../server/tests/server-update/00-assert.yaml | 1 + .../server/tests/server-update/01-assert.yaml | 5 + .../server-update/01-updated-resource.yaml | 5 + .../server/tests/server-update/02-assert.yaml | 1 + .../server/zz_generated.adapter.go | 2 +- .../server/zz_generated.controller.go | 2 +- .../servergroup/zz_generated.adapter.go | 2 +- .../servergroup/zz_generated.controller.go | 2 +- .../service/zz_generated.adapter.go | 2 +- .../service/zz_generated.controller.go | 2 +- internal/controllers/subnet/actuator.go | 51 ++----- .../subnet/zz_generated.adapter.go | 2 +- .../subnet/zz_generated.controller.go | 2 +- .../volume/zz_generated.adapter.go | 2 +- .../volume/zz_generated.controller.go | 2 +- .../volumetype/zz_generated.adapter.go | 2 +- .../volumetype/zz_generated.controller.go | 2 +- internal/osclients/compute.go | 9 ++ internal/osclients/mock/compute.go | 17 ++- internal/osclients/mock/doc.go | 2 +- internal/osclients/mock/domain.go | 2 +- internal/osclients/mock/endpoint.go | 2 +- internal/osclients/mock/group.go | 2 +- internal/osclients/mock/identity.go | 2 +- internal/osclients/mock/image.go | 2 +- internal/osclients/mock/keypair.go | 2 +- internal/osclients/mock/networking.go | 2 +- internal/osclients/mock/role.go | 2 +- internal/osclients/mock/service.go | 2 +- internal/osclients/mock/volume.go | 2 +- internal/osclients/mock/volumetype.go | 2 +- internal/util/dependency/helpers.go | 68 +++++++++ .../api/v1alpha1/address.go | 2 +- .../api/v1alpha1/allocationpool.go | 2 +- .../api/v1alpha1/allocationpoolstatus.go | 2 +- .../api/v1alpha1/allowedaddresspair.go | 2 +- .../api/v1alpha1/allowedaddresspairstatus.go | 2 +- .../api/v1alpha1/cloudcredentialsreference.go | 2 +- .../applyconfiguration/api/v1alpha1/domain.go | 2 +- .../api/v1alpha1/domainfilter.go | 2 +- .../api/v1alpha1/domainimport.go | 2 +- .../api/v1alpha1/domainresourcespec.go | 2 +- .../api/v1alpha1/domainresourcestatus.go | 2 +- .../api/v1alpha1/domainspec.go | 2 +- .../api/v1alpha1/domainstatus.go | 2 +- .../api/v1alpha1/endpoint.go | 2 +- .../api/v1alpha1/endpointfilter.go | 2 +- .../api/v1alpha1/endpointimport.go | 2 +- .../api/v1alpha1/endpointresourcespec.go | 20 +-- .../api/v1alpha1/endpointresourcestatus.go | 20 +-- .../api/v1alpha1/endpointspec.go | 2 +- .../api/v1alpha1/endpointstatus.go | 2 +- .../api/v1alpha1/externalgateway.go | 2 +- .../api/v1alpha1/externalgatewaystatus.go | 2 +- .../api/v1alpha1/filterbykeystonetags.go | 2 +- .../api/v1alpha1/filterbyneutrontags.go | 2 +- .../api/v1alpha1/filterbyservertags.go | 2 +- .../api/v1alpha1/fixedipstatus.go | 2 +- .../applyconfiguration/api/v1alpha1/flavor.go | 2 +- .../api/v1alpha1/flavorfilter.go | 2 +- .../api/v1alpha1/flavorimport.go | 2 +- .../api/v1alpha1/flavorresourcespec.go | 2 +- .../api/v1alpha1/flavorresourcestatus.go | 2 +- .../api/v1alpha1/flavorspec.go | 2 +- .../api/v1alpha1/flavorstatus.go | 2 +- .../api/v1alpha1/floatingip.go | 2 +- .../api/v1alpha1/floatingipfilter.go | 2 +- .../api/v1alpha1/floatingipimport.go | 2 +- .../api/v1alpha1/floatingipresourcespec.go | 2 +- .../api/v1alpha1/floatingipresourcestatus.go | 2 +- .../api/v1alpha1/floatingipspec.go | 2 +- .../api/v1alpha1/floatingipstatus.go | 2 +- .../applyconfiguration/api/v1alpha1/group.go | 2 +- .../api/v1alpha1/groupfilter.go | 2 +- .../api/v1alpha1/groupimport.go | 2 +- .../api/v1alpha1/groupresourcespec.go | 2 +- .../api/v1alpha1/groupresourcestatus.go | 2 +- .../api/v1alpha1/groupspec.go | 2 +- .../api/v1alpha1/groupstatus.go | 2 +- .../api/v1alpha1/hostroute.go | 2 +- .../api/v1alpha1/hostroutestatus.go | 2 +- .../applyconfiguration/api/v1alpha1/image.go | 2 +- .../api/v1alpha1/imagecontent.go | 2 +- .../v1alpha1/imagecontentsourcedownload.go | 2 +- .../api/v1alpha1/imagefilter.go | 2 +- .../api/v1alpha1/imagehash.go | 2 +- .../api/v1alpha1/imageimport.go | 2 +- .../api/v1alpha1/imageproperties.go | 2 +- .../api/v1alpha1/imagepropertieshardware.go | 2 +- .../imagepropertiesoperatingsystem.go | 2 +- .../api/v1alpha1/imageresourcespec.go | 2 +- .../api/v1alpha1/imageresourcestatus.go | 2 +- .../api/v1alpha1/imagespec.go | 2 +- .../api/v1alpha1/imagestatus.go | 2 +- .../api/v1alpha1/imagestatusextra.go | 2 +- .../api/v1alpha1/ipv6options.go | 2 +- .../api/v1alpha1/keypair.go | 2 +- .../api/v1alpha1/keypairfilter.go | 2 +- .../api/v1alpha1/keypairimport.go | 2 +- .../api/v1alpha1/keypairresourcespec.go | 2 +- .../api/v1alpha1/keypairresourcestatus.go | 2 +- .../api/v1alpha1/keypairspec.go | 2 +- .../api/v1alpha1/keypairstatus.go | 2 +- .../api/v1alpha1/managedoptions.go | 2 +- .../api/v1alpha1/network.go | 2 +- .../api/v1alpha1/networkfilter.go | 2 +- .../api/v1alpha1/networkimport.go | 2 +- .../api/v1alpha1/networkresourcespec.go | 2 +- .../api/v1alpha1/networkresourcestatus.go | 2 +- .../api/v1alpha1/networkspec.go | 2 +- .../api/v1alpha1/networkstatus.go | 2 +- .../api/v1alpha1/neutronstatusmetadata.go | 2 +- .../applyconfiguration/api/v1alpha1/port.go | 2 +- .../api/v1alpha1/portfilter.go | 2 +- .../api/v1alpha1/portimport.go | 2 +- .../api/v1alpha1/portrangespec.go | 2 +- .../api/v1alpha1/portrangestatus.go | 2 +- .../api/v1alpha1/portresourcespec.go | 11 +- .../api/v1alpha1/portresourcestatus.go | 11 +- .../api/v1alpha1/portspec.go | 2 +- .../api/v1alpha1/portstatus.go | 2 +- .../api/v1alpha1/project.go | 2 +- .../api/v1alpha1/projectfilter.go | 2 +- .../api/v1alpha1/projectimport.go | 2 +- .../api/v1alpha1/projectresourcespec.go | 2 +- .../api/v1alpha1/projectresourcestatus.go | 2 +- .../api/v1alpha1/projectspec.go | 2 +- .../api/v1alpha1/projectstatus.go | 2 +- .../api/v1alpha1/providerpropertiesstatus.go | 2 +- .../applyconfiguration/api/v1alpha1/role.go | 2 +- .../api/v1alpha1/rolefilter.go | 2 +- .../api/v1alpha1/roleimport.go | 2 +- .../api/v1alpha1/roleresourcespec.go | 2 +- .../api/v1alpha1/roleresourcestatus.go | 2 +- .../api/v1alpha1/rolespec.go | 2 +- .../api/v1alpha1/rolestatus.go | 2 +- .../applyconfiguration/api/v1alpha1/router.go | 2 +- .../api/v1alpha1/routerfilter.go | 2 +- .../api/v1alpha1/routerimport.go | 2 +- .../api/v1alpha1/routerinterface.go | 2 +- .../api/v1alpha1/routerinterfacespec.go | 2 +- .../api/v1alpha1/routerinterfacestatus.go | 2 +- .../api/v1alpha1/routerresourcespec.go | 2 +- .../api/v1alpha1/routerresourcestatus.go | 2 +- .../api/v1alpha1/routerspec.go | 2 +- .../api/v1alpha1/routerstatus.go | 2 +- .../api/v1alpha1/securitygroup.go | 2 +- .../api/v1alpha1/securitygroupfilter.go | 2 +- .../api/v1alpha1/securitygroupimport.go | 2 +- .../api/v1alpha1/securitygroupresourcespec.go | 2 +- .../v1alpha1/securitygroupresourcestatus.go | 2 +- .../api/v1alpha1/securitygrouprule.go | 2 +- .../api/v1alpha1/securitygrouprulestatus.go | 2 +- .../api/v1alpha1/securitygroupspec.go | 2 +- .../api/v1alpha1/securitygroupstatus.go | 2 +- .../applyconfiguration/api/v1alpha1/server.go | 2 +- .../api/v1alpha1/serverfilter.go | 2 +- .../api/v1alpha1/servergroup.go | 2 +- .../api/v1alpha1/servergroupfilter.go | 2 +- .../api/v1alpha1/servergroupimport.go | 2 +- .../api/v1alpha1/servergroupresourcespec.go | 2 +- .../api/v1alpha1/servergroupresourcestatus.go | 2 +- .../api/v1alpha1/servergrouprules.go | 2 +- .../api/v1alpha1/servergrouprulesstatus.go | 2 +- .../api/v1alpha1/servergroupspec.go | 2 +- .../api/v1alpha1/servergroupstatus.go | 2 +- .../api/v1alpha1/serverimport.go | 2 +- .../api/v1alpha1/serverinterfacefixedip.go | 2 +- .../api/v1alpha1/serverinterfacestatus.go | 2 +- .../api/v1alpha1/servermetadata.go | 48 ++++++ .../api/v1alpha1/servermetadatastatus.go | 48 ++++++ .../api/v1alpha1/serverportspec.go | 2 +- .../api/v1alpha1/serverresourcespec.go | 25 ++- .../api/v1alpha1/serverresourcestatus.go | 25 ++- .../api/v1alpha1/serverspec.go | 2 +- .../api/v1alpha1/serverstatus.go | 2 +- .../api/v1alpha1/servervolumespec.go | 2 +- .../api/v1alpha1/servervolumestatus.go | 2 +- .../api/v1alpha1/service.go | 2 +- .../api/v1alpha1/servicefilter.go | 2 +- .../api/v1alpha1/serviceimport.go | 2 +- .../api/v1alpha1/serviceresourcespec.go | 2 +- .../api/v1alpha1/serviceresourcestatus.go | 2 +- .../api/v1alpha1/servicespec.go | 2 +- .../api/v1alpha1/servicestatus.go | 2 +- .../applyconfiguration/api/v1alpha1/subnet.go | 2 +- .../api/v1alpha1/subnetfilter.go | 2 +- .../api/v1alpha1/subnetgateway.go | 2 +- .../api/v1alpha1/subnetimport.go | 2 +- .../api/v1alpha1/subnetresourcespec.go | 2 +- .../api/v1alpha1/subnetresourcestatus.go | 2 +- .../api/v1alpha1/subnetspec.go | 2 +- .../api/v1alpha1/subnetstatus.go | 2 +- .../api/v1alpha1/userdataspec.go | 2 +- .../applyconfiguration/api/v1alpha1/volume.go | 2 +- .../api/v1alpha1/volumeattachmentstatus.go | 2 +- .../api/v1alpha1/volumefilter.go | 2 +- .../api/v1alpha1/volumeimport.go | 2 +- .../api/v1alpha1/volumemetadata.go | 2 +- .../api/v1alpha1/volumemetadatastatus.go | 2 +- .../api/v1alpha1/volumeresourcespec.go | 2 +- .../api/v1alpha1/volumeresourcestatus.go | 2 +- .../api/v1alpha1/volumespec.go | 2 +- .../api/v1alpha1/volumestatus.go | 2 +- .../api/v1alpha1/volumetype.go | 2 +- .../api/v1alpha1/volumetypeextraspec.go | 2 +- .../api/v1alpha1/volumetypeextraspecstatus.go | 2 +- .../api/v1alpha1/volumetypefilter.go | 2 +- .../api/v1alpha1/volumetypeimport.go | 2 +- .../api/v1alpha1/volumetyperesourcespec.go | 2 +- .../api/v1alpha1/volumetyperesourcestatus.go | 2 +- .../api/v1alpha1/volumetypespec.go | 2 +- .../api/v1alpha1/volumetypestatus.go | 2 +- .../applyconfiguration/internal/internal.go | 56 ++++++- pkg/clients/applyconfiguration/utils.go | 6 +- pkg/clients/clientset/clientset/clientset.go | 2 +- .../clientset/fake/clientset_generated.go | 2 +- pkg/clients/clientset/clientset/fake/doc.go | 2 +- .../clientset/clientset/fake/register.go | 2 +- pkg/clients/clientset/clientset/scheme/doc.go | 2 +- .../clientset/clientset/scheme/register.go | 2 +- .../typed/api/v1alpha1/api_client.go | 2 +- .../clientset/typed/api/v1alpha1/doc.go | 2 +- .../clientset/typed/api/v1alpha1/domain.go | 2 +- .../clientset/typed/api/v1alpha1/endpoint.go | 2 +- .../clientset/typed/api/v1alpha1/fake/doc.go | 2 +- .../api/v1alpha1/fake/fake_api_client.go | 2 +- .../typed/api/v1alpha1/fake/fake_domain.go | 2 +- .../typed/api/v1alpha1/fake/fake_endpoint.go | 2 +- .../typed/api/v1alpha1/fake/fake_flavor.go | 2 +- .../api/v1alpha1/fake/fake_floatingip.go | 2 +- .../typed/api/v1alpha1/fake/fake_group.go | 2 +- .../typed/api/v1alpha1/fake/fake_image.go | 2 +- .../typed/api/v1alpha1/fake/fake_keypair.go | 2 +- .../typed/api/v1alpha1/fake/fake_network.go | 2 +- .../typed/api/v1alpha1/fake/fake_port.go | 2 +- .../typed/api/v1alpha1/fake/fake_project.go | 2 +- .../typed/api/v1alpha1/fake/fake_role.go | 2 +- .../typed/api/v1alpha1/fake/fake_router.go | 2 +- .../api/v1alpha1/fake/fake_routerinterface.go | 2 +- .../api/v1alpha1/fake/fake_securitygroup.go | 2 +- .../typed/api/v1alpha1/fake/fake_server.go | 2 +- .../api/v1alpha1/fake/fake_servergroup.go | 2 +- .../typed/api/v1alpha1/fake/fake_service.go | 2 +- .../typed/api/v1alpha1/fake/fake_subnet.go | 2 +- .../typed/api/v1alpha1/fake/fake_volume.go | 2 +- .../api/v1alpha1/fake/fake_volumetype.go | 2 +- .../clientset/typed/api/v1alpha1/flavor.go | 2 +- .../typed/api/v1alpha1/floatingip.go | 2 +- .../typed/api/v1alpha1/generated_expansion.go | 2 +- .../clientset/typed/api/v1alpha1/group.go | 2 +- .../clientset/typed/api/v1alpha1/image.go | 2 +- .../clientset/typed/api/v1alpha1/keypair.go | 2 +- .../clientset/typed/api/v1alpha1/network.go | 2 +- .../clientset/typed/api/v1alpha1/port.go | 2 +- .../clientset/typed/api/v1alpha1/project.go | 2 +- .../clientset/typed/api/v1alpha1/role.go | 2 +- .../clientset/typed/api/v1alpha1/router.go | 2 +- .../typed/api/v1alpha1/routerinterface.go | 2 +- .../typed/api/v1alpha1/securitygroup.go | 2 +- .../clientset/typed/api/v1alpha1/server.go | 2 +- .../typed/api/v1alpha1/servergroup.go | 2 +- .../clientset/typed/api/v1alpha1/service.go | 2 +- .../clientset/typed/api/v1alpha1/subnet.go | 2 +- .../clientset/typed/api/v1alpha1/volume.go | 2 +- .../typed/api/v1alpha1/volumetype.go | 2 +- .../externalversions/api/interface.go | 2 +- .../externalversions/api/v1alpha1/domain.go | 2 +- .../externalversions/api/v1alpha1/endpoint.go | 2 +- .../externalversions/api/v1alpha1/flavor.go | 2 +- .../api/v1alpha1/floatingip.go | 2 +- .../externalversions/api/v1alpha1/group.go | 2 +- .../externalversions/api/v1alpha1/image.go | 2 +- .../api/v1alpha1/interface.go | 2 +- .../externalversions/api/v1alpha1/keypair.go | 2 +- .../externalversions/api/v1alpha1/network.go | 2 +- .../externalversions/api/v1alpha1/port.go | 2 +- .../externalversions/api/v1alpha1/project.go | 2 +- .../externalversions/api/v1alpha1/role.go | 2 +- .../externalversions/api/v1alpha1/router.go | 2 +- .../api/v1alpha1/routerinterface.go | 2 +- .../api/v1alpha1/securitygroup.go | 2 +- .../externalversions/api/v1alpha1/server.go | 2 +- .../api/v1alpha1/servergroup.go | 2 +- .../externalversions/api/v1alpha1/service.go | 2 +- .../externalversions/api/v1alpha1/subnet.go | 2 +- .../externalversions/api/v1alpha1/volume.go | 2 +- .../api/v1alpha1/volumetype.go | 2 +- .../informers/externalversions/factory.go | 2 +- .../informers/externalversions/generic.go | 2 +- .../internalinterfaces/factory_interfaces.go | 2 +- pkg/clients/listers/api/v1alpha1/domain.go | 2 +- pkg/clients/listers/api/v1alpha1/endpoint.go | 2 +- .../api/v1alpha1/expansion_generated.go | 2 +- pkg/clients/listers/api/v1alpha1/flavor.go | 2 +- .../listers/api/v1alpha1/floatingip.go | 2 +- pkg/clients/listers/api/v1alpha1/group.go | 2 +- pkg/clients/listers/api/v1alpha1/image.go | 2 +- pkg/clients/listers/api/v1alpha1/keypair.go | 2 +- pkg/clients/listers/api/v1alpha1/network.go | 2 +- pkg/clients/listers/api/v1alpha1/port.go | 2 +- pkg/clients/listers/api/v1alpha1/project.go | 2 +- pkg/clients/listers/api/v1alpha1/role.go | 2 +- pkg/clients/listers/api/v1alpha1/router.go | 2 +- .../listers/api/v1alpha1/routerinterface.go | 2 +- .../listers/api/v1alpha1/securitygroup.go | 2 +- pkg/clients/listers/api/v1alpha1/server.go | 2 +- .../listers/api/v1alpha1/servergroup.go | 2 +- pkg/clients/listers/api/v1alpha1/service.go | 2 +- pkg/clients/listers/api/v1alpha1/subnet.go | 2 +- pkg/clients/listers/api/v1alpha1/volume.go | 2 +- .../listers/api/v1alpha1/volumetype.go | 2 +- website/docs/crd-reference.md | 47 +++++- 414 files changed, 1405 insertions(+), 811 deletions(-) create mode 100644 internal/util/dependency/helpers.go create mode 100644 pkg/clients/applyconfiguration/api/v1alpha1/servermetadata.go create mode 100644 pkg/clients/applyconfiguration/api/v1alpha1/servermetadatastatus.go diff --git a/README.md b/README.md index 93119e063..301be825b 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ kubectl delete -f $ORC_RELEASE ## License -Copyright 2024. +Copyright 2026. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/endpoint_types.go b/api/v1alpha1/endpoint_types.go index 01e512e37..550b3e4cd 100644 --- a/api/v1alpha1/endpoint_types.go +++ b/api/v1alpha1/endpoint_types.go @@ -18,10 +18,11 @@ package v1alpha1 // EndpointResourceSpec contains the desired state of the resource. type EndpointResourceSpec struct { - // name will be the name of the created resource. If not specified, the - // name of the ORC object will be used. + // description is a human-readable description for the resource. + // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MaxLength:=255 // +optional - Name *OpenStackName `json:"name,omitempty"` + Description *string `json:"description,omitempty"` // enabled indicates whether the endpoint is enabled or not. // +kubebuilder:default:=true @@ -64,17 +65,18 @@ type EndpointFilter struct { // EndpointResourceStatus represents the observed state of the resource. type EndpointResourceStatus struct { - // name is a Human-readable name for the resource. Might not be unique. - // +kubebuilder:validation:MaxLength=1024 + // description is a human-readable description for the resource. + // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MaxLength:=255 // +optional - Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` // enabled indicates whether the endpoint is enabled or not. // +optional - Enabled *bool `json:"enabled,omitempty"` + Enabled bool `json:"enabled,omitempty"` // interface indicates the visibility of the endpoint. - // +kubebuilder:validation:Enum:=admin;internal;public + // +kubebuilder:validation:MaxLength=128 // +optional Interface string `json:"interface,omitempty"` diff --git a/api/v1alpha1/port_types.go b/api/v1alpha1/port_types.go index 22ca3ed77..9e51d0153 100644 --- a/api/v1alpha1/port_types.go +++ b/api/v1alpha1/port_types.go @@ -180,6 +180,11 @@ type PortResourceSpec struct { // +kubebuilder:validation:MaxLength=32 // +optional MACAddress string `json:"macAddress,omitempty"` + + // hostID is the ID of host where the port resides. + // +kubebuilder:validation:MaxLength=36 + // +optional + HostID string `json:"hostID,omitempty"` } type PortResourceStatus struct { @@ -272,6 +277,11 @@ type PortResourceStatus struct { // +optional PortSecurityEnabled *bool `json:"portSecurityEnabled,omitempty"` + // hostID is the ID of host where the port resides. + // +kubebuilder:validation:MaxLength=128 + // +optional + HostID string `json:"hostID,omitempty"` + NeutronStatusMetadata `json:",inline"` } diff --git a/api/v1alpha1/server_types.go b/api/v1alpha1/server_types.go index 7fefa5f38..f4f40b279 100644 --- a/api/v1alpha1/server_types.go +++ b/api/v1alpha1/server_types.go @@ -181,6 +181,34 @@ type ServerResourceSpec struct { // +listType=set // +optional Tags []ServerTag `json:"tags,omitempty"` + + // metadata is a list of metadata key-value pairs which will be set on the server. + // +kubebuilder:validation:MaxItems:=128 + // +listType=atomic + // +optional + Metadata []ServerMetadata `json:"metadata,omitempty"` + + // configDrive specifies whether to attach a config drive to the server. + // When true, configuration data will be available via a special drive + // instead of the metadata service. + // +optional + // +kubebuilder:validation:XValidation:rule="self == oldSelf",message="configDrive is immutable" + ConfigDrive *bool `json:"configDrive,omitempty"` +} + +// ServerMetadata represents a key-value pair for server metadata. +type ServerMetadata struct { + // key is the metadata key. + // +kubebuilder:validation:MinLength:=1 + // +kubebuilder:validation:MaxLength:=255 + // +required + Key string `json:"key,omitempty"` + + // value is the metadata value. + // +kubebuilder:validation:MaxLength:=255 + // +kubebuilder:validation:MinLength:=1 + // +required + Value string `json:"value,omitempty"` } // +kubebuilder:validation:MinProperties:=1 @@ -261,4 +289,27 @@ type ServerResourceStatus struct { // +listType=atomic // +optional Tags []string `json:"tags,omitempty"` + + // metadata is the list of metadata key-value pairs on the resource. + // +kubebuilder:validation:MaxItems:=128 + // +listType=atomic + // +optional + Metadata []ServerMetadataStatus `json:"metadata,omitempty"` + + // configDrive indicates whether the server was booted with a config drive. + // +optional + ConfigDrive bool `json:"configDrive,omitempty"` +} + +// ServerMetadataStatus represents a key-value pair for server metadata in status. +type ServerMetadataStatus struct { + // key is the metadata key. + // +kubebuilder:validation:MaxLength:=255 + // +optional + Key string `json:"key,omitempty"` + + // value is the metadata value. + // +kubebuilder:validation:MaxLength:=255 + // +optional + Value string `json:"value,omitempty"` } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index a73d4ff57..8e9682bed 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1,7 +1,7 @@ //go:build !ignore_autogenerated /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -454,9 +454,9 @@ func (in *EndpointList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EndpointResourceSpec) DeepCopyInto(out *EndpointResourceSpec) { *out = *in - if in.Name != nil { - in, out := &in.Name, &out.Name - *out = new(OpenStackName) + if in.Description != nil { + in, out := &in.Description, &out.Description + *out = new(string) **out = **in } if in.Enabled != nil { @@ -479,11 +479,6 @@ func (in *EndpointResourceSpec) DeepCopy() *EndpointResourceSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EndpointResourceStatus) DeepCopyInto(out *EndpointResourceStatus) { *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 EndpointResourceStatus. @@ -545,7 +540,7 @@ func (in *EndpointStatus) DeepCopyInto(out *EndpointStatus) { if in.Resource != nil { in, out := &in.Resource, &out.Resource *out = new(EndpointResourceStatus) - (*in).DeepCopyInto(*out) + **out = **in } } @@ -4406,6 +4401,36 @@ func (in *ServerList) DeepCopyObject() runtime.Object { return nil } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerMetadata) DeepCopyInto(out *ServerMetadata) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerMetadata. +func (in *ServerMetadata) DeepCopy() *ServerMetadata { + if in == nil { + return nil + } + out := new(ServerMetadata) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ServerMetadataStatus) DeepCopyInto(out *ServerMetadataStatus) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerMetadataStatus. +func (in *ServerMetadataStatus) DeepCopy() *ServerMetadataStatus { + if in == nil { + return nil + } + out := new(ServerMetadataStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ServerPortSpec) DeepCopyInto(out *ServerPortSpec) { *out = *in @@ -4468,6 +4493,16 @@ func (in *ServerResourceSpec) DeepCopyInto(out *ServerResourceSpec) { *out = make([]ServerTag, len(*in)) copy(*out, *in) } + if in.Metadata != nil { + in, out := &in.Metadata, &out.Metadata + *out = make([]ServerMetadata, len(*in)) + copy(*out, *in) + } + if in.ConfigDrive != nil { + in, out := &in.ConfigDrive, &out.ConfigDrive + *out = new(bool) + **out = **in + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerResourceSpec. @@ -4505,6 +4540,11 @@ func (in *ServerResourceStatus) DeepCopyInto(out *ServerResourceStatus) { *out = make([]string, len(*in)) copy(*out, *in) } + if in.Metadata != nil { + in, out := &in.Metadata, &out.Metadata + *out = make([]ServerMetadataStatus, len(*in)) + copy(*out, *in) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ServerResourceStatus. diff --git a/api/v1alpha1/zz_generated.domain-resource.go b/api/v1alpha1/zz_generated.domain-resource.go index 60b3357d6..9fd2b85a4 100644 --- a/api/v1alpha1/zz_generated.domain-resource.go +++ b/api/v1alpha1/zz_generated.domain-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.endpoint-resource.go b/api/v1alpha1/zz_generated.endpoint-resource.go index 33bebc76d..bcff24d11 100644 --- a/api/v1alpha1/zz_generated.endpoint-resource.go +++ b/api/v1alpha1/zz_generated.endpoint-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.flavor-resource.go b/api/v1alpha1/zz_generated.flavor-resource.go index 6577cfb64..977264ed2 100644 --- a/api/v1alpha1/zz_generated.flavor-resource.go +++ b/api/v1alpha1/zz_generated.flavor-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.floatingip-resource.go b/api/v1alpha1/zz_generated.floatingip-resource.go index ec90dd026..66993c36e 100644 --- a/api/v1alpha1/zz_generated.floatingip-resource.go +++ b/api/v1alpha1/zz_generated.floatingip-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.group-resource.go b/api/v1alpha1/zz_generated.group-resource.go index c93a74b88..ffee5b120 100644 --- a/api/v1alpha1/zz_generated.group-resource.go +++ b/api/v1alpha1/zz_generated.group-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.image-resource.go b/api/v1alpha1/zz_generated.image-resource.go index 41e5785f1..dc5c80d4d 100644 --- a/api/v1alpha1/zz_generated.image-resource.go +++ b/api/v1alpha1/zz_generated.image-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.keypair-resource.go b/api/v1alpha1/zz_generated.keypair-resource.go index e0e39301a..77f31369a 100644 --- a/api/v1alpha1/zz_generated.keypair-resource.go +++ b/api/v1alpha1/zz_generated.keypair-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.network-resource.go b/api/v1alpha1/zz_generated.network-resource.go index bc5a017b1..6d3a89d85 100644 --- a/api/v1alpha1/zz_generated.network-resource.go +++ b/api/v1alpha1/zz_generated.network-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.port-resource.go b/api/v1alpha1/zz_generated.port-resource.go index 631ec707b..43f9ef7e0 100644 --- a/api/v1alpha1/zz_generated.port-resource.go +++ b/api/v1alpha1/zz_generated.port-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.project-resource.go b/api/v1alpha1/zz_generated.project-resource.go index ffd861f4f..0845855cb 100644 --- a/api/v1alpha1/zz_generated.project-resource.go +++ b/api/v1alpha1/zz_generated.project-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.role-resource.go b/api/v1alpha1/zz_generated.role-resource.go index 6161c0421..20befafe8 100644 --- a/api/v1alpha1/zz_generated.role-resource.go +++ b/api/v1alpha1/zz_generated.role-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.router-resource.go b/api/v1alpha1/zz_generated.router-resource.go index 45ca8887c..bde8905b2 100644 --- a/api/v1alpha1/zz_generated.router-resource.go +++ b/api/v1alpha1/zz_generated.router-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.securitygroup-resource.go b/api/v1alpha1/zz_generated.securitygroup-resource.go index 33f221ec0..babddf920 100644 --- a/api/v1alpha1/zz_generated.securitygroup-resource.go +++ b/api/v1alpha1/zz_generated.securitygroup-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.server-resource.go b/api/v1alpha1/zz_generated.server-resource.go index 347cd2159..db28929e9 100644 --- a/api/v1alpha1/zz_generated.server-resource.go +++ b/api/v1alpha1/zz_generated.server-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.servergroup-resource.go b/api/v1alpha1/zz_generated.servergroup-resource.go index 6bc16a63a..ddc30d8bb 100644 --- a/api/v1alpha1/zz_generated.servergroup-resource.go +++ b/api/v1alpha1/zz_generated.servergroup-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.service-resource.go b/api/v1alpha1/zz_generated.service-resource.go index 93faf35ca..e4cbc2ecf 100644 --- a/api/v1alpha1/zz_generated.service-resource.go +++ b/api/v1alpha1/zz_generated.service-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.subnet-resource.go b/api/v1alpha1/zz_generated.subnet-resource.go index 072cbc307..fdff17f71 100644 --- a/api/v1alpha1/zz_generated.subnet-resource.go +++ b/api/v1alpha1/zz_generated.subnet-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.volume-resource.go b/api/v1alpha1/zz_generated.volume-resource.go index da525c450..ae830727c 100644 --- a/api/v1alpha1/zz_generated.volume-resource.go +++ b/api/v1alpha1/zz_generated.volume-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/api/v1alpha1/zz_generated.volumetype-resource.go b/api/v1alpha1/zz_generated.volumetype-resource.go index e2567a488..bc06ce713 100644 --- a/api/v1alpha1/zz_generated.volumetype-resource.go +++ b/api/v1alpha1/zz_generated.volumetype-resource.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/models-schema/zz_generated.openapi.go b/cmd/models-schema/zz_generated.openapi.go index 224c2f403..21e2863bd 100644 --- a/cmd/models-schema/zz_generated.openapi.go +++ b/cmd/models-schema/zz_generated.openapi.go @@ -2,7 +2,7 @@ // +build !ignore_autogenerated /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -183,6 +183,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerInterfaceFixedIP": schema_openstack_resource_controller_v2_api_v1alpha1_ServerInterfaceFixedIP(ref), "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerInterfaceStatus": schema_openstack_resource_controller_v2_api_v1alpha1_ServerInterfaceStatus(ref), "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerList": schema_openstack_resource_controller_v2_api_v1alpha1_ServerList(ref), + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerMetadata": schema_openstack_resource_controller_v2_api_v1alpha1_ServerMetadata(ref), + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerMetadataStatus": schema_openstack_resource_controller_v2_api_v1alpha1_ServerMetadataStatus(ref), "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerPortSpec": schema_openstack_resource_controller_v2_api_v1alpha1_ServerPortSpec(ref), "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerResourceSpec": schema_openstack_resource_controller_v2_api_v1alpha1_ServerResourceSpec(ref), "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerResourceStatus": schema_openstack_resource_controller_v2_api_v1alpha1_ServerResourceStatus(ref), @@ -1176,9 +1178,9 @@ func schema_openstack_resource_controller_v2_api_v1alpha1_EndpointResourceSpec(r Description: "EndpointResourceSpec contains the desired state of the resource.", Type: []string{"object"}, Properties: map[string]spec.Schema{ - "name": { + "description": { SchemaProps: spec.SchemaProps{ - Description: "name will be the name of the created resource. If not specified, the name of the ORC object will be used.", + Description: "description is a human-readable description for the resource.", Type: []string{"string"}, Format: "", }, @@ -1226,9 +1228,9 @@ func schema_openstack_resource_controller_v2_api_v1alpha1_EndpointResourceStatus Description: "EndpointResourceStatus represents the observed state of the resource.", Type: []string{"object"}, Properties: map[string]spec.Schema{ - "name": { + "description": { SchemaProps: spec.SchemaProps{ - Description: "name is a Human-readable name for the resource. Might not be unique.", + Description: "description is a human-readable description for the resource.", Type: []string{"string"}, Format: "", }, @@ -5278,6 +5280,13 @@ func schema_openstack_resource_controller_v2_api_v1alpha1_PortResourceSpec(ref c Format: "", }, }, + "hostID": { + SchemaProps: spec.SchemaProps{ + Description: "hostID is the ID of host where the port resides.", + Type: []string{"string"}, + Format: "", + }, + }, }, Required: []string{"networkRef"}, }, @@ -5455,6 +5464,13 @@ func schema_openstack_resource_controller_v2_api_v1alpha1_PortResourceStatus(ref Format: "", }, }, + "hostID": { + SchemaProps: spec.SchemaProps{ + Description: "hostID is the ID of host where the port resides.", + Type: []string{"string"}, + Format: "", + }, + }, "createdAt": { SchemaProps: spec.SchemaProps{ Description: "createdAt shows the date and time when the resource was created. The date and time stamp format is ISO 8601", @@ -8462,6 +8478,61 @@ func schema_openstack_resource_controller_v2_api_v1alpha1_ServerList(ref common. } } +func schema_openstack_resource_controller_v2_api_v1alpha1_ServerMetadata(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ServerMetadata represents a key-value pair for server metadata.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "key": { + SchemaProps: spec.SchemaProps{ + Description: "key is the metadata key.", + Type: []string{"string"}, + Format: "", + }, + }, + "value": { + SchemaProps: spec.SchemaProps{ + Description: "value is the metadata value.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"key", "value"}, + }, + }, + } +} + +func schema_openstack_resource_controller_v2_api_v1alpha1_ServerMetadataStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "ServerMetadataStatus represents a key-value pair for server metadata in status.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "key": { + SchemaProps: spec.SchemaProps{ + Description: "key is the metadata key.", + Type: []string{"string"}, + Format: "", + }, + }, + "value": { + SchemaProps: spec.SchemaProps{ + Description: "value is the metadata value.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_openstack_resource_controller_v2_api_v1alpha1_ServerPortSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -8594,12 +8665,38 @@ func schema_openstack_resource_controller_v2_api_v1alpha1_ServerResourceSpec(ref }, }, }, + "metadata": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "metadata is a list of metadata key-value pairs which will be set on the server.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerMetadata"), + }, + }, + }, + }, + }, + "configDrive": { + SchemaProps: spec.SchemaProps{ + Description: "configDrive specifies whether to attach a config drive to the server. When true, configuration data will be available via a special drive instead of the metadata service.", + Type: []string{"boolean"}, + Format: "", + }, + }, }, Required: []string{"imageRef", "flavorRef", "ports"}, }, }, Dependencies: []string{ - "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerPortSpec", "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerVolumeSpec", "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.UserDataSpec"}, + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerMetadata", "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerPortSpec", "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerVolumeSpec", "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.UserDataSpec"}, } } @@ -8723,11 +8820,37 @@ func schema_openstack_resource_controller_v2_api_v1alpha1_ServerResourceStatus(r }, }, }, + "metadata": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "metadata is the list of metadata key-value pairs on the resource.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerMetadataStatus"), + }, + }, + }, + }, + }, + "configDrive": { + SchemaProps: spec.SchemaProps{ + Description: "configDrive indicates whether the server was booted with a config drive.", + Type: []string{"boolean"}, + Format: "", + }, + }, }, }, }, Dependencies: []string{ - "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerInterfaceStatus", "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerVolumeStatus"}, + "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerInterfaceStatus", "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerMetadataStatus", "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1.ServerVolumeStatus"}, } } diff --git a/cmd/resource-generator/data/adapter.template b/cmd/resource-generator/data/adapter.template index 30e7ec827..7bec457ee 100644 --- a/cmd/resource-generator/data/adapter.template +++ b/cmd/resource-generator/data/adapter.template @@ -1,5 +1,5 @@ /* -Copyright {{ .Year }} The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/resource-generator/data/api.template b/cmd/resource-generator/data/api.template index 1abe2bf30..9b1655038 100644 --- a/cmd/resource-generator/data/api.template +++ b/cmd/resource-generator/data/api.template @@ -1,5 +1,5 @@ /* -Copyright {{ .Year }} The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/resource-generator/data/controller.template b/cmd/resource-generator/data/controller.template index 3879f901e..6a57c273d 100644 --- a/cmd/resource-generator/data/controller.template +++ b/cmd/resource-generator/data/controller.template @@ -1,5 +1,5 @@ /* -Copyright {{ .Year }} The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/resource-generator/data/internal-osclients-mock-doc.go.template b/cmd/resource-generator/data/internal-osclients-mock-doc.go.template index 7ff63572c..ba9cfca3e 100644 --- a/cmd/resource-generator/data/internal-osclients-mock-doc.go.template +++ b/cmd/resource-generator/data/internal-osclients-mock-doc.go.template @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/resource-generator/main.go b/cmd/resource-generator/main.go index 7b401f0cb..d2097d195 100644 --- a/cmd/resource-generator/main.go +++ b/cmd/resource-generator/main.go @@ -12,7 +12,6 @@ import ( ) const ( - defaultYear = "2025" defaultAPIVersion = "v1alpha1" ) @@ -54,7 +53,6 @@ type additionalPrintColumn struct { type templateFields struct { APIVersion string - Year string Name string NameLower string IsNotNamed bool @@ -163,7 +161,8 @@ var resources []templateFields = []templateFields{ Name: "Group", }, { - Name: "Endpoint", + Name: "Endpoint", + IsNotNamed: true, }, } @@ -251,10 +250,6 @@ func addDefaults(resources []templateFields) { for i := range resources { resource := &resources[i] - if resource.Year == "" { - resource.Year = defaultYear - } - if resource.APIVersion == "" { resource.APIVersion = defaultAPIVersion } diff --git a/cmd/scaffold-controller/data/api/types.go.template b/cmd/scaffold-controller/data/api/types.go.template index b2cd8ee11..3d3c389b9 100644 --- a/cmd/scaffold-controller/data/api/types.go.template +++ b/cmd/scaffold-controller/data/api/types.go.template @@ -1,5 +1,5 @@ /* -Copyright {{ .Year }} The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/scaffold-controller/data/client/client.go.template b/cmd/scaffold-controller/data/client/client.go.template index c0bebee4d..bba2af076 100644 --- a/cmd/scaffold-controller/data/client/client.go.template +++ b/cmd/scaffold-controller/data/client/client.go.template @@ -1,5 +1,5 @@ /* -Copyright {{ .Year }} The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/scaffold-controller/data/controller/actuator.go.template b/cmd/scaffold-controller/data/controller/actuator.go.template index dc083e79d..ac6c2af62 100644 --- a/cmd/scaffold-controller/data/controller/actuator.go.template +++ b/cmd/scaffold-controller/data/controller/actuator.go.template @@ -1,5 +1,5 @@ /* -Copyright {{ .Year }} The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,9 +25,6 @@ import ( "{{ .GophercloudModule }}" corev1 "k8s.io/api/core/v1" -{{- if len .ImportDependencies }} - apierrors "k8s.io/apimachinery/pkg/api/errors" -{{- end }} "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -37,6 +34,9 @@ import ( "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress" "github.com/k-orc/openstack-resource-controller/v2/internal/logging" "github.com/k-orc/openstack-resource-controller/v2/internal/osclients" +{{- if len .ImportDependencies }} + "github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency" +{{- end }} orcerrors "github.com/k-orc/openstack-resource-controller/v2/internal/util/errors" ) @@ -106,24 +106,12 @@ func (actuator {{ .PackageName }}Actuator) ListOSResourcesForImport(ctx context. var reconcileStatus progress.ReconcileStatus {{- range .ImportDependencies }} {{ $depNameCamelCase := . | camelCase }} - {{ $depNameCamelCase }} := &orcv1alpha1.{{ . }}{} - if filter.{{ . }}Ref != nil { - {{ $depNameCamelCase }}Key := client.ObjectKey{Name: string(*filter.{{ . }}Ref), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, {{ $depNameCamelCase }}Key, {{ $depNameCamelCase }}); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("{{ . }}", {{ $depNameCamelCase }}Key.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching {{ $depNameCamelCase }} %s: %w", {{ $depNameCamelCase }}Key.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable({{ $depNameCamelCase }}) || {{ $depNameCamelCase }}.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("{{ . }}", {{ $depNameCamelCase }}Key.Name, progress.WaitingOnReady)) - } - } - } + {{ $depNameCamelCase }}, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, + filter.{{ . }}Ref, "{{ . }}", + func(dep *orcv1alpha1.{{ . }}) bool { return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) {{- end }} if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { @@ -135,12 +123,12 @@ func (actuator {{ .PackageName }}Actuator) ListOSResourcesForImport(ctx context. Name: string(ptr.Deref(filter.Name, "")), Description: string(ptr.Deref(filter.Description, "")), {{- range .ImportDependencies }} - {{ . }}: ptr.Deref({{ . | camelCase }}.Status.ID, ""), + {{ . }}ID: ptr.Deref({{ . | camelCase }}.Status.ID, ""), {{- end }} // TODO(scaffolding): Add more import filters } - return actuator.osClient.List{{ .Kind }}s(ctx, listOpts), nil + return actuator.osClient.List{{ .Kind }}s(ctx, listOpts), {{ if len .ImportDependencies }}reconcileStatus{{ else }}nil{{ end }} } func (actuator {{ .PackageName }}Actuator) CreateResource(ctx context.Context, obj orcObjectPT) (*osResourceT, progress.ReconcileStatus) { diff --git a/cmd/scaffold-controller/data/controller/actuator_test.go.template b/cmd/scaffold-controller/data/controller/actuator_test.go.template index 2926ee701..59d7e9c31 100644 --- a/cmd/scaffold-controller/data/controller/actuator_test.go.template +++ b/cmd/scaffold-controller/data/controller/actuator_test.go.template @@ -1,5 +1,5 @@ /* -Copyright {{ .Year }} The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/scaffold-controller/data/controller/controller.go.template b/cmd/scaffold-controller/data/controller/controller.go.template index 98d57af78..1fdc04434 100644 --- a/cmd/scaffold-controller/data/controller/controller.go.template +++ b/cmd/scaffold-controller/data/controller/controller.go.template @@ -1,5 +1,5 @@ /* -Copyright {{ .Year }} The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/scaffold-controller/data/controller/status.go.template b/cmd/scaffold-controller/data/controller/status.go.template index ed9890263..98bc23b94 100644 --- a/cmd/scaffold-controller/data/controller/status.go.template +++ b/cmd/scaffold-controller/data/controller/status.go.template @@ -1,5 +1,5 @@ /* -Copyright {{ .Year }} The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/cmd/scaffold-controller/main.go b/cmd/scaffold-controller/main.go index 37ac50c75..03de800d8 100644 --- a/cmd/scaffold-controller/main.go +++ b/cmd/scaffold-controller/main.go @@ -13,7 +13,6 @@ import ( "regexp" "slices" "strings" - "time" "golang.org/x/text/cases" "golang.org/x/text/language" @@ -32,7 +31,6 @@ type templateFields struct { OpenStackJSONObject string AvailablePollingPeriod int DeletingPollingPeriod int - Year int RequiredCreateDependencies strList OptionalCreateDependencies strList AllCreateDependencies strList @@ -180,7 +178,6 @@ func main() { fields.PackageName = strings.ToLower(fields.Kind) fields.GophercloudPackage = path.Base(fields.GophercloudModule) - fields.Year = time.Now().Year() fields.AllCreateDependencies = slices.Concat(fields.RequiredCreateDependencies, fields.OptionalCreateDependencies) render("data/api", filepath.Join("api", "v1alpha1"), &fields) diff --git a/config/crd/bases/openstack.k-orc.cloud_endpoints.yaml b/config/crd/bases/openstack.k-orc.cloud_endpoints.yaml index c2dbddb3d..2b03a96e2 100644 --- a/config/crd/bases/openstack.k-orc.cloud_endpoints.yaml +++ b/config/crd/bases/openstack.k-orc.cloud_endpoints.yaml @@ -155,6 +155,12 @@ spec: resource must be specified if the management policy is `managed`. properties: + description: + description: description is a human-readable description for the + resource. + maxLength: 255 + minLength: 1 + type: string enabled: default: true description: enabled indicates whether the endpoint is enabled @@ -167,14 +173,6 @@ spec: - internal - public type: string - name: - description: |- - name will be the name of the created resource. If not specified, the - name of the ORC object will be used. - maxLength: 255 - minLength: 1 - pattern: ^[^,]+$ - type: string serviceRef: description: serviceRef is a reference to the ORC Service which this resource is associated with. @@ -295,21 +293,19 @@ spec: description: resource contains the observed state of the OpenStack resource. properties: + description: + description: description is a human-readable description for the + resource. + maxLength: 255 + minLength: 1 + type: string enabled: description: enabled indicates whether the endpoint is enabled or not. type: boolean interface: description: interface indicates the visibility of the endpoint. - enum: - - admin - - internal - - public - type: string - name: - description: name is a Human-readable name for the resource. Might - not be unique. - maxLength: 1024 + maxLength: 128 type: string serviceID: description: serviceID is the ID of the Service to which the resource diff --git a/config/crd/bases/openstack.k-orc.cloud_ports.yaml b/config/crd/bases/openstack.k-orc.cloud_ports.yaml index 6b96e097a..c14173d71 100644 --- a/config/crd/bases/openstack.k-orc.cloud_ports.yaml +++ b/config/crd/bases/openstack.k-orc.cloud_ports.yaml @@ -298,6 +298,10 @@ spec: maxLength: 255 minLength: 1 type: string + hostID: + description: hostID is the ID of host where the port resides. + maxLength: 36 + type: string macAddress: description: macAddress is the MAC address of the port. maxLength: 32 @@ -561,6 +565,10 @@ spec: maxItems: 128 type: array x-kubernetes-list-type: atomic + hostID: + description: hostID is the ID of host where the port resides. + maxLength: 128 + type: string macAddress: description: macAddress is the MAC address of the port. maxLength: 1024 diff --git a/config/crd/bases/openstack.k-orc.cloud_servers.yaml b/config/crd/bases/openstack.k-orc.cloud_servers.yaml index c9feaab67..2a882bad3 100644 --- a/config/crd/bases/openstack.k-orc.cloud_servers.yaml +++ b/config/crd/bases/openstack.k-orc.cloud_servers.yaml @@ -202,6 +202,15 @@ spec: x-kubernetes-validations: - message: availabilityZone is immutable rule: self == oldSelf + configDrive: + description: |- + configDrive specifies whether to attach a config drive to the server. + When true, configuration data will be available via a special drive + instead of the metadata service. + type: boolean + x-kubernetes-validations: + - message: configDrive is immutable + rule: self == oldSelf flavorRef: description: flavorRef references the flavor to use for the server instance. @@ -231,6 +240,30 @@ spec: x-kubernetes-validations: - message: keypairRef is immutable rule: self == oldSelf + metadata: + description: metadata is a list of metadata key-value pairs which + will be set on the server. + items: + description: ServerMetadata represents a key-value pair for + server metadata. + properties: + key: + description: key is the metadata key. + maxLength: 255 + minLength: 1 + type: string + value: + description: value is the metadata value. + maxLength: 255 + minLength: 1 + type: string + required: + - key + - value + type: object + maxItems: 128 + type: array + x-kubernetes-list-type: atomic name: description: |- name will be the name of the created resource. If not specified, the @@ -431,6 +464,10 @@ spec: server is located. maxLength: 1024 type: string + configDrive: + description: configDrive indicates whether the server was booted + with a config drive. + type: boolean hostID: description: hostID is the host where the server is located in the cloud. @@ -488,6 +525,25 @@ spec: maxItems: 64 type: array x-kubernetes-list-type: atomic + metadata: + description: metadata is the list of metadata key-value pairs + on the resource. + items: + description: ServerMetadataStatus represents a key-value pair + for server metadata in status. + properties: + key: + description: key is the metadata key. + maxLength: 255 + type: string + value: + description: value is the metadata value. + maxLength: 255 + type: string + type: object + maxItems: 128 + type: array + x-kubernetes-list-type: atomic name: description: name is the human-readable name of the resource. Might not be unique. diff --git a/config/samples/openstack_v1alpha1_server.yaml b/config/samples/openstack_v1alpha1_server.yaml index 29691f536..382d6f9b4 100644 --- a/config/samples/openstack_v1alpha1_server.yaml +++ b/config/samples/openstack_v1alpha1_server.yaml @@ -20,3 +20,9 @@ spec: tags: - tag1 - tag2 + metadata: + - key: environment + value: development + - key: owner + value: sample + configDrive: true diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt index 329a83718..2bdfd71ce 100644 --- a/hack/boilerplate.go.txt +++ b/hack/boilerplate.go.txt @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/domain/zz_generated.adapter.go b/internal/controllers/domain/zz_generated.adapter.go index 89af22535..6a386af72 100644 --- a/internal/controllers/domain/zz_generated.adapter.go +++ b/internal/controllers/domain/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/domain/zz_generated.controller.go b/internal/controllers/domain/zz_generated.controller.go index 31fd025a2..42194e684 100644 --- a/internal/controllers/domain/zz_generated.controller.go +++ b/internal/controllers/domain/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/endpoint/actuator.go b/internal/controllers/endpoint/actuator.go index 1dae97108..ba68d9be1 100644 --- a/internal/controllers/endpoint/actuator.go +++ b/internal/controllers/endpoint/actuator.go @@ -167,9 +167,10 @@ func (actuator endpointActuator) CreateResource(ctx context.Context, obj orcObje return nil, reconcileStatus } createOpts := endpoints.CreateOpts{ - Name: getResourceName(obj), - ServiceID: serviceID, Availability: gophercloud.Availability(resource.Interface), + Description: ptr.Deref(resource.Description, ""), + Enabled: resource.Enabled, + ServiceID: serviceID, URL: resource.URL, } @@ -200,7 +201,7 @@ func (actuator endpointActuator) updateResource(ctx context.Context, obj orcObje updateOpts := endpoints.UpdateOpts{} - handleNameUpdate(&updateOpts, obj, osResource) + handleEnabledUpdate(&updateOpts, resource, osResource) handleURLUpdate(&updateOpts, resource, osResource) handleInterfaceUpdate(&updateOpts, resource, osResource) @@ -239,14 +240,10 @@ func needsUpdate(updateOpts endpoints.UpdateOpts) (bool, error) { updateMap = make(map[string]any) } - return len(updateMap) > 0, nil -} + log := ctrl.LoggerFrom(context.Background()) + log.Info("Description", "updateMap", updateMap) -func handleNameUpdate(updateOpts *endpoints.UpdateOpts, obj orcObjectPT, osResource *osResourceT) { - name := getResourceName(obj) - if osResource.Name != name { - updateOpts.Name = name - } + return len(updateMap) > 0, nil } func handleURLUpdate(updateOpts *endpoints.UpdateOpts, resource *resourceSpecT, osResource *osResourceT) { @@ -263,6 +260,13 @@ func handleInterfaceUpdate(updateOpts *endpoints.UpdateOpts, resource *resourceS } } +func handleEnabledUpdate(updateOpts *endpoints.UpdateOpts, resource *resourceSpecT, osResource *osResourceT) { + enabled := resource.Enabled + if enabled != nil && osResource.Enabled != *enabled { + updateOpts.Enabled = enabled + } +} + func (actuator endpointActuator) GetResourceReconcilers(ctx context.Context, orcObject orcObjectPT, osResource *osResourceT, controller interfaces.ResourceController) ([]resourceReconciler, progress.ReconcileStatus) { return []resourceReconciler{ actuator.updateResource, diff --git a/internal/controllers/endpoint/status.go b/internal/controllers/endpoint/status.go index 22003bb8c..2e570f0cb 100644 --- a/internal/controllers/endpoint/status.go +++ b/internal/controllers/endpoint/status.go @@ -53,8 +53,11 @@ func (endpointStatusWriter) ApplyResourceStatus(log logr.Logger, osResource *osR WithServiceID(osResource.ServiceID). WithEnabled(osResource.Enabled). WithInterface(string(osResource.Availability)). - WithURL(osResource.URL). - WithName(osResource.Name) + WithURL(osResource.URL) + + if osResource.Description != "" { + resourceStatus.WithDescription(osResource.Description) + } statusApply.WithResource(resourceStatus) } diff --git a/internal/controllers/endpoint/tests/endpoint-create-full/00-assert.yaml b/internal/controllers/endpoint/tests/endpoint-create-full/00-assert.yaml index 3507b634b..0c962cfe7 100644 --- a/internal/controllers/endpoint/tests/endpoint-create-full/00-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-create-full/00-assert.yaml @@ -5,10 +5,10 @@ metadata: name: endpoint-create-full status: resource: - name: endpoint-create-full-override + description: "Endpoint description" interface: internal url: https://example.com - #enabled: false + enabled: false conditions: - type: Available status: "True" @@ -31,3 +31,4 @@ resourceRefs: assertAll: - celExpr: "endpoint.status.id != ''" - celExpr: "endpoint.status.resource.serviceID == service.status.id" + - celExpr: "!has(endpoint.status.resource.name)" diff --git a/internal/controllers/endpoint/tests/endpoint-create-full/00-create-resource.yaml b/internal/controllers/endpoint/tests/endpoint-create-full/00-create-resource.yaml index d65438be4..aa7360418 100644 --- a/internal/controllers/endpoint/tests/endpoint-create-full/00-create-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-create-full/00-create-resource.yaml @@ -21,10 +21,8 @@ spec: secretName: openstack-clouds managementPolicy: managed resource: - name: endpoint-create-full-override + description: "Endpoint description" serviceRef: endpoint-create-full interface: internal url: https://example.com - # TODO(winiciusallan): make this field available after - # the next gophercloud minor. - #enabled: false + enabled: false diff --git a/internal/controllers/endpoint/tests/endpoint-create-minimal/00-assert.yaml b/internal/controllers/endpoint/tests/endpoint-create-minimal/00-assert.yaml index 28806601c..3924e2cf7 100644 --- a/internal/controllers/endpoint/tests/endpoint-create-minimal/00-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-create-minimal/00-assert.yaml @@ -5,7 +5,6 @@ metadata: name: endpoint-create-minimal status: resource: - name: endpoint-create-minimal url: http://example.com interface: internal enabled: true @@ -31,3 +30,4 @@ resourceRefs: assertAll: - celExpr: "endpoint.status.id != ''" - celExpr: "endpoint.status.resource.serviceID == service.status.id" + - celExpr: "!has(endpoint.status.resource.name)" diff --git a/internal/controllers/endpoint/tests/endpoint-import/00-import-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import/00-import-resource.yaml index df38e9315..e42eeedd3 100644 --- a/internal/controllers/endpoint/tests/endpoint-import/00-import-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import/00-import-resource.yaml @@ -25,3 +25,4 @@ spec: serviceRef: endpoint-import interface: internal url: http://example.com + enabled: false diff --git a/internal/controllers/endpoint/tests/endpoint-import/01-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import/01-assert.yaml index 9d6a646c4..a7983cc2c 100644 --- a/internal/controllers/endpoint/tests/endpoint-import/01-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import/01-assert.yaml @@ -14,7 +14,6 @@ status: status: "False" reason: Success resource: - name: endpoint-import-external-not-this-one interface: internal url: http://example.com --- diff --git a/internal/controllers/endpoint/tests/endpoint-import/02-assert.yaml b/internal/controllers/endpoint/tests/endpoint-import/02-assert.yaml index a66d66a46..a776882ab 100644 --- a/internal/controllers/endpoint/tests/endpoint-import/02-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import/02-assert.yaml @@ -32,7 +32,6 @@ status: status: "False" reason: Success resource: - name: endpoint-import-external interface: internal url: http://example.com - #enabled: true + enabled: false diff --git a/internal/controllers/endpoint/tests/endpoint-import/02-create-resource.yaml b/internal/controllers/endpoint/tests/endpoint-import/02-create-resource.yaml index 5b67ce9d5..499ff7783 100644 --- a/internal/controllers/endpoint/tests/endpoint-import/02-create-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-import/02-create-resource.yaml @@ -12,3 +12,4 @@ spec: serviceRef: endpoint-import interface: internal url: http://example.com + enabled: false diff --git a/internal/controllers/endpoint/tests/endpoint-update/00-assert.yaml b/internal/controllers/endpoint/tests/endpoint-update/00-assert.yaml index 76532138b..0714459c2 100644 --- a/internal/controllers/endpoint/tests/endpoint-update/00-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-update/00-assert.yaml @@ -5,10 +5,9 @@ metadata: name: endpoint-update status: resource: - name: endpoint-update interface: internal url: http://example.com - enabled: true + enabled: false conditions: - type: Available status: "True" @@ -30,3 +29,5 @@ resourceRefs: ref: service assertAll: - celExpr: "endpoint.status.resource.serviceID == service.status.id" + - celExpr: "!has(endpoint.status.resource.name)" + - celExpr: "!has(endpoint.status.resource.description)" diff --git a/internal/controllers/endpoint/tests/endpoint-update/00-minimal-resource.yaml b/internal/controllers/endpoint/tests/endpoint-update/00-minimal-resource.yaml index cfa64972e..535c94d1a 100644 --- a/internal/controllers/endpoint/tests/endpoint-update/00-minimal-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-update/00-minimal-resource.yaml @@ -24,3 +24,6 @@ spec: serviceRef: endpoint-update interface: internal url: http://example.com + # Set a different value than the default so we can update it + # later. + enabled: false diff --git a/internal/controllers/endpoint/tests/endpoint-update/01-assert.yaml b/internal/controllers/endpoint/tests/endpoint-update/01-assert.yaml index 94ced3887..4d03c34d6 100644 --- a/internal/controllers/endpoint/tests/endpoint-update/01-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-update/01-assert.yaml @@ -5,10 +5,9 @@ metadata: name: endpoint-update status: resource: - name: endpoint-update-updated interface: public url: http://example.com/updated - #enabled: true + enabled: true conditions: - type: Available status: "True" diff --git a/internal/controllers/endpoint/tests/endpoint-update/01-updated-resource.yaml b/internal/controllers/endpoint/tests/endpoint-update/01-updated-resource.yaml index bd1374ea5..c95d344e3 100644 --- a/internal/controllers/endpoint/tests/endpoint-update/01-updated-resource.yaml +++ b/internal/controllers/endpoint/tests/endpoint-update/01-updated-resource.yaml @@ -5,9 +5,6 @@ metadata: name: endpoint-update spec: resource: - name: endpoint-update-updated interface: public url: http://example.com/updated - # TODO(winiciusallan): change it later. - #enabled: true - + enabled: true diff --git a/internal/controllers/endpoint/tests/endpoint-update/02-assert.yaml b/internal/controllers/endpoint/tests/endpoint-update/02-assert.yaml index 64ee33bd4..f41c5016e 100644 --- a/internal/controllers/endpoint/tests/endpoint-update/02-assert.yaml +++ b/internal/controllers/endpoint/tests/endpoint-update/02-assert.yaml @@ -12,6 +12,8 @@ resourceRefs: ref: service assertAll: - celExpr: "endpoint.status.resource.serviceID == service.status.id" + - celExpr: "!has(endpoint.status.resource.name)" + - celExpr: "!has(endpoint.status.resource.description)" --- apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Endpoint @@ -19,10 +21,9 @@ metadata: name: endpoint-update status: resource: - name: endpoint-update interface: internal url: http://example.com - #enabled: true + enabled: false conditions: - type: Available status: "True" diff --git a/internal/controllers/endpoint/zz_generated.adapter.go b/internal/controllers/endpoint/zz_generated.adapter.go index 934d9b7da..fe95ab43f 100644 --- a/internal/controllers/endpoint/zz_generated.adapter.go +++ b/internal/controllers/endpoint/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -76,13 +76,3 @@ func (f adapterT) GetImportFilter() *filterT { } return f.Spec.Import.Filter } - -// getResourceName returns the name of the OpenStack resource we should use. -// This method is not implemented as part of APIObjectAdapter as it is intended -// to be used by resource actuators, which don't use the adapter. -func getResourceName(orcObject orcObjectPT) string { - if orcObject.Spec.Resource.Name != nil { - return string(*orcObject.Spec.Resource.Name) - } - return orcObject.Name -} diff --git a/internal/controllers/endpoint/zz_generated.controller.go b/internal/controllers/endpoint/zz_generated.controller.go index 1dd55a109..e0ccac2f9 100644 --- a/internal/controllers/endpoint/zz_generated.controller.go +++ b/internal/controllers/endpoint/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/flavor/zz_generated.adapter.go b/internal/controllers/flavor/zz_generated.adapter.go index c82b74162..936fc6735 100644 --- a/internal/controllers/flavor/zz_generated.adapter.go +++ b/internal/controllers/flavor/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/flavor/zz_generated.controller.go b/internal/controllers/flavor/zz_generated.controller.go index 38cf8b85c..675989cc0 100644 --- a/internal/controllers/flavor/zz_generated.controller.go +++ b/internal/controllers/flavor/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/floatingip/actuator.go b/internal/controllers/floatingip/actuator.go index 05a15a061..8a99c564e 100644 --- a/internal/controllers/floatingip/actuator.go +++ b/internal/controllers/floatingip/actuator.go @@ -18,7 +18,6 @@ package floatingip import ( "context" - "fmt" "iter" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/layer3/floatingips" @@ -27,10 +26,10 @@ import ( "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress" "github.com/k-orc/openstack-resource-controller/v2/internal/logging" osclients "github.com/k-orc/openstack-resource-controller/v2/internal/osclients" + "github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency" orcerrors "github.com/k-orc/openstack-resource-controller/v2/internal/util/errors" "github.com/k-orc/openstack-resource-controller/v2/internal/util/tags" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -89,62 +88,29 @@ func (actuator floatingipActuator) ListOSResourcesForAdoption(ctx context.Contex func (actuator floatingipCreateActuator) ListOSResourcesForImport(ctx context.Context, obj orcObjectPT, filter filterT) (iter.Seq2[*osResourceT, error], progress.ReconcileStatus) { var reconcileStatus progress.ReconcileStatus - network := &orcv1alpha1.Network{} - if filter.FloatingNetworkRef != nil { - networkKey := client.ObjectKey{Name: string(ptr.Deref(filter.FloatingNetworkRef, "")), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, networkKey, network); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Network", networkKey.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching network %s: %w", networkKey.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable(network) || network.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Network", networkKey.Name, progress.WaitingOnReady)) - } - } - } - - port := &orcv1alpha1.Port{} - if filter.PortRef != nil { - portKey := client.ObjectKey{Name: string(ptr.Deref(filter.PortRef, "")), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, portKey, port); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Port", portKey.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching port %s: %w", portKey.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable(port) || port.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Port", portKey.Name, progress.WaitingOnReady)) - } - } - } - - project := &orcv1alpha1.Project{} - if filter.ProjectRef != nil { - projectKey := client.ObjectKey{Name: string(*filter.ProjectRef), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, projectKey, project); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Project", projectKey.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching project %s: %w", projectKey.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable(project) || project.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Project", projectKey.Name, progress.WaitingOnReady)) - } - } - } + network, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, filter.FloatingNetworkRef, "Network", + func(dep *orcv1alpha1.Network) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) + + port, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, filter.PortRef, "Port", + func(dep *orcv1alpha1.Port) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) + + project, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, filter.ProjectRef, "Project", + func(dep *orcv1alpha1.Project) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { return nil, reconcileStatus diff --git a/internal/controllers/floatingip/zz_generated.adapter.go b/internal/controllers/floatingip/zz_generated.adapter.go index 2c4796f71..c0ff372fb 100644 --- a/internal/controllers/floatingip/zz_generated.adapter.go +++ b/internal/controllers/floatingip/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/floatingip/zz_generated.controller.go b/internal/controllers/floatingip/zz_generated.controller.go index 223181f4c..9d3324464 100644 --- a/internal/controllers/floatingip/zz_generated.controller.go +++ b/internal/controllers/floatingip/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/group/actuator.go b/internal/controllers/group/actuator.go index 268cd2fd3..afdaad252 100644 --- a/internal/controllers/group/actuator.go +++ b/internal/controllers/group/actuator.go @@ -18,12 +18,10 @@ package group import ( "context" - "fmt" "iter" "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/groups" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -33,6 +31,7 @@ import ( "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress" "github.com/k-orc/openstack-resource-controller/v2/internal/logging" "github.com/k-orc/openstack-resource-controller/v2/internal/osclients" + "github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency" orcerrors "github.com/k-orc/openstack-resource-controller/v2/internal/util/errors" ) @@ -83,24 +82,13 @@ func (actuator groupActuator) ListOSResourcesForImport(ctx context.Context, obj var reconcileStatus progress.ReconcileStatus - domain := &orcv1alpha1.Domain{} - if filter.DomainRef != nil { - domainKey := client.ObjectKey{Name: string(*filter.DomainRef), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, domainKey, domain); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Domain", domainKey.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching domain %s: %w", domainKey.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable(domain) || domain.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Domain", domainKey.Name, progress.WaitingOnReady)) - } - } - } + domain, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, filter.DomainRef, "Domain", + func(dep *orcv1alpha1.Domain) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { return nil, reconcileStatus diff --git a/internal/controllers/group/zz_generated.adapter.go b/internal/controllers/group/zz_generated.adapter.go index 48d281caf..be06e584f 100644 --- a/internal/controllers/group/zz_generated.adapter.go +++ b/internal/controllers/group/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/group/zz_generated.controller.go b/internal/controllers/group/zz_generated.controller.go index 572c0f289..39e06261a 100644 --- a/internal/controllers/group/zz_generated.controller.go +++ b/internal/controllers/group/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/image/zz_generated.adapter.go b/internal/controllers/image/zz_generated.adapter.go index c81752969..fe096571b 100644 --- a/internal/controllers/image/zz_generated.adapter.go +++ b/internal/controllers/image/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/image/zz_generated.controller.go b/internal/controllers/image/zz_generated.controller.go index 73bfa7160..a980a5c4f 100644 --- a/internal/controllers/image/zz_generated.controller.go +++ b/internal/controllers/image/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/keypair/zz_generated.adapter.go b/internal/controllers/keypair/zz_generated.adapter.go index 9b71b893a..d3b72644c 100644 --- a/internal/controllers/keypair/zz_generated.adapter.go +++ b/internal/controllers/keypair/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/keypair/zz_generated.controller.go b/internal/controllers/keypair/zz_generated.controller.go index 95bb9f371..c3bdcda17 100644 --- a/internal/controllers/keypair/zz_generated.controller.go +++ b/internal/controllers/keypair/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/network/actuator.go b/internal/controllers/network/actuator.go index 8d7f1eeed..ffb7a147b 100644 --- a/internal/controllers/network/actuator.go +++ b/internal/controllers/network/actuator.go @@ -18,7 +18,6 @@ package network import ( "context" - "fmt" "iter" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/dns" @@ -27,7 +26,6 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/portsecurity" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/networks" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -37,6 +35,7 @@ import ( "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress" "github.com/k-orc/openstack-resource-controller/v2/internal/logging" "github.com/k-orc/openstack-resource-controller/v2/internal/osclients" + "github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency" orcerrors "github.com/k-orc/openstack-resource-controller/v2/internal/util/errors" "github.com/k-orc/openstack-resource-controller/v2/internal/util/tags" ) @@ -84,24 +83,13 @@ func (actuator networkActuator) ListOSResourcesForAdoption(ctx context.Context, func (actuator networkActuator) ListOSResourcesForImport(ctx context.Context, obj orcObjectPT, filter filterT) (iter.Seq2[*osResourceT, error], progress.ReconcileStatus) { var reconcileStatus progress.ReconcileStatus - project := &orcv1alpha1.Project{} - if filter.ProjectRef != nil { - projectKey := client.ObjectKey{Name: string(*filter.ProjectRef), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, projectKey, project); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Project", projectKey.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching project %s: %w", projectKey.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable(project) || project.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Project", projectKey.Name, progress.WaitingOnReady)) - } - } - } + project, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, filter.ProjectRef, "Project", + func(dep *orcv1alpha1.Project) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { return nil, reconcileStatus diff --git a/internal/controllers/network/zz_generated.adapter.go b/internal/controllers/network/zz_generated.adapter.go index 647cec323..771518735 100644 --- a/internal/controllers/network/zz_generated.adapter.go +++ b/internal/controllers/network/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/network/zz_generated.controller.go b/internal/controllers/network/zz_generated.controller.go index e2b23d0d9..f054559f0 100644 --- a/internal/controllers/network/zz_generated.controller.go +++ b/internal/controllers/network/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/port/actuator.go b/internal/controllers/port/actuator.go index 61c23c7b5..822f6a5be 100644 --- a/internal/controllers/port/actuator.go +++ b/internal/controllers/port/actuator.go @@ -27,7 +27,6 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/portsecurity" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/ports" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -37,6 +36,7 @@ import ( "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress" "github.com/k-orc/openstack-resource-controller/v2/internal/logging" osclients "github.com/k-orc/openstack-resource-controller/v2/internal/osclients" + "github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency" orcerrors "github.com/k-orc/openstack-resource-controller/v2/internal/util/errors" "github.com/k-orc/openstack-resource-controller/v2/internal/util/tags" ) @@ -89,43 +89,21 @@ func (actuator portActuator) ListOSResourcesForAdoption(ctx context.Context, obj func (actuator portActuator) ListOSResourcesForImport(ctx context.Context, obj orcObjectPT, filter filterT) (iter.Seq2[*osResourceT, error], progress.ReconcileStatus) { var reconcileStatus progress.ReconcileStatus - network := &orcv1alpha1.Network{} - if filter.NetworkRef != "" { - networkKey := client.ObjectKey{Name: string(filter.NetworkRef), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, networkKey, network); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Network", networkKey.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching network %s: %w", networkKey.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable(network) || network.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Network", networkKey.Name, progress.WaitingOnReady)) - } - } - } + network, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, &filter.NetworkRef, "Network", + func(dep *orcv1alpha1.Network) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) - project := &orcv1alpha1.Project{} - if filter.ProjectRef != nil { - projectKey := client.ObjectKey{Name: string(*filter.ProjectRef), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, projectKey, project); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Project", projectKey.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching project %s: %w", projectKey.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable(project) || project.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Project", projectKey.Name, progress.WaitingOnReady)) - } - } - } + project, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, filter.ProjectRef, "Project", + func(dep *orcv1alpha1.Project) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { return nil, reconcileStatus @@ -254,6 +232,7 @@ func (actuator portActuator) CreateResource(ctx context.Context, obj *orcv1alpha portsBindingOpts := portsbinding.CreateOptsExt{ CreateOptsBuilder: createOpts, VNICType: resource.VNICType, + HostID: resource.HostID, } portSecurityOpts := portsecurity.PortCreateOptsExt{ @@ -504,6 +483,16 @@ func handlePortBindingUpdate(updateOpts ports.UpdateOptsBuilder, resource *resou } } } + + if resource.HostID != "" { + if resource.HostID != osResource.HostID { + updateOpts = &portsbinding.UpdateOptsExt{ + UpdateOptsBuilder: updateOpts, + HostID: &resource.HostID, + } + } + } + return updateOpts } diff --git a/internal/controllers/port/status.go b/internal/controllers/port/status.go index e193b9fb1..379e91e70 100644 --- a/internal/controllers/port/status.go +++ b/internal/controllers/port/status.go @@ -72,7 +72,8 @@ func (portStatusWriter) ApplyResourceStatus(log logr.Logger, osResource *osResou WithPortSecurityEnabled(osResource.PortSecurityEnabled). WithRevisionNumber(int64(osResource.RevisionNumber)). WithCreatedAt(metav1.NewTime(osResource.CreatedAt)). - WithUpdatedAt(metav1.NewTime(osResource.UpdatedAt)) + WithUpdatedAt(metav1.NewTime(osResource.UpdatedAt)). + WithHostID(osResource.HostID) if osResource.Description != "" { resourceStatus.WithDescription(osResource.Description) diff --git a/internal/controllers/port/tests/port-create-full/00-assert.yaml b/internal/controllers/port/tests/port-create-full/00-assert.yaml index 3c866dbb6..f026eea4a 100644 --- a/internal/controllers/port/tests/port-create-full/00-assert.yaml +++ b/internal/controllers/port/tests/port-create-full/00-assert.yaml @@ -14,8 +14,9 @@ status: portSecurityEnabled: true propagateUplinkStatus: false status: DOWN - vnicType: direct + vnicType: macvtap macAddress: fa:16:3e:23:fd:d7 + hostID: devstack tags: - tag1 --- diff --git a/internal/controllers/port/tests/port-create-full/00-create-resource.yaml b/internal/controllers/port/tests/port-create-full/00-create-resource.yaml index 1721a83a1..bbb52641d 100644 --- a/internal/controllers/port/tests/port-create-full/00-create-resource.yaml +++ b/internal/controllers/port/tests/port-create-full/00-create-resource.yaml @@ -82,6 +82,7 @@ spec: - subnetRef: port-create-full ip: 192.168.155.122 portSecurity: Enabled - vnicType: direct + vnicType: macvtap projectRef: port-create-full macAddress: fa:16:3e:23:fd:d7 + hostID: devstack diff --git a/internal/controllers/port/tests/port-update/00-assert.yaml b/internal/controllers/port/tests/port-update/00-assert.yaml index fef380932..6ec7e451d 100644 --- a/internal/controllers/port/tests/port-update/00-assert.yaml +++ b/internal/controllers/port/tests/port-update/00-assert.yaml @@ -6,6 +6,10 @@ resourceRefs: kind: port name: port-update ref: port + - apiVersion: openstack.k-orc.cloud/v1alpha1 + kind: port + name: port-update-admin + ref: portAdmin assertAll: - celExpr: "port.status.id != ''" - celExpr: "port.status.resource.createdAt != ''" @@ -13,6 +17,9 @@ assertAll: - celExpr: "port.status.resource.macAddress != ''" - celExpr: "!has(port.status.resource.fixedIPs)" - celExpr: "!has(port.status.resource.description)" + # Following the network API reference, the default value for + # hostID field is an empty string. + - celExpr: "portAdmin.status.resource.hostID == ''" --- apiVersion: openstack.k-orc.cloud/v1alpha1 kind: Port @@ -36,3 +43,26 @@ status: message: OpenStack resource is up to date status: "False" reason: Success +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Port +metadata: + name: port-update-admin +status: + resource: + name: port-update-admin + adminStateUp: true + portSecurityEnabled: true + propagateUplinkStatus: false + revisionNumber: 1 + status: DOWN + vnicType: normal + conditions: + - type: Available + message: OpenStack resource is available + status: "True" + reason: Success + - type: Progressing + message: OpenStack resource is up to date + status: "False" + reason: Success diff --git a/internal/controllers/port/tests/port-update/00-minimal-resource.yaml b/internal/controllers/port/tests/port-update/00-minimal-resource.yaml index d1242e77f..03bbe59c3 100644 --- a/internal/controllers/port/tests/port-update/00-minimal-resource.yaml +++ b/internal/controllers/port/tests/port-update/00-minimal-resource.yaml @@ -12,3 +12,17 @@ spec: portSecurity: Disabled # Need to set the default values to revert them correctly in the 02-revert-resource step. vnicType: normal +--- +# This port is intended to be used only to test fields editable +# by admin users +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Port +metadata: + name: port-update-admin +spec: + cloudCredentialsRef: + cloudName: openstack-admin + secretName: openstack-clouds + managementPolicy: managed + resource: + networkRef: port-update diff --git a/internal/controllers/port/tests/port-update/01-assert.yaml b/internal/controllers/port/tests/port-update/01-assert.yaml index ef7850e61..1bcaf2d7f 100644 --- a/internal/controllers/port/tests/port-update/01-assert.yaml +++ b/internal/controllers/port/tests/port-update/01-assert.yaml @@ -48,4 +48,19 @@ status: reason: Success - type: Progressing status: "False" - reason: Success \ No newline at end of file + reason: Success +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Port +metadata: + name: port-update-admin +status: + resource: + hostID: devstack + conditions: + - type: Available + status: "True" + reason: Success + - type: Progressing + status: "False" + reason: Success diff --git a/internal/controllers/port/tests/port-update/01-updated-resource.yaml b/internal/controllers/port/tests/port-update/01-updated-resource.yaml index 796726336..107b4ab5d 100644 --- a/internal/controllers/port/tests/port-update/01-updated-resource.yaml +++ b/internal/controllers/port/tests/port-update/01-updated-resource.yaml @@ -19,4 +19,16 @@ spec: tags: - tag1 vnicType: direct - portSecurity: Enabled \ No newline at end of file + portSecurity: Enabled +--- +apiVersion: openstack.k-orc.cloud/v1alpha1 +kind: Port +metadata: + name: port-update-admin +spec: + cloudCredentialsRef: + cloudName: openstack-admin + secretName: openstack-clouds + managementPolicy: managed + resource: + hostID: devstack diff --git a/internal/controllers/port/tests/port-update/02-reverted-resource.yaml b/internal/controllers/port/tests/port-update/02-reverted-resource.yaml index ec043aae6..2c6c253ff 100644 --- a/internal/controllers/port/tests/port-update/02-reverted-resource.yaml +++ b/internal/controllers/port/tests/port-update/02-reverted-resource.yaml @@ -4,4 +4,4 @@ apiVersion: kuttl.dev/v1beta1 kind: TestStep commands: - command: kubectl replace -f 00-minimal-resource.yaml - namespaced: true \ No newline at end of file + namespaced: true diff --git a/internal/controllers/port/zz_generated.adapter.go b/internal/controllers/port/zz_generated.adapter.go index e9ca55c79..1cafbd343 100644 --- a/internal/controllers/port/zz_generated.adapter.go +++ b/internal/controllers/port/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/port/zz_generated.controller.go b/internal/controllers/port/zz_generated.controller.go index 290986682..160f732dc 100644 --- a/internal/controllers/port/zz_generated.controller.go +++ b/internal/controllers/port/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/project/zz_generated.adapter.go b/internal/controllers/project/zz_generated.adapter.go index 0d6afee56..fea8a21c1 100644 --- a/internal/controllers/project/zz_generated.adapter.go +++ b/internal/controllers/project/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/project/zz_generated.controller.go b/internal/controllers/project/zz_generated.controller.go index 34984c633..7660eb2bb 100644 --- a/internal/controllers/project/zz_generated.controller.go +++ b/internal/controllers/project/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/role/actuator.go b/internal/controllers/role/actuator.go index b278cdd8d..ba3be6b75 100644 --- a/internal/controllers/role/actuator.go +++ b/internal/controllers/role/actuator.go @@ -18,12 +18,11 @@ package role import ( "context" - "fmt" "iter" "github.com/gophercloud/gophercloud/v2/openstack/identity/v3/roles" + "github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -82,24 +81,13 @@ func (actuator roleActuator) ListOSResourcesForAdoption(ctx context.Context, orc func (actuator roleActuator) ListOSResourcesForImport(ctx context.Context, obj orcObjectPT, filter filterT) (iter.Seq2[*osResourceT, error], progress.ReconcileStatus) { var reconcileStatus progress.ReconcileStatus - domain := &orcv1alpha1.Domain{} - if filter.DomainRef != nil { - domainKey := client.ObjectKey{Name: string(*filter.DomainRef), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, domainKey, domain); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Domain", domainKey.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching domain %s: %w", domainKey.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable(domain) || domain.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Domain", domainKey.Name, progress.WaitingOnReady)) - } - } - } + domain, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, filter.DomainRef, "Domain", + func(dep *orcv1alpha1.Domain) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { return nil, reconcileStatus diff --git a/internal/controllers/role/zz_generated.adapter.go b/internal/controllers/role/zz_generated.adapter.go index 3c98f6eca..5587b85d4 100644 --- a/internal/controllers/role/zz_generated.adapter.go +++ b/internal/controllers/role/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/role/zz_generated.controller.go b/internal/controllers/role/zz_generated.controller.go index e3caa1f35..bc7cce067 100644 --- a/internal/controllers/role/zz_generated.controller.go +++ b/internal/controllers/role/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/router/actuator.go b/internal/controllers/router/actuator.go index 04c1d491b..59768482e 100644 --- a/internal/controllers/router/actuator.go +++ b/internal/controllers/router/actuator.go @@ -18,12 +18,10 @@ package router import ( "context" - "fmt" "iter" "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/layer3/routers" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -33,6 +31,7 @@ import ( "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress" "github.com/k-orc/openstack-resource-controller/v2/internal/logging" osclients "github.com/k-orc/openstack-resource-controller/v2/internal/osclients" + "github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency" orcerrors "github.com/k-orc/openstack-resource-controller/v2/internal/util/errors" "github.com/k-orc/openstack-resource-controller/v2/internal/util/tags" ) @@ -84,24 +83,13 @@ func (actuator routerActuator) ListOSResourcesForAdoption(ctx context.Context, o func (actuator routerCreateActuator) ListOSResourcesForImport(ctx context.Context, obj orcObjectPT, filter filterT) (iter.Seq2[*osResourceT, error], progress.ReconcileStatus) { var reconcileStatus progress.ReconcileStatus - project := &orcv1alpha1.Project{} - if filter.ProjectRef != nil { - projectKey := client.ObjectKey{Name: string(*filter.ProjectRef), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, projectKey, project); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Project", projectKey.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching project %s: %w", projectKey.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable(project) || project.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Project", projectKey.Name, progress.WaitingOnReady)) - } - } - } + project, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, filter.ProjectRef, "Project", + func(dep *orcv1alpha1.Project) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { return nil, reconcileStatus diff --git a/internal/controllers/router/zz_generated.adapter.go b/internal/controllers/router/zz_generated.adapter.go index 27f6b7339..ccab08587 100644 --- a/internal/controllers/router/zz_generated.adapter.go +++ b/internal/controllers/router/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/router/zz_generated.controller.go b/internal/controllers/router/zz_generated.controller.go index 255858fc5..71e247334 100644 --- a/internal/controllers/router/zz_generated.controller.go +++ b/internal/controllers/router/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/securitygroup/actuator.go b/internal/controllers/securitygroup/actuator.go index b7165e595..703f25c7c 100644 --- a/internal/controllers/securitygroup/actuator.go +++ b/internal/controllers/securitygroup/actuator.go @@ -29,10 +29,10 @@ import ( "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress" "github.com/k-orc/openstack-resource-controller/v2/internal/logging" osclients "github.com/k-orc/openstack-resource-controller/v2/internal/osclients" + "github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency" orcerrors "github.com/k-orc/openstack-resource-controller/v2/internal/util/errors" "github.com/k-orc/openstack-resource-controller/v2/internal/util/tags" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/utils/ptr" "k8s.io/utils/set" ctrl "sigs.k8s.io/controller-runtime" @@ -82,24 +82,13 @@ func (actuator securityGroupActuator) ListOSResourcesForAdoption(ctx context.Con func (actuator securityGroupActuator) ListOSResourcesForImport(ctx context.Context, obj orcObjectPT, filter filterT) (iter.Seq2[*osResourceT, error], progress.ReconcileStatus) { var reconcileStatus progress.ReconcileStatus - project := &orcv1alpha1.Project{} - if filter.ProjectRef != nil { - projectKey := client.ObjectKey{Name: string(*filter.ProjectRef), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, projectKey, project); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Project", projectKey.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching project %s: %w", projectKey.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable(project) || project.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Project", projectKey.Name, progress.WaitingOnReady)) - } - } - } + project, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, filter.ProjectRef, "Project", + func(dep *orcv1alpha1.Project) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { return nil, reconcileStatus diff --git a/internal/controllers/securitygroup/zz_generated.adapter.go b/internal/controllers/securitygroup/zz_generated.adapter.go index eb98fad70..1b055740c 100644 --- a/internal/controllers/securitygroup/zz_generated.adapter.go +++ b/internal/controllers/securitygroup/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/securitygroup/zz_generated.controller.go b/internal/controllers/securitygroup/zz_generated.controller.go index d6a0449a7..e3477ad53 100644 --- a/internal/controllers/securitygroup/zz_generated.controller.go +++ b/internal/controllers/securitygroup/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/server/actuator.go b/internal/controllers/server/actuator.go index 6a2118695..acadd0be1 100644 --- a/internal/controllers/server/actuator.go +++ b/internal/controllers/server/actuator.go @@ -29,7 +29,6 @@ import ( "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/servers" "github.com/gophercloud/gophercloud/v2/openstack/compute/v2/volumeattach" corev1 "k8s.io/api/core/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/utils/ptr" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" @@ -39,6 +38,7 @@ import ( "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress" "github.com/k-orc/openstack-resource-controller/v2/internal/logging" "github.com/k-orc/openstack-resource-controller/v2/internal/osclients" + "github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency" orcerrors "github.com/k-orc/openstack-resource-controller/v2/internal/util/errors" "github.com/k-orc/openstack-resource-controller/v2/internal/util/tags" ) @@ -150,69 +150,6 @@ func (actuator serverActuator) ListOSResourcesForImport(ctx context.Context, obj return wrapServers(actuator.osClient.ListServers(ctx, listOpts)), nil } -// getDependencyHelper is a generic helper for fetching and validating dependencies -func getDependencyHelper[T client.Object]( - ctx context.Context, - k8sClient client.Client, - obj *orcv1alpha1.Server, - name string, - kind string, - isReady func(T) bool, - dep T, -) (T, progress.ReconcileStatus) { - objectKey := client.ObjectKey{Name: name, Namespace: obj.Namespace} - err := k8sClient.Get(ctx, objectKey, dep) - if apierrors.IsNotFound(err) { - return dep, progress.NewReconcileStatus().WaitingOnObject(kind, objectKey.Name, progress.WaitingOnCreation) - } else if err != nil { - return dep, progress.WrapError(fmt.Errorf("fetching %s %s: %w", kind, objectKey.Name, err)) - } else if !isReady(dep) { - return dep, progress.NewReconcileStatus().WaitingOnObject(kind, objectKey.Name, progress.WaitingOnReady) - } - return dep, progress.NewReconcileStatus() -} - -func (actuator serverActuator) getFlavorHelper(ctx context.Context, obj *orcv1alpha1.Server, resource *orcv1alpha1.ServerResourceSpec) (*orcv1alpha1.Flavor, progress.ReconcileStatus) { - return getDependencyHelper(ctx, actuator.k8sClient, obj, string(resource.FlavorRef), "Flavor", func(f *orcv1alpha1.Flavor) bool { - return orcv1alpha1.IsAvailable(f) && f.Status.ID != nil - }, &orcv1alpha1.Flavor{}) -} - -func (actuator serverActuator) getServerGroupHelper(ctx context.Context, obj *orcv1alpha1.Server, resource *orcv1alpha1.ServerResourceSpec) (*orcv1alpha1.ServerGroup, progress.ReconcileStatus) { - if resource.ServerGroupRef == nil { - return &orcv1alpha1.ServerGroup{}, progress.NewReconcileStatus() - } - return getDependencyHelper(ctx, actuator.k8sClient, obj, string(*resource.ServerGroupRef), "ServerGroup", func(sg *orcv1alpha1.ServerGroup) bool { - return orcv1alpha1.IsAvailable(sg) && sg.Status.ID != nil - }, &orcv1alpha1.ServerGroup{}) -} - -func (actuator serverActuator) getKeypairHelper(ctx context.Context, obj *orcv1alpha1.Server, resource *orcv1alpha1.ServerResourceSpec) (*orcv1alpha1.KeyPair, progress.ReconcileStatus) { - if resource.KeypairRef == nil { - return &orcv1alpha1.KeyPair{}, progress.NewReconcileStatus() - } - return getDependencyHelper(ctx, actuator.k8sClient, obj, string(*resource.KeypairRef), "KeyPair", func(kp *orcv1alpha1.KeyPair) bool { - return orcv1alpha1.IsAvailable(kp) && kp.Status.Resource != nil - }, &orcv1alpha1.KeyPair{}) -} - -func (actuator serverActuator) getUserDataHelper(ctx context.Context, obj *orcv1alpha1.Server, resource *orcv1alpha1.ServerResourceSpec) ([]byte, progress.ReconcileStatus) { - if resource.UserData == nil || resource.UserData.SecretRef == nil { - return nil, progress.NewReconcileStatus() - } - secret, reconcileStatus := getDependencyHelper(ctx, actuator.k8sClient, obj, string(*resource.UserData.SecretRef), "Secret", func(s *corev1.Secret) bool { - return true // Secrets don't have availability status - }, &corev1.Secret{}) - if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { - return nil, reconcileStatus - } - userData, ok := secret.Data["value"] - if !ok { - return nil, progress.NewReconcileStatus().WithProgressMessage("User data secret does not contain \"value\" key") - } - return userData, progress.NewReconcileStatus() -} - func (actuator serverActuator) CreateResource(ctx context.Context, obj *orcv1alpha1.Server) (*osResourceT, progress.ReconcileStatus) { resource := obj.Spec.Resource if resource == nil { @@ -234,7 +171,11 @@ func (actuator serverActuator) CreateResource(ctx context.Context, obj *orcv1alp image = dep } - flavor, flavorReconcileStatus := actuator.getFlavorHelper(ctx, obj, resource) + flavor, flavorReconcileStatus := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, + &resource.FlavorRef, "Flavor", + func(f *orcv1alpha1.Flavor) bool { return orcv1alpha1.IsAvailable(f) && f.Status.ID != nil }, + ) reconcileStatus = reconcileStatus.WithReconcileStatus(flavorReconcileStatus) portList := make([]servers.Network, len(resource.Ports)) @@ -265,14 +206,37 @@ func (actuator serverActuator) CreateResource(ctx context.Context, obj *orcv1alp } } - serverGroup, serverGroupReconcileStatus := actuator.getServerGroupHelper(ctx, obj, resource) + serverGroup, serverGroupReconcileStatus := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, + resource.ServerGroupRef, "ServerGroup", + func(sg *orcv1alpha1.ServerGroup) bool { return orcv1alpha1.IsAvailable(sg) && sg.Status.ID != nil }, + ) reconcileStatus = reconcileStatus.WithReconcileStatus(serverGroupReconcileStatus) - keypair, keypairReconcileStatus := actuator.getKeypairHelper(ctx, obj, resource) + keypair, keypairReconcileStatus := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, + resource.KeypairRef, "KeyPair", + func(kp *orcv1alpha1.KeyPair) bool { return orcv1alpha1.IsAvailable(kp) && kp.Status.Resource != nil }, + ) reconcileStatus = reconcileStatus.WithReconcileStatus(keypairReconcileStatus) - userData, userDataReconcileStatus := actuator.getUserDataHelper(ctx, obj, resource) - reconcileStatus = reconcileStatus.WithReconcileStatus(userDataReconcileStatus) + var userData []byte + if resource.UserData != nil { + secret, secretReconcileStatus := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, + resource.UserData.SecretRef, "Secret", + func(*corev1.Secret) bool { return true }, // Secrets don't have availability status + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(secretReconcileStatus) + if secretReconcileStatus == nil { + var ok bool + userData, ok = secret.Data["value"] + if !ok { + reconcileStatus = reconcileStatus.WithReconcileStatus( + progress.NewReconcileStatus().WithProgressMessage("User data secret does not contain \"value\" key")) + } + } + } if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { return nil, reconcileStatus @@ -285,6 +249,11 @@ func (actuator serverActuator) CreateResource(ctx context.Context, obj *orcv1alp // Sort tags before creation to simplify comparisons slices.Sort(tags) + metadata := make(map[string]string) + for _, m := range resource.Metadata { + metadata[m.Key] = m.Value + } + serverCreateOpts := servers.CreateOpts{ Name: getResourceName(obj), ImageRef: *image.Status.ID, @@ -292,7 +261,9 @@ func (actuator serverActuator) CreateResource(ctx context.Context, obj *orcv1alp Networks: portList, UserData: userData, Tags: tags, + Metadata: metadata, AvailabilityZone: resource.AvailabilityZone, + ConfigDrive: resource.ConfigDrive, } /* keypairs.CreateOptsExt was merged into servers.CreateOpts in gopher cloud V3 @@ -343,6 +314,7 @@ func (actuator serverActuator) GetResourceReconcilers(ctx context.Context, orcOb actuator.checkStatus, actuator.updateResource, actuator.reconcileTags, + actuator.reconcileMetadata, actuator.reconcilePortAttachments, actuator.reconcileVolumeAttachments, }, nil @@ -429,6 +401,39 @@ func (actuator serverActuator) reconcileTags(ctx context.Context, obj orcObjectP return tags.ReconcileTags[orcObjectPT, osResourceT](obj.Spec.Resource.Tags, ptr.Deref(osResource.Tags, []string{}), tags.NewServerTagReplacer(actuator.osClient, osResource.ID))(ctx, obj, osResource) } +func (actuator serverActuator) reconcileMetadata(ctx context.Context, obj orcObjectPT, osResource *osResourceT) progress.ReconcileStatus { + log := ctrl.LoggerFrom(ctx) + resource := obj.Spec.Resource + if resource == nil { + return progress.WrapError( + orcerrors.Terminal(orcv1alpha1.ConditionReasonInvalidConfiguration, "Update requested, but spec.resource is not set")) + } + + // Metadata cannot be set on a server that is still building + if osResource.Status == "" || osResource.Status == ServerStatusBuild { + return progress.NewReconcileStatus().WaitingOnOpenStack(progress.WaitingOnReady, serverActivePollingPeriod) + } + + // Build the desired metadata map from spec + desiredMetadata := make(map[string]string) + for _, m := range resource.Metadata { + desiredMetadata[m.Key] = m.Value + } + + // Compare with current metadata + if maps.Equal(desiredMetadata, osResource.Metadata) { + return nil + } + + log.V(logging.Verbose).Info("Updating server metadata") + _, err := actuator.osClient.ReplaceServerMetadata(ctx, osResource.ID, desiredMetadata) + if err != nil { + return progress.WrapError(err) + } + + return progress.NeedsRefresh() +} + func (actuator serverActuator) reconcilePortAttachments(ctx context.Context, obj orcObjectPT, osResource *osResourceT) progress.ReconcileStatus { log := ctrl.LoggerFrom(ctx) resource := obj.Spec.Resource diff --git a/internal/controllers/server/status.go b/internal/controllers/server/status.go index aa7c47ccf..39956c531 100644 --- a/internal/controllers/server/status.go +++ b/internal/controllers/server/status.go @@ -18,6 +18,8 @@ package server import ( "fmt" + "maps" + "slices" "github.com/go-logr/logr" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -69,7 +71,8 @@ func (serverStatusWriter) ApplyResourceStatus(log logr.Logger, osResource *osRes WithHostID(osResource.HostID). WithAvailabilityZone(osResource.AvailabilityZone). WithServerGroups(ptr.Deref(osResource.ServerGroups, []string{})...). - WithTags(ptr.Deref(osResource.Tags, []string{})...) + WithTags(ptr.Deref(osResource.Tags, []string{})...). + WithConfigDrive(osResource.ConfigDrive) if imageID, ok := osResource.Image["id"]; ok { status.WithImageID(fmt.Sprintf("%s", imageID)) @@ -97,5 +100,12 @@ func (serverStatusWriter) ApplyResourceStatus(log logr.Logger, osResource *osRes status.WithInterfaces(interfaceStatus) } + // Sort metadata keys for deterministic output + for _, k := range slices.Sorted(maps.Keys(osResource.Metadata)) { + status.WithMetadata(orcapplyconfigv1alpha1.ServerMetadataStatus(). + WithKey(k). + WithValue(osResource.Metadata[k])) + } + statusApply.WithResource(status) } diff --git a/internal/controllers/server/tests/server-create-full/00-assert.yaml b/internal/controllers/server/tests/server-create-full/00-assert.yaml index 5f351d6d1..68c65c73b 100644 --- a/internal/controllers/server/tests/server-create-full/00-assert.yaml +++ b/internal/controllers/server/tests/server-create-full/00-assert.yaml @@ -66,3 +66,9 @@ status: tags: - tag1 - tag2 + metadata: + - key: environment + value: test + - key: owner + value: kuttl + configDrive: true diff --git a/internal/controllers/server/tests/server-create-full/00-create-resource.yaml b/internal/controllers/server/tests/server-create-full/00-create-resource.yaml index 006b18145..6f82c53f2 100644 --- a/internal/controllers/server/tests/server-create-full/00-create-resource.yaml +++ b/internal/controllers/server/tests/server-create-full/00-create-resource.yaml @@ -48,3 +48,9 @@ spec: tags: - tag1 - tag2 + metadata: + - key: environment + value: test + - key: owner + value: kuttl + configDrive: true diff --git a/internal/controllers/server/tests/server-update/00-assert.yaml b/internal/controllers/server/tests/server-update/00-assert.yaml index 551244650..6964361e5 100644 --- a/internal/controllers/server/tests/server-update/00-assert.yaml +++ b/internal/controllers/server/tests/server-update/00-assert.yaml @@ -24,6 +24,7 @@ assertAll: - celExpr: "server.status.resource.serverGroups[0] == sg.status.id" - celExpr: "!has(server.status.resource.tags)" - celExpr: "!has(server.status.resource.volumes)" + - celExpr: "!has(server.status.resource.metadata)" - celExpr: "size(server.status.resource.interfaces) == 1" - celExpr: "server.status.resource.interfaces[0].portID == port.status.id" --- diff --git a/internal/controllers/server/tests/server-update/01-assert.yaml b/internal/controllers/server/tests/server-update/01-assert.yaml index 473aecab0..db83497d8 100644 --- a/internal/controllers/server/tests/server-update/01-assert.yaml +++ b/internal/controllers/server/tests/server-update/01-assert.yaml @@ -54,6 +54,11 @@ status: tags: - tag1 - tag2 + metadata: + - key: environment + value: staging + - key: team + value: platform conditions: - type: Available status: "True" diff --git a/internal/controllers/server/tests/server-update/01-updated-resource.yaml b/internal/controllers/server/tests/server-update/01-updated-resource.yaml index 248b328a2..ae0cac6df 100644 --- a/internal/controllers/server/tests/server-update/01-updated-resource.yaml +++ b/internal/controllers/server/tests/server-update/01-updated-resource.yaml @@ -44,3 +44,8 @@ spec: tags: - tag1 - tag2 + metadata: + - key: environment + value: staging + - key: team + value: platform diff --git a/internal/controllers/server/tests/server-update/02-assert.yaml b/internal/controllers/server/tests/server-update/02-assert.yaml index 68beeb722..ec2db2777 100644 --- a/internal/controllers/server/tests/server-update/02-assert.yaml +++ b/internal/controllers/server/tests/server-update/02-assert.yaml @@ -32,6 +32,7 @@ assertAll: - celExpr: "server.status.resource.serverGroups[0] == sg.status.id" - celExpr: "!has(server.status.resource.tags)" - celExpr: "!has(server.status.resource.volumes)" + - celExpr: "!has(server.status.resource.metadata)" - celExpr: "!has(volume.status.resource.attachments)" - celExpr: "port1.status.resource.deviceID == server.status.id" - celExpr: "port1.status.resource.status == 'ACTIVE'" diff --git a/internal/controllers/server/zz_generated.adapter.go b/internal/controllers/server/zz_generated.adapter.go index 340fff439..1b51cde39 100644 --- a/internal/controllers/server/zz_generated.adapter.go +++ b/internal/controllers/server/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/server/zz_generated.controller.go b/internal/controllers/server/zz_generated.controller.go index 6a5156eb0..d3aee5648 100644 --- a/internal/controllers/server/zz_generated.controller.go +++ b/internal/controllers/server/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/servergroup/zz_generated.adapter.go b/internal/controllers/servergroup/zz_generated.adapter.go index ee366d633..dc272f462 100644 --- a/internal/controllers/servergroup/zz_generated.adapter.go +++ b/internal/controllers/servergroup/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/servergroup/zz_generated.controller.go b/internal/controllers/servergroup/zz_generated.controller.go index 8da2d169d..181f872cc 100644 --- a/internal/controllers/servergroup/zz_generated.controller.go +++ b/internal/controllers/servergroup/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/service/zz_generated.adapter.go b/internal/controllers/service/zz_generated.adapter.go index 3f8d585bc..f70ba04d9 100644 --- a/internal/controllers/service/zz_generated.adapter.go +++ b/internal/controllers/service/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/service/zz_generated.controller.go b/internal/controllers/service/zz_generated.controller.go index a1fe4a121..0e0232fae 100644 --- a/internal/controllers/service/zz_generated.controller.go +++ b/internal/controllers/service/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/subnet/actuator.go b/internal/controllers/subnet/actuator.go index 951718ba6..f3e0e8dd4 100644 --- a/internal/controllers/subnet/actuator.go +++ b/internal/controllers/subnet/actuator.go @@ -37,6 +37,7 @@ import ( "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress" "github.com/k-orc/openstack-resource-controller/v2/internal/logging" "github.com/k-orc/openstack-resource-controller/v2/internal/osclients" + "github.com/k-orc/openstack-resource-controller/v2/internal/util/dependency" orcerrors "github.com/k-orc/openstack-resource-controller/v2/internal/util/errors" "github.com/k-orc/openstack-resource-controller/v2/internal/util/tags" ) @@ -86,43 +87,21 @@ func (actuator subnetActuator) ListOSResourcesForAdoption(ctx context.Context, o func (actuator subnetActuator) ListOSResourcesForImport(ctx context.Context, obj orcObjectPT, filter filterT) (iter.Seq2[*osResourceT, error], progress.ReconcileStatus) { var reconcileStatus progress.ReconcileStatus - network := &orcv1alpha1.Network{} - if filter.NetworkRef != "" { - networkKey := client.ObjectKey{Name: string(filter.NetworkRef), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, networkKey, network); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Network", networkKey.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching network %s: %w", networkKey.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable(network) || network.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Network", networkKey.Name, progress.WaitingOnReady)) - } - } - } + network, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, &filter.NetworkRef, "Network", + func(dep *orcv1alpha1.Network) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) - project := &orcv1alpha1.Project{} - if filter.ProjectRef != nil { - projectKey := client.ObjectKey{Name: string(*filter.ProjectRef), Namespace: obj.Namespace} - if err := actuator.k8sClient.Get(ctx, projectKey, project); err != nil { - if apierrors.IsNotFound(err) { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Project", projectKey.Name, progress.WaitingOnCreation)) - } else { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WrapError(fmt.Errorf("fetching project %s: %w", projectKey.Name, err))) - } - } else { - if !orcv1alpha1.IsAvailable(project) || project.Status.ID == nil { - reconcileStatus = reconcileStatus.WithReconcileStatus( - progress.WaitingOnObject("Project", projectKey.Name, progress.WaitingOnReady)) - } - } - } + project, rs := dependency.FetchDependency( + ctx, actuator.k8sClient, obj.Namespace, filter.ProjectRef, "Project", + func(dep *orcv1alpha1.Project) bool { + return orcv1alpha1.IsAvailable(dep) && dep.Status.ID != nil + }, + ) + reconcileStatus = reconcileStatus.WithReconcileStatus(rs) if needsReschedule, _ := reconcileStatus.NeedsReschedule(); needsReschedule { return nil, reconcileStatus diff --git a/internal/controllers/subnet/zz_generated.adapter.go b/internal/controllers/subnet/zz_generated.adapter.go index 102a41b91..34c84d5b8 100644 --- a/internal/controllers/subnet/zz_generated.adapter.go +++ b/internal/controllers/subnet/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/subnet/zz_generated.controller.go b/internal/controllers/subnet/zz_generated.controller.go index 58e27bae3..73fe60115 100644 --- a/internal/controllers/subnet/zz_generated.controller.go +++ b/internal/controllers/subnet/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/volume/zz_generated.adapter.go b/internal/controllers/volume/zz_generated.adapter.go index fe9aebdd1..956b64693 100644 --- a/internal/controllers/volume/zz_generated.adapter.go +++ b/internal/controllers/volume/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/volume/zz_generated.controller.go b/internal/controllers/volume/zz_generated.controller.go index d4585cef1..080ff160c 100644 --- a/internal/controllers/volume/zz_generated.controller.go +++ b/internal/controllers/volume/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/volumetype/zz_generated.adapter.go b/internal/controllers/volumetype/zz_generated.adapter.go index 2490ef70e..9f19fa751 100644 --- a/internal/controllers/volumetype/zz_generated.adapter.go +++ b/internal/controllers/volumetype/zz_generated.adapter.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/controllers/volumetype/zz_generated.controller.go b/internal/controllers/volumetype/zz_generated.controller.go index 0e551e2f2..74d96c985 100644 --- a/internal/controllers/volumetype/zz_generated.controller.go +++ b/internal/controllers/volumetype/zz_generated.controller.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/osclients/compute.go b/internal/osclients/compute.go index e40154150..43f4396d5 100644 --- a/internal/osclients/compute.go +++ b/internal/osclients/compute.go @@ -72,6 +72,7 @@ type ComputeClient interface { DeleteAttachedInterface(ctx context.Context, serverID, portID string) error ReplaceAllServerAttributesTags(ctx context.Context, resourceID string, opts tags.ReplaceAllOptsBuilder) ([]string, error) + ReplaceServerMetadata(ctx context.Context, serverID string, opts servers.MetadataOpts) (map[string]string, error) } type computeClient struct{ client *gophercloud.ServiceClient } @@ -187,6 +188,10 @@ func (c computeClient) ReplaceAllServerAttributesTags(ctx context.Context, resou return tags.ReplaceAll(ctx, c.client, resourceID, opts).Extract() } +func (c computeClient) ReplaceServerMetadata(ctx context.Context, serverID string, opts servers.MetadataOpts) (map[string]string, error) { + return servers.ResetMetadata(ctx, c.client, serverID, opts).Extract() +} + type computeErrorClient struct{ error } // NewComputeErrorClient returns a ComputeClient in which every method returns the given error. @@ -275,3 +280,7 @@ func (e computeErrorClient) DeleteAttachedInterface(_ context.Context, _, _ stri func (e computeErrorClient) ReplaceAllServerAttributesTags(_ context.Context, _ string, _ tags.ReplaceAllOptsBuilder) ([]string, error) { return nil, e.error } + +func (e computeErrorClient) ReplaceServerMetadata(_ context.Context, _ string, _ servers.MetadataOpts) (map[string]string, error) { + return nil, e.error +} diff --git a/internal/osclients/mock/compute.go b/internal/osclients/mock/compute.go index c22ab6984..2fdea0de4 100644 --- a/internal/osclients/mock/compute.go +++ b/internal/osclients/mock/compute.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -324,6 +324,21 @@ func (mr *MockComputeClientMockRecorder) ReplaceAllServerAttributesTags(ctx, res return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceAllServerAttributesTags", reflect.TypeOf((*MockComputeClient)(nil).ReplaceAllServerAttributesTags), ctx, resourceID, opts) } +// ReplaceServerMetadata mocks base method. +func (m *MockComputeClient) ReplaceServerMetadata(ctx context.Context, serverID string, opts servers.MetadataOpts) (map[string]string, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReplaceServerMetadata", ctx, serverID, opts) + ret0, _ := ret[0].(map[string]string) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReplaceServerMetadata indicates an expected call of ReplaceServerMetadata. +func (mr *MockComputeClientMockRecorder) ReplaceServerMetadata(ctx, serverID, opts any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceServerMetadata", reflect.TypeOf((*MockComputeClient)(nil).ReplaceServerMetadata), ctx, serverID, opts) +} + // UpdateServer mocks base method. func (m *MockComputeClient) UpdateServer(ctx context.Context, id string, opts servers.UpdateOptsBuilder) (*servers.Server, error) { m.ctrl.T.Helper() diff --git a/internal/osclients/mock/doc.go b/internal/osclients/mock/doc.go index 84971e17a..176f3bc93 100644 --- a/internal/osclients/mock/doc.go +++ b/internal/osclients/mock/doc.go @@ -1,6 +1,6 @@ // Code generated by resource-generator. DO NOT EDIT. /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/osclients/mock/domain.go b/internal/osclients/mock/domain.go index bfc9c6c1c..a16b2b178 100644 --- a/internal/osclients/mock/domain.go +++ b/internal/osclients/mock/domain.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/osclients/mock/endpoint.go b/internal/osclients/mock/endpoint.go index dafc92276..ed4ea1be4 100644 --- a/internal/osclients/mock/endpoint.go +++ b/internal/osclients/mock/endpoint.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/osclients/mock/group.go b/internal/osclients/mock/group.go index f4c5da425..0612ebed2 100644 --- a/internal/osclients/mock/group.go +++ b/internal/osclients/mock/group.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/osclients/mock/identity.go b/internal/osclients/mock/identity.go index 70079f962..17f8e4f6c 100644 --- a/internal/osclients/mock/identity.go +++ b/internal/osclients/mock/identity.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/osclients/mock/image.go b/internal/osclients/mock/image.go index dc5dba62e..939917569 100644 --- a/internal/osclients/mock/image.go +++ b/internal/osclients/mock/image.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/osclients/mock/keypair.go b/internal/osclients/mock/keypair.go index e4dfac055..f5d28c603 100644 --- a/internal/osclients/mock/keypair.go +++ b/internal/osclients/mock/keypair.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/osclients/mock/networking.go b/internal/osclients/mock/networking.go index 9b5e25046..ceab233d2 100644 --- a/internal/osclients/mock/networking.go +++ b/internal/osclients/mock/networking.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/osclients/mock/role.go b/internal/osclients/mock/role.go index 3108304d2..08ea8397c 100644 --- a/internal/osclients/mock/role.go +++ b/internal/osclients/mock/role.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/osclients/mock/service.go b/internal/osclients/mock/service.go index b8c9191a8..05bee911b 100644 --- a/internal/osclients/mock/service.go +++ b/internal/osclients/mock/service.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/osclients/mock/volume.go b/internal/osclients/mock/volume.go index efb1390f0..ca736d3d1 100644 --- a/internal/osclients/mock/volume.go +++ b/internal/osclients/mock/volume.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/osclients/mock/volumetype.go b/internal/osclients/mock/volumetype.go index e0dd5be49..08a648872 100644 --- a/internal/osclients/mock/volumetype.go +++ b/internal/osclients/mock/volumetype.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/internal/util/dependency/helpers.go b/internal/util/dependency/helpers.go new file mode 100644 index 000000000..be9caa005 --- /dev/null +++ b/internal/util/dependency/helpers.go @@ -0,0 +1,68 @@ +/* +Copyright 2025 The ORC 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 dependency + +import ( + "context" + "fmt" + + apierrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/utils/ptr" + "sigs.k8s.io/controller-runtime/pkg/client" + + orcv1alpha1 "github.com/k-orc/openstack-resource-controller/v2/api/v1alpha1" + "github.com/k-orc/openstack-resource-controller/v2/internal/controllers/generic/progress" +) + +// FetchDependency fetches a resource by name and checks if it's ready. +// Unlike GetDependency on DeletionGuardDependency, this doesn't add finalizers +// and is suitable for one-off lookups like resolving refs in import filters. +// +// Always returns an object (empty struct if not found/ready/error) for safe field access. +// +// Returns: +// - The fetched object (empty struct if name is nil, not found, not ready, or on error) +// - ReconcileStatus indicating wait state or error (nil only if name is nil or object is ready) +func FetchDependency[TP DependencyType[T], T any]( + ctx context.Context, + k8sClient client.Client, + namespace string, + name *orcv1alpha1.KubernetesNameRef, + kind string, + isReady func(TP) bool, +) (TP, progress.ReconcileStatus) { + var obj TP = new(T) + + if ptr.Deref(name, "") == "" { + return obj, nil + } + + objectKey := client.ObjectKey{Name: string(*name), Namespace: namespace} + + if err := k8sClient.Get(ctx, objectKey, obj); err != nil { + if apierrors.IsNotFound(err) { + return obj, progress.NewReconcileStatus().WaitingOnObject(kind, string(*name), progress.WaitingOnCreation) + } + return obj, progress.WrapError(fmt.Errorf("fetching %s %s: %w", kind, string(*name), err)) + } + + if !isReady(obj) { + return obj, progress.NewReconcileStatus().WaitingOnObject(kind, string(*name), progress.WaitingOnReady) + } + + return obj, nil +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/address.go b/pkg/clients/applyconfiguration/api/v1alpha1/address.go index 74478a9e0..7db825b3b 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/address.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/address.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/allocationpool.go b/pkg/clients/applyconfiguration/api/v1alpha1/allocationpool.go index d152ed380..bf3667ad7 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/allocationpool.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/allocationpool.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/allocationpoolstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/allocationpoolstatus.go index a806531d6..a66c82e05 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/allocationpoolstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/allocationpoolstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/allowedaddresspair.go b/pkg/clients/applyconfiguration/api/v1alpha1/allowedaddresspair.go index 48d77abbe..b80e96c5d 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/allowedaddresspair.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/allowedaddresspair.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/allowedaddresspairstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/allowedaddresspairstatus.go index d18d0a5d8..19ec2e80f 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/allowedaddresspairstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/allowedaddresspairstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/cloudcredentialsreference.go b/pkg/clients/applyconfiguration/api/v1alpha1/cloudcredentialsreference.go index 455c0eb1e..d619ae9ff 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/cloudcredentialsreference.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/cloudcredentialsreference.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/domain.go b/pkg/clients/applyconfiguration/api/v1alpha1/domain.go index 5f1b4216b..b8748feeb 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/domain.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/domain.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/domainfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/domainfilter.go index bed3c4ef7..49152b6a3 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/domainfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/domainfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/domainimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/domainimport.go index 26198ccab..a208643cd 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/domainimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/domainimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/domainresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/domainresourcespec.go index c18282d4f..1b9a0ea6b 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/domainresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/domainresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/domainresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/domainresourcestatus.go index ca5d524f5..91911434a 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/domainresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/domainresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/domainspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/domainspec.go index 2c72fdef4..e5357a87e 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/domainspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/domainspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/domainstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/domainstatus.go index 0294b7a06..c7540a168 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/domainstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/domainstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpoint.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpoint.go index a099f728f..6c1f5e897 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/endpoint.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpoint.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointfilter.go index 3cf7c6000..fe33276e4 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/endpointfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointimport.go index e20a99cd7..8d6cae433 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/endpointimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcespec.go index b9f157902..ff59ccce4 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,11 +25,11 @@ import ( // EndpointResourceSpecApplyConfiguration represents a declarative configuration of the EndpointResourceSpec type for use // with apply. type EndpointResourceSpecApplyConfiguration struct { - Name *apiv1alpha1.OpenStackName `json:"name,omitempty"` - Enabled *bool `json:"enabled,omitempty"` - Interface *string `json:"interface,omitempty"` - URL *string `json:"url,omitempty"` - ServiceRef *apiv1alpha1.KubernetesNameRef `json:"serviceRef,omitempty"` + Description *string `json:"description,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Interface *string `json:"interface,omitempty"` + URL *string `json:"url,omitempty"` + ServiceRef *apiv1alpha1.KubernetesNameRef `json:"serviceRef,omitempty"` } // EndpointResourceSpecApplyConfiguration constructs a declarative configuration of the EndpointResourceSpec type for use with @@ -38,11 +38,11 @@ func EndpointResourceSpec() *EndpointResourceSpecApplyConfiguration { return &EndpointResourceSpecApplyConfiguration{} } -// WithName sets the Name field in the declarative configuration to the given value +// WithDescription sets the Description field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *EndpointResourceSpecApplyConfiguration) WithName(value apiv1alpha1.OpenStackName) *EndpointResourceSpecApplyConfiguration { - b.Name = &value +// If called multiple times, the Description field is set to the value of the last call. +func (b *EndpointResourceSpecApplyConfiguration) WithDescription(value string) *EndpointResourceSpecApplyConfiguration { + b.Description = &value return b } diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcestatus.go index 8a0b7c87c..54a98b5a7 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,11 +21,11 @@ package v1alpha1 // EndpointResourceStatusApplyConfiguration represents a declarative configuration of the EndpointResourceStatus type for use // with apply. type EndpointResourceStatusApplyConfiguration struct { - Name *string `json:"name,omitempty"` - Enabled *bool `json:"enabled,omitempty"` - Interface *string `json:"interface,omitempty"` - URL *string `json:"url,omitempty"` - ServiceID *string `json:"serviceID,omitempty"` + Description *string `json:"description,omitempty"` + Enabled *bool `json:"enabled,omitempty"` + Interface *string `json:"interface,omitempty"` + URL *string `json:"url,omitempty"` + ServiceID *string `json:"serviceID,omitempty"` } // EndpointResourceStatusApplyConfiguration constructs a declarative configuration of the EndpointResourceStatus type for use with @@ -34,11 +34,11 @@ func EndpointResourceStatus() *EndpointResourceStatusApplyConfiguration { return &EndpointResourceStatusApplyConfiguration{} } -// WithName sets the Name field in the declarative configuration to the given value +// WithDescription sets the Description field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. -// If called multiple times, the Name field is set to the value of the last call. -func (b *EndpointResourceStatusApplyConfiguration) WithName(value string) *EndpointResourceStatusApplyConfiguration { - b.Name = &value +// If called multiple times, the Description field is set to the value of the last call. +func (b *EndpointResourceStatusApplyConfiguration) WithDescription(value string) *EndpointResourceStatusApplyConfiguration { + b.Description = &value return b } diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointspec.go index fbe73d129..198237c30 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/endpointspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/endpointstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/endpointstatus.go index ab14837ef..d620075a5 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/endpointstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/endpointstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/externalgateway.go b/pkg/clients/applyconfiguration/api/v1alpha1/externalgateway.go index d16d8f6b5..304964005 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/externalgateway.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/externalgateway.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/externalgatewaystatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/externalgatewaystatus.go index a93eaaab1..3b07be9fd 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/externalgatewaystatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/externalgatewaystatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/filterbykeystonetags.go b/pkg/clients/applyconfiguration/api/v1alpha1/filterbykeystonetags.go index bc4fe7536..925726e12 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/filterbykeystonetags.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/filterbykeystonetags.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/filterbyneutrontags.go b/pkg/clients/applyconfiguration/api/v1alpha1/filterbyneutrontags.go index 785486a6f..c8796fafd 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/filterbyneutrontags.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/filterbyneutrontags.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/filterbyservertags.go b/pkg/clients/applyconfiguration/api/v1alpha1/filterbyservertags.go index e8e8b6347..a7360cde9 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/filterbyservertags.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/filterbyservertags.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/fixedipstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/fixedipstatus.go index f12c972b2..88afdedf4 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/fixedipstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/fixedipstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/flavor.go b/pkg/clients/applyconfiguration/api/v1alpha1/flavor.go index b6c7a5a4c..da6e101b2 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/flavor.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/flavor.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/flavorfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/flavorfilter.go index 90864da00..84ea15f96 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/flavorfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/flavorfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/flavorimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/flavorimport.go index 8c9f5931b..a8e657fc0 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/flavorimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/flavorimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/flavorresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/flavorresourcespec.go index 6f3321810..335f722a6 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/flavorresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/flavorresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/flavorresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/flavorresourcestatus.go index 28ab52d58..7b4996ed4 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/flavorresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/flavorresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/flavorspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/flavorspec.go index f60351b00..abe7c0d07 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/flavorspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/flavorspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/flavorstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/flavorstatus.go index 660532d5d..928a60e26 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/flavorstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/flavorstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/floatingip.go b/pkg/clients/applyconfiguration/api/v1alpha1/floatingip.go index 29c0ddd81..2923fc5df 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/floatingip.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/floatingip.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/floatingipfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/floatingipfilter.go index 518de3eb0..bdaf24e7a 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/floatingipfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/floatingipfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/floatingipimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/floatingipimport.go index 261d3b3d7..759a0a4b3 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/floatingipimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/floatingipimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/floatingipresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/floatingipresourcespec.go index 11b4cb473..7de2cc0ef 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/floatingipresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/floatingipresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/floatingipresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/floatingipresourcestatus.go index c3c792fb2..697f5ba19 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/floatingipresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/floatingipresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/floatingipspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/floatingipspec.go index 3a34d0527..8fe12ac3a 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/floatingipspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/floatingipspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/floatingipstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/floatingipstatus.go index c78821748..61291bdd7 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/floatingipstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/floatingipstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/group.go b/pkg/clients/applyconfiguration/api/v1alpha1/group.go index c01e53c37..1904aa4f2 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/group.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/group.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/groupfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/groupfilter.go index 74e576e8f..974125061 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/groupfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/groupfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/groupimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/groupimport.go index 8b2722827..f5ea5aaff 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/groupimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/groupimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/groupresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/groupresourcespec.go index 1be73b8ad..3d914a439 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/groupresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/groupresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/groupresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/groupresourcestatus.go index 53f2fd0ab..bfe2aa55f 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/groupresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/groupresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/groupspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/groupspec.go index 0aaee9e04..59a744101 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/groupspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/groupspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/groupstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/groupstatus.go index 88af39d51..564e9cdc4 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/groupstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/groupstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/hostroute.go b/pkg/clients/applyconfiguration/api/v1alpha1/hostroute.go index 19be79bac..4cc09b094 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/hostroute.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/hostroute.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/hostroutestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/hostroutestatus.go index 90bfffa3d..11bf6a596 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/hostroutestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/hostroutestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/image.go b/pkg/clients/applyconfiguration/api/v1alpha1/image.go index 9a3d2d392..386817976 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/image.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/image.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imagecontent.go b/pkg/clients/applyconfiguration/api/v1alpha1/imagecontent.go index 6b096f15a..d9e68e2e6 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imagecontent.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imagecontent.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imagecontentsourcedownload.go b/pkg/clients/applyconfiguration/api/v1alpha1/imagecontentsourcedownload.go index 9ed05d174..b00f1c48d 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imagecontentsourcedownload.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imagecontentsourcedownload.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imagefilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/imagefilter.go index 3d6a9bb2b..827d8c797 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imagefilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imagefilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imagehash.go b/pkg/clients/applyconfiguration/api/v1alpha1/imagehash.go index 5c8558384..67a0478d3 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imagehash.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imagehash.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imageimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/imageimport.go index bcf5fa561..27df0f019 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imageimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imageimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imageproperties.go b/pkg/clients/applyconfiguration/api/v1alpha1/imageproperties.go index 36265de38..f73ac4121 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imageproperties.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imageproperties.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imagepropertieshardware.go b/pkg/clients/applyconfiguration/api/v1alpha1/imagepropertieshardware.go index 926a0c247..2d7f89208 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imagepropertieshardware.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imagepropertieshardware.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imagepropertiesoperatingsystem.go b/pkg/clients/applyconfiguration/api/v1alpha1/imagepropertiesoperatingsystem.go index fa1789a4d..81f6858de 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imagepropertiesoperatingsystem.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imagepropertiesoperatingsystem.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imageresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/imageresourcespec.go index aff932b2b..5c1adb6ad 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imageresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imageresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imageresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/imageresourcestatus.go index bc5c5db70..e697b64d0 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imageresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imageresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imagespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/imagespec.go index ba1ea2252..7982dcda4 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imagespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imagespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imagestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/imagestatus.go index 15c7410b9..033e2cd30 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imagestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imagestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/imagestatusextra.go b/pkg/clients/applyconfiguration/api/v1alpha1/imagestatusextra.go index e5a147d2b..d2fc95947 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/imagestatusextra.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/imagestatusextra.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/ipv6options.go b/pkg/clients/applyconfiguration/api/v1alpha1/ipv6options.go index a82b36222..d95b64185 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/ipv6options.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/ipv6options.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/keypair.go b/pkg/clients/applyconfiguration/api/v1alpha1/keypair.go index db29ba7ba..9a5937b2b 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/keypair.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/keypair.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/keypairfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/keypairfilter.go index 22f0353bf..bee0e363b 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/keypairfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/keypairfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/keypairimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/keypairimport.go index ed766367b..14a0205b9 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/keypairimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/keypairimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/keypairresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/keypairresourcespec.go index 1ae0c8fe9..fc2069cfa 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/keypairresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/keypairresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/keypairresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/keypairresourcestatus.go index 2be862ba2..f0047e4c1 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/keypairresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/keypairresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/keypairspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/keypairspec.go index ffe67fe9c..725c5278d 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/keypairspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/keypairspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/keypairstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/keypairstatus.go index 5a4a51b13..fb316a629 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/keypairstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/keypairstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/managedoptions.go b/pkg/clients/applyconfiguration/api/v1alpha1/managedoptions.go index 89f690a9c..092ab7883 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/managedoptions.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/managedoptions.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/network.go b/pkg/clients/applyconfiguration/api/v1alpha1/network.go index f8bac102e..76876d253 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/network.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/network.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/networkfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/networkfilter.go index f1a1d5f87..557babf8b 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/networkfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/networkfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/networkimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/networkimport.go index fa9f7702e..f0e6311cf 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/networkimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/networkimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/networkresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/networkresourcespec.go index 8646ab92f..a85d19867 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/networkresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/networkresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/networkresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/networkresourcestatus.go index 1935b223b..fa1d0a2e5 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/networkresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/networkresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/networkspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/networkspec.go index 8de986799..a27a7b21c 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/networkspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/networkspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/networkstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/networkstatus.go index 1c8312a59..1d671bd04 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/networkstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/networkstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/neutronstatusmetadata.go b/pkg/clients/applyconfiguration/api/v1alpha1/neutronstatusmetadata.go index b9cc4fd26..04d7aca93 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/neutronstatusmetadata.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/neutronstatusmetadata.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/port.go b/pkg/clients/applyconfiguration/api/v1alpha1/port.go index 2ef3698b9..17b2763e5 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/port.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/port.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/portfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/portfilter.go index ab6d6e18d..2db6c09a6 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/portimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/portimport.go index 272da1940..fd760ff61 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/portrangespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/portrangespec.go index 811b56f0e..64bc4a298 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portrangespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portrangespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/portrangestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/portrangestatus.go index 4728e5ca0..b92bd01c6 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portrangestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portrangestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go index ac7d4ed07..aab07d8bc 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -37,6 +37,7 @@ type PortResourceSpecApplyConfiguration struct { PortSecurity *apiv1alpha1.PortSecurityState `json:"portSecurity,omitempty"` ProjectRef *apiv1alpha1.KubernetesNameRef `json:"projectRef,omitempty"` MACAddress *string `json:"macAddress,omitempty"` + HostID *string `json:"hostID,omitempty"` } // PortResourceSpecApplyConfiguration constructs a declarative configuration of the PortResourceSpec type for use with @@ -154,3 +155,11 @@ func (b *PortResourceSpecApplyConfiguration) WithMACAddress(value string) *PortR b.MACAddress = &value return b } + +// WithHostID sets the HostID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the HostID field is set to the value of the last call. +func (b *PortResourceSpecApplyConfiguration) WithHostID(value string) *PortResourceSpecApplyConfiguration { + b.HostID = &value + return b +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/portresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/portresourcestatus.go index 1fd734822..21ad2725e 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -41,6 +41,7 @@ type PortResourceStatusApplyConfiguration struct { PropagateUplinkStatus *bool `json:"propagateUplinkStatus,omitempty"` VNICType *string `json:"vnicType,omitempty"` PortSecurityEnabled *bool `json:"portSecurityEnabled,omitempty"` + HostID *string `json:"hostID,omitempty"` NeutronStatusMetadataApplyConfiguration `json:",inline"` } @@ -192,6 +193,14 @@ func (b *PortResourceStatusApplyConfiguration) WithPortSecurityEnabled(value boo return b } +// WithHostID sets the HostID field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the HostID field is set to the value of the last call. +func (b *PortResourceStatusApplyConfiguration) WithHostID(value string) *PortResourceStatusApplyConfiguration { + b.HostID = &value + return b +} + // WithCreatedAt sets the CreatedAt field in the declarative configuration to the given value // and returns the receiver, so that objects can be built by chaining "With" function invocations. // If called multiple times, the CreatedAt field is set to the value of the last call. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/portspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/portspec.go index 6b6a549f2..f3a31f9d1 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/portstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/portstatus.go index 700231629..f902f1538 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/project.go b/pkg/clients/applyconfiguration/api/v1alpha1/project.go index 7bb0dc9a6..4ce5d897a 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/project.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/project.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/projectfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/projectfilter.go index 0bdcf6a82..90b315787 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/projectfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/projectfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/projectimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/projectimport.go index 395deb31f..486e72fd5 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/projectimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/projectimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/projectresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/projectresourcespec.go index fc8721b8c..8a5ef4250 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/projectresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/projectresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/projectresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/projectresourcestatus.go index 5520405c9..0e2ad1f94 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/projectresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/projectresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/projectspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/projectspec.go index d98c9dc9c..fe81e80ba 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/projectspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/projectspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/projectstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/projectstatus.go index f829757ae..328980bcf 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/projectstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/projectstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/providerpropertiesstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/providerpropertiesstatus.go index a274c3f3b..47bfc8c2a 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/providerpropertiesstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/providerpropertiesstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/role.go b/pkg/clients/applyconfiguration/api/v1alpha1/role.go index 14fcda794..1fcf9bf44 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/role.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/role.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/rolefilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/rolefilter.go index d27c0d297..2194e2982 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/rolefilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/rolefilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/roleimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/roleimport.go index da25d500b..336bc2fe1 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/roleimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/roleimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/roleresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/roleresourcespec.go index 4f3fad0c5..c1288f979 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/roleresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/roleresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/roleresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/roleresourcestatus.go index 847f97c26..b915ba35a 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/roleresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/roleresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/rolespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/rolespec.go index 92fa50276..05205d08b 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/rolespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/rolespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/rolestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/rolestatus.go index cc11f42f4..8731d9e8b 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/rolestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/rolestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/router.go b/pkg/clients/applyconfiguration/api/v1alpha1/router.go index 3fe5add44..52d6a7d07 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/router.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/router.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/routerfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/routerfilter.go index d87275dfc..100978fb6 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/routerfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/routerfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/routerimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/routerimport.go index c48eae55e..d182caade 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/routerimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/routerimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/routerinterface.go b/pkg/clients/applyconfiguration/api/v1alpha1/routerinterface.go index 671f33942..caf20d3d0 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/routerinterface.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/routerinterface.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/routerinterfacespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/routerinterfacespec.go index 1af36e749..4fccc28c6 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/routerinterfacespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/routerinterfacespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/routerinterfacestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/routerinterfacestatus.go index 8e162f3bf..280668da5 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/routerinterfacestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/routerinterfacestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/routerresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/routerresourcespec.go index 2b4cb81b2..4b0a09ff7 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/routerresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/routerresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/routerresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/routerresourcestatus.go index b89a23529..985da1065 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/routerresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/routerresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/routerspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/routerspec.go index cf70e4771..fb3da1400 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/routerspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/routerspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/routerstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/routerstatus.go index ca1eca811..2b42ab43e 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/routerstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/routerstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroup.go b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroup.go index 56ccc6e15..2f05e98c2 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroup.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroup.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupfilter.go index e4368095d..f11d7bbdc 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupimport.go index 4faa3f3dd..20855e5a3 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupresourcespec.go index 17d57aafc..f02908f6a 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupresourcestatus.go index 2ccdb930a..2709c209b 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/securitygrouprule.go b/pkg/clients/applyconfiguration/api/v1alpha1/securitygrouprule.go index f6513d5f0..09fa8329e 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/securitygrouprule.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/securitygrouprule.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/securitygrouprulestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/securitygrouprulestatus.go index 8bd924f2a..7d9b31ba6 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/securitygrouprulestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/securitygrouprulestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupspec.go index cb624b694..aea02dbb7 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupstatus.go index dae3cc7ac..8ff720652 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/securitygroupstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/server.go b/pkg/clients/applyconfiguration/api/v1alpha1/server.go index 60db77744..21adde247 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/server.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/server.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/serverfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/serverfilter.go index 822ba54d3..1212b6a29 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/serverfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/serverfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servergroup.go b/pkg/clients/applyconfiguration/api/v1alpha1/servergroup.go index b5bbc8ba0..e534de68c 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servergroup.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servergroup.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servergroupfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/servergroupfilter.go index 0576765dd..70d12d4fc 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servergroupfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servergroupfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servergroupimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/servergroupimport.go index c46e8a88a..0aa17ce03 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servergroupimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servergroupimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servergroupresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/servergroupresourcespec.go index 0b9f058e7..08ef8c08a 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servergroupresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servergroupresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servergroupresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/servergroupresourcestatus.go index 67b1d3be7..ddf1524b2 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servergroupresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servergroupresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servergrouprules.go b/pkg/clients/applyconfiguration/api/v1alpha1/servergrouprules.go index e6dc75cef..ab7af2939 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servergrouprules.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servergrouprules.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servergrouprulesstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/servergrouprulesstatus.go index add47f563..cb61dbfb3 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servergrouprulesstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servergrouprulesstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servergroupspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/servergroupspec.go index 096f6f610..21efdd462 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servergroupspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servergroupspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servergroupstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/servergroupstatus.go index b9b392b12..8b7e8ce34 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servergroupstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servergroupstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/serverimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/serverimport.go index c93fa9f7d..30ef85c81 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/serverimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/serverimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/serverinterfacefixedip.go b/pkg/clients/applyconfiguration/api/v1alpha1/serverinterfacefixedip.go index 1bbab2048..ce743b6d0 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/serverinterfacefixedip.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/serverinterfacefixedip.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/serverinterfacestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/serverinterfacestatus.go index 609d5664a..add66fb42 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/serverinterfacestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/serverinterfacestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servermetadata.go b/pkg/clients/applyconfiguration/api/v1alpha1/servermetadata.go new file mode 100644 index 000000000..7d332a991 --- /dev/null +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servermetadata.go @@ -0,0 +1,48 @@ +/* +Copyright The ORC 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// ServerMetadataApplyConfiguration represents a declarative configuration of the ServerMetadata type for use +// with apply. +type ServerMetadataApplyConfiguration struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +// ServerMetadataApplyConfiguration constructs a declarative configuration of the ServerMetadata type for use with +// apply. +func ServerMetadata() *ServerMetadataApplyConfiguration { + return &ServerMetadataApplyConfiguration{} +} + +// WithKey sets the Key field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Key field is set to the value of the last call. +func (b *ServerMetadataApplyConfiguration) WithKey(value string) *ServerMetadataApplyConfiguration { + b.Key = &value + return b +} + +// WithValue sets the Value field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Value field is set to the value of the last call. +func (b *ServerMetadataApplyConfiguration) WithValue(value string) *ServerMetadataApplyConfiguration { + b.Value = &value + return b +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servermetadatastatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/servermetadatastatus.go new file mode 100644 index 000000000..0f978fa89 --- /dev/null +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servermetadatastatus.go @@ -0,0 +1,48 @@ +/* +Copyright The ORC 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. +*/ + +// Code generated by applyconfiguration-gen. DO NOT EDIT. + +package v1alpha1 + +// ServerMetadataStatusApplyConfiguration represents a declarative configuration of the ServerMetadataStatus type for use +// with apply. +type ServerMetadataStatusApplyConfiguration struct { + Key *string `json:"key,omitempty"` + Value *string `json:"value,omitempty"` +} + +// ServerMetadataStatusApplyConfiguration constructs a declarative configuration of the ServerMetadataStatus type for use with +// apply. +func ServerMetadataStatus() *ServerMetadataStatusApplyConfiguration { + return &ServerMetadataStatusApplyConfiguration{} +} + +// WithKey sets the Key field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Key field is set to the value of the last call. +func (b *ServerMetadataStatusApplyConfiguration) WithKey(value string) *ServerMetadataStatusApplyConfiguration { + b.Key = &value + return b +} + +// WithValue sets the Value field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the Value field is set to the value of the last call. +func (b *ServerMetadataStatusApplyConfiguration) WithValue(value string) *ServerMetadataStatusApplyConfiguration { + b.Value = &value + return b +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/serverportspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/serverportspec.go index a09007518..3b812beae 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/serverportspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/serverportspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/serverresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/serverresourcespec.go index 5233713da..c3308477a 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/serverresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/serverresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -35,6 +35,8 @@ type ServerResourceSpecApplyConfiguration struct { AvailabilityZone *string `json:"availabilityZone,omitempty"` KeypairRef *apiv1alpha1.KubernetesNameRef `json:"keypairRef,omitempty"` Tags []apiv1alpha1.ServerTag `json:"tags,omitempty"` + Metadata []ServerMetadataApplyConfiguration `json:"metadata,omitempty"` + ConfigDrive *bool `json:"configDrive,omitempty"` } // ServerResourceSpecApplyConfiguration constructs a declarative configuration of the ServerResourceSpec type for use with @@ -134,3 +136,24 @@ func (b *ServerResourceSpecApplyConfiguration) WithTags(values ...apiv1alpha1.Se } return b } + +// WithMetadata adds the given value to the Metadata field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Metadata field. +func (b *ServerResourceSpecApplyConfiguration) WithMetadata(values ...*ServerMetadataApplyConfiguration) *ServerResourceSpecApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMetadata") + } + b.Metadata = append(b.Metadata, *values[i]) + } + return b +} + +// WithConfigDrive sets the ConfigDrive field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ConfigDrive field is set to the value of the last call. +func (b *ServerResourceSpecApplyConfiguration) WithConfigDrive(value bool) *ServerResourceSpecApplyConfiguration { + b.ConfigDrive = &value + return b +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/serverresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/serverresourcestatus.go index 119583f20..12f1a1032 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/serverresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/serverresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -30,6 +30,8 @@ type ServerResourceStatusApplyConfiguration struct { Volumes []ServerVolumeStatusApplyConfiguration `json:"volumes,omitempty"` Interfaces []ServerInterfaceStatusApplyConfiguration `json:"interfaces,omitempty"` Tags []string `json:"tags,omitempty"` + Metadata []ServerMetadataStatusApplyConfiguration `json:"metadata,omitempty"` + ConfigDrive *bool `json:"configDrive,omitempty"` } // ServerResourceStatusApplyConfiguration constructs a declarative configuration of the ServerResourceStatus type for use with @@ -123,3 +125,24 @@ func (b *ServerResourceStatusApplyConfiguration) WithTags(values ...string) *Ser } return b } + +// WithMetadata adds the given value to the Metadata field in the declarative configuration +// and returns the receiver, so that objects can be build by chaining "With" function invocations. +// If called multiple times, values provided by each call will be appended to the Metadata field. +func (b *ServerResourceStatusApplyConfiguration) WithMetadata(values ...*ServerMetadataStatusApplyConfiguration) *ServerResourceStatusApplyConfiguration { + for i := range values { + if values[i] == nil { + panic("nil value passed to WithMetadata") + } + b.Metadata = append(b.Metadata, *values[i]) + } + return b +} + +// WithConfigDrive sets the ConfigDrive field in the declarative configuration to the given value +// and returns the receiver, so that objects can be built by chaining "With" function invocations. +// If called multiple times, the ConfigDrive field is set to the value of the last call. +func (b *ServerResourceStatusApplyConfiguration) WithConfigDrive(value bool) *ServerResourceStatusApplyConfiguration { + b.ConfigDrive = &value + return b +} diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/serverspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/serverspec.go index 03baf01b1..2e284079c 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/serverspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/serverspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/serverstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/serverstatus.go index d27cd78a9..c433aafb2 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/serverstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/serverstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servervolumespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/servervolumespec.go index 9ca2d0c40..bccea241b 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servervolumespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servervolumespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servervolumestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/servervolumestatus.go index 15d6b7e4b..601fcf8f9 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servervolumestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servervolumestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/service.go b/pkg/clients/applyconfiguration/api/v1alpha1/service.go index 460eeb720..30619a81b 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/service.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/service.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servicefilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/servicefilter.go index 1ca8d84b3..284623ca4 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servicefilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servicefilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/serviceimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/serviceimport.go index b719d046d..42ccae04a 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/serviceimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/serviceimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/serviceresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/serviceresourcespec.go index f03f3c54b..5fd35cef6 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/serviceresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/serviceresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/serviceresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/serviceresourcestatus.go index 88f1a8fc1..1ee6b1169 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/serviceresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/serviceresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servicespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/servicespec.go index 03cafe9b5..1cc5b6645 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servicespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servicespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/servicestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/servicestatus.go index 80bf199ba..89fa866d4 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/servicestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/servicestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/subnet.go b/pkg/clients/applyconfiguration/api/v1alpha1/subnet.go index 0c0f127fc..b4d653764 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/subnet.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/subnet.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/subnetfilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/subnetfilter.go index 7eac6055a..77070b0b1 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/subnetfilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/subnetfilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/subnetgateway.go b/pkg/clients/applyconfiguration/api/v1alpha1/subnetgateway.go index e82635429..8982b39d4 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/subnetgateway.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/subnetgateway.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/subnetimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/subnetimport.go index 7b8255fef..483fe0f1e 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/subnetimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/subnetimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/subnetresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/subnetresourcespec.go index 1e0e65238..73f73099c 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/subnetresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/subnetresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/subnetresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/subnetresourcestatus.go index 8c0f8f918..7da523a8d 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/subnetresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/subnetresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/subnetspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/subnetspec.go index ff3c3c27c..4c092dd01 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/subnetspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/subnetspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/subnetstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/subnetstatus.go index 8b8b1d216..e538e3724 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/subnetstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/subnetstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/userdataspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/userdataspec.go index bbfc17368..394503c52 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/userdataspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/userdataspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volume.go b/pkg/clients/applyconfiguration/api/v1alpha1/volume.go index 648631092..5dc4ae9ce 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volume.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volume.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumeattachmentstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumeattachmentstatus.go index d005148bf..bf2f8469c 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumeattachmentstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumeattachmentstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumefilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumefilter.go index cd69f5931..5f501b8f9 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumefilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumefilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumeimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumeimport.go index 2c8a4f667..0607f42e6 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumeimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumeimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumemetadata.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumemetadata.go index 243503205..d8a099f3a 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumemetadata.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumemetadata.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumemetadatastatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumemetadatastatus.go index 680b4a38c..5791a90fd 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumemetadatastatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumemetadatastatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumeresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumeresourcespec.go index 7386c2714..efa5c19ca 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumeresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumeresourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumeresourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumeresourcestatus.go index d3113778e..1ac93544c 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumeresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumeresourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumespec.go index 1444e10c1..e0ffdcbca 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumestatus.go index 6d93bb445..3e6be3743 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumetype.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumetype.go index baa70c6d4..67d365b19 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumetype.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumetype.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumetypeextraspec.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumetypeextraspec.go index 4dde7e431..bebc95ca9 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumetypeextraspec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumetypeextraspec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumetypeextraspecstatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumetypeextraspecstatus.go index 3bec3d64e..17928fc31 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumetypeextraspecstatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumetypeextraspecstatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumetypefilter.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumetypefilter.go index 252352714..3173d031b 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumetypefilter.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumetypefilter.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumetypeimport.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumetypeimport.go index d6756b106..e228e4c2f 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumetypeimport.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumetypeimport.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumetyperesourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumetyperesourcespec.go index f85aef90c..88691bffb 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumetyperesourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumetyperesourcespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumetyperesourcestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumetyperesourcestatus.go index 9550c19b5..a6e393435 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumetyperesourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumetyperesourcestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumetypespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumetypespec.go index ee9cb26d7..d4540dcfd 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumetypespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumetypespec.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/api/v1alpha1/volumetypestatus.go b/pkg/clients/applyconfiguration/api/v1alpha1/volumetypestatus.go index 78e67a846..64a797263 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/volumetypestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/volumetypestatus.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/applyconfiguration/internal/internal.go b/pkg/clients/applyconfiguration/internal/internal.go index b1b784c8e..3a6adc44c 100644 --- a/pkg/clients/applyconfiguration/internal/internal.go +++ b/pkg/clients/applyconfiguration/internal/internal.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -237,15 +237,15 @@ var schemaYAML = typed.YAMLObject(`types: - name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointResourceSpec map: fields: + - name: description + type: + scalar: string - name: enabled type: scalar: boolean - name: interface type: scalar: string - - name: name - type: - scalar: string - name: serviceRef type: scalar: string @@ -256,15 +256,15 @@ var schemaYAML = typed.YAMLObject(`types: - name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.EndpointResourceStatus map: fields: + - name: description + type: + scalar: string - name: enabled type: scalar: boolean - name: interface type: scalar: string - - name: name - type: - scalar: string - name: serviceID type: scalar: string @@ -1448,6 +1448,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: description type: scalar: string + - name: hostID + type: + scalar: string - name: macAddress type: scalar: string @@ -1508,6 +1511,9 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.FixedIPStatus elementRelationship: atomic + - name: hostID + type: + scalar: string - name: macAddress type: scalar: string @@ -2470,6 +2476,24 @@ var schemaYAML = typed.YAMLObject(`types: - name: portState type: scalar: string +- name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.ServerMetadata + map: + fields: + - name: key + type: + scalar: string + - name: value + type: + scalar: string +- name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.ServerMetadataStatus + map: + fields: + - name: key + type: + scalar: string + - name: value + type: + scalar: string - name: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.ServerPortSpec map: fields: @@ -2482,6 +2506,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: availabilityZone type: scalar: string + - name: configDrive + type: + scalar: boolean - name: flavorRef type: scalar: string @@ -2491,6 +2518,12 @@ var schemaYAML = typed.YAMLObject(`types: - name: keypairRef type: scalar: string + - name: metadata + type: + list: + elementType: + namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.ServerMetadata + elementRelationship: atomic - name: name type: scalar: string @@ -2524,6 +2557,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: availabilityZone type: scalar: string + - name: configDrive + type: + scalar: boolean - name: hostID type: scalar: string @@ -2536,6 +2572,12 @@ var schemaYAML = typed.YAMLObject(`types: elementType: namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.ServerInterfaceStatus elementRelationship: atomic + - name: metadata + type: + list: + elementType: + namedType: com.github.k-orc.openstack-resource-controller.v2.api.v1alpha1.ServerMetadataStatus + elementRelationship: atomic - name: name type: scalar: string diff --git a/pkg/clients/applyconfiguration/utils.go b/pkg/clients/applyconfiguration/utils.go index ed751fc92..47aeedc7d 100644 --- a/pkg/clients/applyconfiguration/utils.go +++ b/pkg/clients/applyconfiguration/utils.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -306,6 +306,10 @@ func ForKind(kind schema.GroupVersionKind) interface{} { return &apiv1alpha1.ServerInterfaceFixedIPApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("ServerInterfaceStatus"): return &apiv1alpha1.ServerInterfaceStatusApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("ServerMetadata"): + return &apiv1alpha1.ServerMetadataApplyConfiguration{} + case v1alpha1.SchemeGroupVersion.WithKind("ServerMetadataStatus"): + return &apiv1alpha1.ServerMetadataStatusApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("ServerPortSpec"): return &apiv1alpha1.ServerPortSpecApplyConfiguration{} case v1alpha1.SchemeGroupVersion.WithKind("ServerResourceSpec"): diff --git a/pkg/clients/clientset/clientset/clientset.go b/pkg/clients/clientset/clientset/clientset.go index 5dc724996..a0302397c 100644 --- a/pkg/clients/clientset/clientset/clientset.go +++ b/pkg/clients/clientset/clientset/clientset.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/fake/clientset_generated.go b/pkg/clients/clientset/clientset/fake/clientset_generated.go index 39bf8513e..042753987 100644 --- a/pkg/clients/clientset/clientset/fake/clientset_generated.go +++ b/pkg/clients/clientset/clientset/fake/clientset_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/fake/doc.go b/pkg/clients/clientset/clientset/fake/doc.go index 089f28395..5b176fb04 100644 --- a/pkg/clients/clientset/clientset/fake/doc.go +++ b/pkg/clients/clientset/clientset/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/fake/register.go b/pkg/clients/clientset/clientset/fake/register.go index 69e224215..3c6caad14 100644 --- a/pkg/clients/clientset/clientset/fake/register.go +++ b/pkg/clients/clientset/clientset/fake/register.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/scheme/doc.go b/pkg/clients/clientset/clientset/scheme/doc.go index 959b8b28d..955d36bd2 100644 --- a/pkg/clients/clientset/clientset/scheme/doc.go +++ b/pkg/clients/clientset/clientset/scheme/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/scheme/register.go b/pkg/clients/clientset/clientset/scheme/register.go index 37f2ae0a4..333c2c424 100644 --- a/pkg/clients/clientset/clientset/scheme/register.go +++ b/pkg/clients/clientset/clientset/scheme/register.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/api_client.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/api_client.go index 09c39d525..f90697ff5 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/api_client.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/api_client.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/doc.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/doc.go index b757132de..ab5d0be93 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/doc.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/domain.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/domain.go index f76ed31fe..83ba6d973 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/domain.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/domain.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/endpoint.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/endpoint.go index 8c0f3c58b..4eda9ea43 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/endpoint.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/endpoint.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/doc.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/doc.go index 1b3dfc5a5..d409d454c 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/doc.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/doc.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_api_client.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_api_client.go index dfe83cdee..8872b9ab7 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_api_client.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_api_client.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_domain.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_domain.go index ef082eb77..ea78b8a40 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_domain.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_domain.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_endpoint.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_endpoint.go index bc2842cde..ab36dca23 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_endpoint.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_endpoint.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_flavor.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_flavor.go index 1686abb94..bf4efd93d 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_flavor.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_flavor.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_floatingip.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_floatingip.go index e720499d5..136c49056 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_floatingip.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_floatingip.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_group.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_group.go index c3a168e1c..2ef581ba1 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_group.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_group.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_image.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_image.go index 6efdd68ea..bc5bbc879 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_image.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_image.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_keypair.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_keypair.go index cbbf5a3a2..37553ac03 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_keypair.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_keypair.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_network.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_network.go index 52d96bb68..f68d65923 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_network.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_network.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_port.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_port.go index 3f20c5d01..540a5ba2c 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_port.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_port.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_project.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_project.go index c1f1f6046..c75981692 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_project.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_project.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_role.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_role.go index e7701df25..3dc54b77d 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_role.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_role.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_router.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_router.go index 831c9220e..dec48bdd2 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_router.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_router.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_routerinterface.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_routerinterface.go index 34d76d5cd..b519e73e8 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_routerinterface.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_routerinterface.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_securitygroup.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_securitygroup.go index 2ef4b1ba6..865fb786c 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_securitygroup.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_securitygroup.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_server.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_server.go index 9ae492970..a8e37ad42 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_server.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_server.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_servergroup.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_servergroup.go index 61816c71a..3c1cbf2fb 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_servergroup.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_servergroup.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_service.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_service.go index 0c175dad5..17971c02b 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_service.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_service.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_subnet.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_subnet.go index 540939764..9dd38a30f 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_subnet.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_subnet.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_volume.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_volume.go index c1097298c..fef4e1e78 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_volume.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_volume.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_volumetype.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_volumetype.go index 7797551bd..126aebd95 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_volumetype.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/fake/fake_volumetype.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/flavor.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/flavor.go index d2bcfddad..7f59e0ef1 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/flavor.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/flavor.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/floatingip.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/floatingip.go index defa84705..00a9802a4 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/floatingip.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/floatingip.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/generated_expansion.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/generated_expansion.go index a2aff2eff..2b5405b4b 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/generated_expansion.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/generated_expansion.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/group.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/group.go index 5dc034c44..a8e168094 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/group.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/group.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/image.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/image.go index d15056837..bb719a623 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/image.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/image.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/keypair.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/keypair.go index 71d9d50b6..f2d1f177e 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/keypair.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/keypair.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/network.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/network.go index bd0756eb5..2422c0b25 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/network.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/network.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/port.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/port.go index 33fd81223..e59bc653b 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/port.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/port.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/project.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/project.go index 5dfd39fd6..e777bff87 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/project.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/project.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/role.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/role.go index 779708067..5ac1433f6 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/role.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/role.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/router.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/router.go index 0e092644d..5da2176b0 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/router.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/router.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/routerinterface.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/routerinterface.go index 195f91f02..3d6e86c32 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/routerinterface.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/routerinterface.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/securitygroup.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/securitygroup.go index c71c2affe..d996525f2 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/securitygroup.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/securitygroup.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/server.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/server.go index 0fba20892..77e068970 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/server.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/server.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/servergroup.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/servergroup.go index 4966a6301..71d968283 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/servergroup.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/servergroup.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/service.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/service.go index 1fc5509ea..ed1f4ddca 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/service.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/service.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/subnet.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/subnet.go index 10bebdfc7..8ef009c1f 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/subnet.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/subnet.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/volume.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/volume.go index 966563255..7c5147c1f 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/volume.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/volume.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/clientset/clientset/typed/api/v1alpha1/volumetype.go b/pkg/clients/clientset/clientset/typed/api/v1alpha1/volumetype.go index 352e3c31e..8aa0602c7 100644 --- a/pkg/clients/clientset/clientset/typed/api/v1alpha1/volumetype.go +++ b/pkg/clients/clientset/clientset/typed/api/v1alpha1/volumetype.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/interface.go b/pkg/clients/informers/externalversions/api/interface.go index 796462031..ca024a2e7 100644 --- a/pkg/clients/informers/externalversions/api/interface.go +++ b/pkg/clients/informers/externalversions/api/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/domain.go b/pkg/clients/informers/externalversions/api/v1alpha1/domain.go index 4c5fba2de..2e0a8879a 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/domain.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/domain.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/endpoint.go b/pkg/clients/informers/externalversions/api/v1alpha1/endpoint.go index 496b05405..7deada74f 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/endpoint.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/endpoint.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/flavor.go b/pkg/clients/informers/externalversions/api/v1alpha1/flavor.go index 3a941fc22..4f371b017 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/flavor.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/flavor.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/floatingip.go b/pkg/clients/informers/externalversions/api/v1alpha1/floatingip.go index 65cf18f1c..099d674b5 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/floatingip.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/floatingip.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/group.go b/pkg/clients/informers/externalversions/api/v1alpha1/group.go index c240e2021..eefe73c64 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/group.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/group.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/image.go b/pkg/clients/informers/externalversions/api/v1alpha1/image.go index c0a97354c..707dcfacd 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/image.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/image.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/interface.go b/pkg/clients/informers/externalversions/api/v1alpha1/interface.go index 801c38e89..f05a56e5c 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/interface.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/interface.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/keypair.go b/pkg/clients/informers/externalversions/api/v1alpha1/keypair.go index f0c1e2b57..33ef79fd4 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/keypair.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/keypair.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/network.go b/pkg/clients/informers/externalversions/api/v1alpha1/network.go index 24e300230..84e12259c 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/network.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/network.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/port.go b/pkg/clients/informers/externalversions/api/v1alpha1/port.go index 8eeaa5406..7e037c84d 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/port.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/port.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/project.go b/pkg/clients/informers/externalversions/api/v1alpha1/project.go index 345ac1c19..0025d8e21 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/project.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/project.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/role.go b/pkg/clients/informers/externalversions/api/v1alpha1/role.go index cfdb7de7a..7975f8f7e 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/role.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/role.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/router.go b/pkg/clients/informers/externalversions/api/v1alpha1/router.go index 8e5d3d4a2..fc472b5bd 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/router.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/router.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/routerinterface.go b/pkg/clients/informers/externalversions/api/v1alpha1/routerinterface.go index 1f94db3ab..b937e51f7 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/routerinterface.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/routerinterface.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/securitygroup.go b/pkg/clients/informers/externalversions/api/v1alpha1/securitygroup.go index 7680e921a..385356ccc 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/securitygroup.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/securitygroup.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/server.go b/pkg/clients/informers/externalversions/api/v1alpha1/server.go index 416e0ee84..130029213 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/server.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/server.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/servergroup.go b/pkg/clients/informers/externalversions/api/v1alpha1/servergroup.go index 70c6c1e33..3a3fd71c3 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/servergroup.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/servergroup.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/service.go b/pkg/clients/informers/externalversions/api/v1alpha1/service.go index dd9f14d78..43ca18e0a 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/service.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/service.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/subnet.go b/pkg/clients/informers/externalversions/api/v1alpha1/subnet.go index 4bfc120f0..6a902f657 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/subnet.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/subnet.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/volume.go b/pkg/clients/informers/externalversions/api/v1alpha1/volume.go index fb175347a..c42cc57a0 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/volume.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/volume.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/api/v1alpha1/volumetype.go b/pkg/clients/informers/externalversions/api/v1alpha1/volumetype.go index be022c62a..34b6336eb 100644 --- a/pkg/clients/informers/externalversions/api/v1alpha1/volumetype.go +++ b/pkg/clients/informers/externalversions/api/v1alpha1/volumetype.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/factory.go b/pkg/clients/informers/externalversions/factory.go index 3f0620df3..2260c31fb 100644 --- a/pkg/clients/informers/externalversions/factory.go +++ b/pkg/clients/informers/externalversions/factory.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/generic.go b/pkg/clients/informers/externalversions/generic.go index 1ad4042c4..d1972e11f 100644 --- a/pkg/clients/informers/externalversions/generic.go +++ b/pkg/clients/informers/externalversions/generic.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/informers/externalversions/internalinterfaces/factory_interfaces.go b/pkg/clients/informers/externalversions/internalinterfaces/factory_interfaces.go index 1ff80aa05..38e582cf3 100644 --- a/pkg/clients/informers/externalversions/internalinterfaces/factory_interfaces.go +++ b/pkg/clients/informers/externalversions/internalinterfaces/factory_interfaces.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/domain.go b/pkg/clients/listers/api/v1alpha1/domain.go index 4cae34fba..1e3d17051 100644 --- a/pkg/clients/listers/api/v1alpha1/domain.go +++ b/pkg/clients/listers/api/v1alpha1/domain.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/endpoint.go b/pkg/clients/listers/api/v1alpha1/endpoint.go index 427f09149..1d7599408 100644 --- a/pkg/clients/listers/api/v1alpha1/endpoint.go +++ b/pkg/clients/listers/api/v1alpha1/endpoint.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/expansion_generated.go b/pkg/clients/listers/api/v1alpha1/expansion_generated.go index 357c7d560..69ec8ffef 100644 --- a/pkg/clients/listers/api/v1alpha1/expansion_generated.go +++ b/pkg/clients/listers/api/v1alpha1/expansion_generated.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/flavor.go b/pkg/clients/listers/api/v1alpha1/flavor.go index 0f8cb4282..820fe098a 100644 --- a/pkg/clients/listers/api/v1alpha1/flavor.go +++ b/pkg/clients/listers/api/v1alpha1/flavor.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/floatingip.go b/pkg/clients/listers/api/v1alpha1/floatingip.go index f41a20321..f7dbc95c5 100644 --- a/pkg/clients/listers/api/v1alpha1/floatingip.go +++ b/pkg/clients/listers/api/v1alpha1/floatingip.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/group.go b/pkg/clients/listers/api/v1alpha1/group.go index 33ea8f0f5..1364f5214 100644 --- a/pkg/clients/listers/api/v1alpha1/group.go +++ b/pkg/clients/listers/api/v1alpha1/group.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/image.go b/pkg/clients/listers/api/v1alpha1/image.go index f80691124..d63ba89c8 100644 --- a/pkg/clients/listers/api/v1alpha1/image.go +++ b/pkg/clients/listers/api/v1alpha1/image.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/keypair.go b/pkg/clients/listers/api/v1alpha1/keypair.go index 6283d582e..268c14ac7 100644 --- a/pkg/clients/listers/api/v1alpha1/keypair.go +++ b/pkg/clients/listers/api/v1alpha1/keypair.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/network.go b/pkg/clients/listers/api/v1alpha1/network.go index 3039921cd..cdd26de8a 100644 --- a/pkg/clients/listers/api/v1alpha1/network.go +++ b/pkg/clients/listers/api/v1alpha1/network.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/port.go b/pkg/clients/listers/api/v1alpha1/port.go index 4a1748403..a61984e89 100644 --- a/pkg/clients/listers/api/v1alpha1/port.go +++ b/pkg/clients/listers/api/v1alpha1/port.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/project.go b/pkg/clients/listers/api/v1alpha1/project.go index 56fd8b6a3..c2dd486be 100644 --- a/pkg/clients/listers/api/v1alpha1/project.go +++ b/pkg/clients/listers/api/v1alpha1/project.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/role.go b/pkg/clients/listers/api/v1alpha1/role.go index 2068923b2..c2d62f895 100644 --- a/pkg/clients/listers/api/v1alpha1/role.go +++ b/pkg/clients/listers/api/v1alpha1/role.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/router.go b/pkg/clients/listers/api/v1alpha1/router.go index 71c3ce837..5adceeb9b 100644 --- a/pkg/clients/listers/api/v1alpha1/router.go +++ b/pkg/clients/listers/api/v1alpha1/router.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/routerinterface.go b/pkg/clients/listers/api/v1alpha1/routerinterface.go index 285c89483..0a3712f4c 100644 --- a/pkg/clients/listers/api/v1alpha1/routerinterface.go +++ b/pkg/clients/listers/api/v1alpha1/routerinterface.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/securitygroup.go b/pkg/clients/listers/api/v1alpha1/securitygroup.go index 7d0748924..5868504a9 100644 --- a/pkg/clients/listers/api/v1alpha1/securitygroup.go +++ b/pkg/clients/listers/api/v1alpha1/securitygroup.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/server.go b/pkg/clients/listers/api/v1alpha1/server.go index c79cc772a..66d769baa 100644 --- a/pkg/clients/listers/api/v1alpha1/server.go +++ b/pkg/clients/listers/api/v1alpha1/server.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/servergroup.go b/pkg/clients/listers/api/v1alpha1/servergroup.go index d376dc119..a677d2564 100644 --- a/pkg/clients/listers/api/v1alpha1/servergroup.go +++ b/pkg/clients/listers/api/v1alpha1/servergroup.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/service.go b/pkg/clients/listers/api/v1alpha1/service.go index fc5902d0b..46c571406 100644 --- a/pkg/clients/listers/api/v1alpha1/service.go +++ b/pkg/clients/listers/api/v1alpha1/service.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/subnet.go b/pkg/clients/listers/api/v1alpha1/subnet.go index 751437886..c1f916198 100644 --- a/pkg/clients/listers/api/v1alpha1/subnet.go +++ b/pkg/clients/listers/api/v1alpha1/subnet.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/volume.go b/pkg/clients/listers/api/v1alpha1/volume.go index fda954e65..70d54efc5 100644 --- a/pkg/clients/listers/api/v1alpha1/volume.go +++ b/pkg/clients/listers/api/v1alpha1/volume.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/pkg/clients/listers/api/v1alpha1/volumetype.go b/pkg/clients/listers/api/v1alpha1/volumetype.go index b2bc83536..3dcb8d773 100644 --- a/pkg/clients/listers/api/v1alpha1/volumetype.go +++ b/pkg/clients/listers/api/v1alpha1/volumetype.go @@ -1,5 +1,5 @@ /* -Copyright 2025 The ORC Authors. +Copyright The ORC Authors. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/website/docs/crd-reference.md b/website/docs/crd-reference.md index 56034cb4b..eba5a1d1e 100644 --- a/website/docs/crd-reference.md +++ b/website/docs/crd-reference.md @@ -408,7 +408,7 @@ _Appears in:_ | Field | Description | Default | Validation | | --- | --- | --- | --- | -| `name` _[OpenStackName](#openstackname)_ | name will be the name of the created resource. If not specified, the
name of the ORC object will be used. | | MaxLength: 255
MinLength: 1
Pattern: `^[^,]+$`
| +| `description` _string_ | description is a human-readable description for the resource. | | MaxLength: 255
MinLength: 1
| | `enabled` _boolean_ | enabled indicates whether the endpoint is enabled or not. | true | | | `interface` _string_ | interface indicates the visibility of the endpoint. | | Enum: [admin internal public]
| | `url` _string_ | url is the endpoint URL. | | MaxLength: 1024
| @@ -428,9 +428,9 @@ _Appears in:_ | Field | Description | Default | Validation | | --- | --- | --- | --- | -| `name` _string_ | name is a Human-readable name for the resource. Might not be unique. | | MaxLength: 1024
| +| `description` _string_ | description is a human-readable description for the resource. | | MaxLength: 255
MinLength: 1
| | `enabled` _boolean_ | enabled indicates whether the endpoint is enabled or not. | | | -| `interface` _string_ | interface indicates the visibility of the endpoint. | | Enum: [admin internal public]
| +| `interface` _string_ | interface indicates the visibility of the endpoint. | | MaxLength: 128
| | `url` _string_ | url is the endpoint URL. | | MaxLength: 1024
| | `serviceID` _string_ | serviceID is the ID of the Service to which the resource is associated. | | MaxLength: 1024
| @@ -2145,7 +2145,6 @@ _Validation:_ - Pattern: `^[^,]+$` _Appears in:_ -- [EndpointResourceSpec](#endpointresourcespec) - [FlavorFilter](#flavorfilter) - [FlavorResourceSpec](#flavorresourcespec) - [ImageFilter](#imagefilter) @@ -2314,6 +2313,7 @@ _Appears in:_ | `portSecurity` _[PortSecurityState](#portsecuritystate)_ | portSecurity controls port security for this port.
When set to Enabled, port security is enabled.
When set to Disabled, port security is disabled and SecurityGroupRefs must be empty.
When set to Inherit (default), it takes the value from the network level. | Inherit | Enum: [Enabled Disabled Inherit]
| | `projectRef` _[KubernetesNameRef](#kubernetesnameref)_ | projectRef is a reference to the ORC Project this resource is associated with.
Typically, only used by admin. | | MaxLength: 253
MinLength: 1
| | `macAddress` _string_ | macAddress is the MAC address of the port. | | MaxLength: 32
| +| `hostID` _string_ | hostID is the ID of host where the port resides. | | MaxLength: 36
| #### PortResourceStatus @@ -2345,6 +2345,7 @@ _Appears in:_ | `propagateUplinkStatus` _boolean_ | propagateUplinkStatus represents the uplink status propagation of
the port. | | | | `vnicType` _string_ | vnicType is the type of vNIC which this port is attached to. | | MaxLength: 64
| | `portSecurityEnabled` _boolean_ | portSecurityEnabled indicates whether port security is enabled or not. | | | +| `hostID` _string_ | hostID is the ID of host where the port resides. | | MaxLength: 128
| | `createdAt` _[Time](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#time-v1-meta)_ | createdAt shows the date and time when the resource was created. The date and time stamp format is ISO 8601 | | | | `updatedAt` _[Time](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.29/#time-v1-meta)_ | updatedAt shows the date and time when the resource was updated. The date and time stamp format is ISO 8601 | | | | `revisionNumber` _integer_ | revisionNumber optionally set via extensions/standard-attr-revisions | | | @@ -3436,6 +3437,40 @@ _Appears in:_ | `fixedIPs` _[ServerInterfaceFixedIP](#serverinterfacefixedip) array_ | fixedIPs is the list of fixed IP addresses assigned to the interface. | | MaxItems: 32
| +#### ServerMetadata + + + +ServerMetadata represents a key-value pair for server metadata. + + + +_Appears in:_ +- [ServerResourceSpec](#serverresourcespec) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `key` _string_ | key is the metadata key. | | MaxLength: 255
MinLength: 1
| +| `value` _string_ | value is the metadata value. | | MaxLength: 255
MinLength: 1
| + + +#### ServerMetadataStatus + + + +ServerMetadataStatus represents a key-value pair for server metadata in status. + + + +_Appears in:_ +- [ServerResourceStatus](#serverresourcestatus) + +| Field | Description | Default | Validation | +| --- | --- | --- | --- | +| `key` _string_ | key is the metadata key. | | MaxLength: 255
| +| `value` _string_ | value is the metadata value. | | MaxLength: 255
| + + #### ServerPortSpec @@ -3477,6 +3512,8 @@ _Appears in:_ | `availabilityZone` _string_ | availabilityZone is the availability zone in which to create the server. | | MaxLength: 255
| | `keypairRef` _[KubernetesNameRef](#kubernetesnameref)_ | keypairRef is a reference to a KeyPair object. The server will be
created with this keypair for SSH access. | | MaxLength: 253
MinLength: 1
| | `tags` _[ServerTag](#servertag) array_ | tags is a list of tags which will be applied to the server. | | MaxItems: 50
MaxLength: 80
MinLength: 1
| +| `metadata` _[ServerMetadata](#servermetadata) array_ | Refer to Kubernetes API documentation for fields of `metadata`. | | MaxItems: 128
| +| `configDrive` _boolean_ | configDrive specifies whether to attach a config drive to the server.
When true, configuration data will be available via a special drive
instead of the metadata service. | | | #### ServerResourceStatus @@ -3501,6 +3538,8 @@ _Appears in:_ | `volumes` _[ServerVolumeStatus](#servervolumestatus) array_ | volumes contains the volumes attached to the server. | | MaxItems: 64
| | `interfaces` _[ServerInterfaceStatus](#serverinterfacestatus) array_ | interfaces contains the list of interfaces attached to the server. | | MaxItems: 64
| | `tags` _string array_ | tags is the list of tags on the resource. | | MaxItems: 50
items:MaxLength: 1024
| +| `metadata` _[ServerMetadataStatus](#servermetadatastatus) array_ | Refer to Kubernetes API documentation for fields of `metadata`. | | MaxItems: 128
| +| `configDrive` _boolean_ | configDrive indicates whether the server was booted with a config drive. | | | #### ServerSpec