diff --git a/api/v1alpha4/types.go b/api/v1alpha4/types.go index c08891b6bb..db17a7a5e1 100644 --- a/api/v1alpha4/types.go +++ b/api/v1alpha4/types.go @@ -137,6 +137,11 @@ type PortOpts struct { // The virtual network interface card (vNIC) type that is bound to the neutron port. VNICType string `json:"vnicType,omitempty"` + // A dictionary that enables the application running on the specified + // host to pass and receive virtual network interface (VIF) port-specific + // information to the plug-in. + Profile map[string]string `json:"profile,omitempty"` + // DisablePortSecurity enables or disables the port security when set. // When not set, it takes the value of the corresponding field at the network level. DisablePortSecurity *bool `json:"disablePortSecurity,omitempty"` diff --git a/api/v1alpha4/zz_generated.deepcopy.go b/api/v1alpha4/zz_generated.deepcopy.go index 5d6e77c20c..1986e99329 100644 --- a/api/v1alpha4/zz_generated.deepcopy.go +++ b/api/v1alpha4/zz_generated.deepcopy.go @@ -812,6 +812,13 @@ func (in *PortOpts) DeepCopyInto(out *PortOpts) { *out = make([]AddressPair, len(*in)) copy(*out, *in) } + if in.Profile != nil { + in, out := &in.Profile, &out.Profile + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } if in.DisablePortSecurity != nil { in, out := &in.DisablePortSecurity, &out.DisablePortSecurity *out = new(bool) diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml index 9b8c8d0870..c8fa83aa2b 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml @@ -1306,6 +1306,14 @@ spec: create the port. If unspecified, create the port on the default cluster network. type: string + profile: + additionalProperties: + type: string + description: A dictionary that enables the application + running on the specified host to pass and receive + virtual network interface (VIF) port-specific information + to the plug-in. + type: object projectId: type: string securityGroups: @@ -1747,6 +1755,14 @@ spec: create the port. If unspecified, create the port on the default cluster network. type: string + profile: + additionalProperties: + type: string + description: A dictionary that enables the application + running on the specified host to pass and receive + virtual network interface (VIF) port-specific information + to the plug-in. + type: object projectId: type: string securityGroups: @@ -2016,6 +2032,13 @@ spec: the port. If unspecified, create the port on the default cluster network. type: string + profile: + additionalProperties: + type: string + description: A dictionary that enables the application running + on the specified host to pass and receive virtual network + interface (VIF) port-specific information to the plug-in. + type: object projectId: type: string securityGroups: @@ -2197,6 +2220,13 @@ spec: the port. If unspecified, create the port on the default cluster network. type: string + profile: + additionalProperties: + type: string + description: A dictionary that enables the application running + on the specified host to pass and receive virtual network + interface (VIF) port-specific information to the plug-in. + type: object projectId: type: string securityGroups: diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml index 85374773b7..79af0fde6a 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml @@ -288,6 +288,14 @@ spec: which to create the port. If unspecified, create the port on the default cluster network. type: string + profile: + additionalProperties: + type: string + description: A dictionary that enables the application + running on the specified host to pass and + receive virtual network interface (VIF) port-specific + information to the plug-in. + type: object projectId: type: string securityGroups: diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml index 356e344c83..8e8569a448 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml @@ -596,6 +596,13 @@ spec: the port. If unspecified, create the port on the default cluster network. type: string + profile: + additionalProperties: + type: string + description: A dictionary that enables the application running + on the specified host to pass and receive virtual network + interface (VIF) port-specific information to the plug-in. + type: object projectId: type: string securityGroups: diff --git a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml index 0145575878..125477405a 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml @@ -545,6 +545,14 @@ spec: create the port. If unspecified, create the port on the default cluster network. type: string + profile: + additionalProperties: + type: string + description: A dictionary that enables the application + running on the specified host to pass and receive + virtual network interface (VIF) port-specific information + to the plug-in. + type: object projectId: type: string securityGroups: diff --git a/docs/book/src/clusteropenstack/configuration.md b/docs/book/src/clusteropenstack/configuration.md index 8ec85a49d4..989a094b68 100644 --- a/docs/book/src/clusteropenstack/configuration.md +++ b/docs/book/src/clusteropenstack/configuration.md @@ -214,7 +214,7 @@ spec: ## Ports -A server can also be connected to networks by describing what ports to create. Describing a server's connection with `ports` allows for finer and more advanced configuration. For example, you can specify per-port security groups, fixed IPs or VNIC type. +A server can also be connected to networks by describing what ports to create. Describing a server's connection with `ports` allows for finer and more advanced configuration. For example, you can specify per-port security groups, fixed IPs, VNIC type or profile. ```yaml apiVersion: infrastructure.cluster.x-k8s.io/v1alpha4 @@ -232,6 +232,9 @@ spec: ipAddress: securityGroups: - + profile: + capabilities: + - ``` Any such ports are created in addition to ports used for connections to networks or subnets. diff --git a/pkg/cloud/services/compute/instance.go b/pkg/cloud/services/compute/instance.go index 08f1dbd1ba..2f2c05ca70 100644 --- a/pkg/cloud/services/compute/instance.go +++ b/pkg/cloud/services/compute/instance.go @@ -518,7 +518,7 @@ func (s *Service) getOrCreatePort(eventObject runtime.Object, clusterName string CreateOptsBuilder: createOpts, HostID: portOpts.HostID, VNICType: portOpts.VNICType, - Profile: nil, + Profile: getPortProfile(portOpts.Profile), } mc = metrics.NewMetricPrometheusContext("port", "create") @@ -532,6 +532,21 @@ func (s *Service) getOrCreatePort(eventObject runtime.Object, clusterName string return port, nil } +func getPortProfile(p map[string]string) map[string]interface{} { + portProfile := make(map[string]interface{}) + for k, v := range p { + portProfile[k] = v + } + // We need return nil if there is no profiles + // to have backward compatible defaults. + // To set profiles, your tenant needs this permission: + // rule:create_port and rule:create_port:binding:profile + if len(portProfile) == 0 { + return nil + } + return portProfile +} + func (s *Service) getOrCreateTrunk(eventObject runtime.Object, clusterName, trunkName, portID string) (*trunks.Trunk, error) { mc := metrics.NewMetricPrometheusContext("trunk", "list") allPages, err := trunks.List(s.networkClient, trunks.ListOpts{