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/cmd/models-schema/zz_generated.openapi.go b/cmd/models-schema/zz_generated.openapi.go index 37432d6b8..16bf94279 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_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"}, }, @@ -5086,6 +5093,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", 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/internal/controllers/port/actuator.go b/internal/controllers/port/actuator.go index 61c23c7b5..692474e41 100644 --- a/internal/controllers/port/actuator.go +++ b/internal/controllers/port/actuator.go @@ -254,6 +254,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 +505,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/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go b/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go index ac7d4ed07..ba3979e9e 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portresourcespec.go @@ -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..f4b34cad1 100644 --- a/pkg/clients/applyconfiguration/api/v1alpha1/portresourcestatus.go +++ b/pkg/clients/applyconfiguration/api/v1alpha1/portresourcestatus.go @@ -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/internal/internal.go b/pkg/clients/applyconfiguration/internal/internal.go index e3cbf8592..4b97cb3ea 100644 --- a/pkg/clients/applyconfiguration/internal/internal.go +++ b/pkg/clients/applyconfiguration/internal/internal.go @@ -1333,6 +1333,9 @@ var schemaYAML = typed.YAMLObject(`types: - name: description type: scalar: string + - name: hostID + type: + scalar: string - name: macAddress type: scalar: string @@ -1393,6 +1396,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 diff --git a/website/docs/crd-reference.md b/website/docs/crd-reference.md index da7cd698d..38766bd7b 100644 --- a/website/docs/crd-reference.md +++ b/website/docs/crd-reference.md @@ -2171,6 +2171,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 @@ -2202,6 +2203,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 | | |