diff --git a/api/v1alpha4/types.go b/api/v1alpha4/types.go index 7130df23d2..578aa5d3dc 100644 --- a/api/v1alpha4/types.go +++ b/api/v1alpha4/types.go @@ -55,7 +55,9 @@ type SecurityGroupFilter struct { } type NetworkParam struct { - // The UUID of the network. Required if you omit the port attribute. + // Optional UUID of the network. + // If specified this will not be validated prior to server creation. + // Required if `Subnets` specifies a subnet by UUID. UUID string `json:"uuid,omitempty"` // A fixed IPv4 address for the NIC. FixedIP string `json:"fixedIP,omitempty"` @@ -85,10 +87,12 @@ type Filter struct { } type SubnetParam struct { - // The UUID of the network. Required if you omit the port attribute. + // Optional UUID of the subnet. + // If specified this will not be validated prior to server creation. + // If specified, the enclosing `NetworkParam` must also be specified by UUID. UUID string `json:"uuid,omitempty"` - // Filters for optional network query + // Filters for optional subnet query Filter SubnetFilter `json:"filter,omitempty"` } 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 8d024dd3c5..0ff3527731 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclusters.yaml @@ -1193,7 +1193,7 @@ spec: items: properties: filter: - description: Filters for optional network query + description: Filters for optional subnet query properties: cidr: type: string @@ -1239,14 +1239,17 @@ spec: type: string type: object uuid: - description: The UUID of the network. Required - if you omit the port attribute. + description: Optional UUID of the subnet. If specified + this will not be validated prior to server creation. + If specified, the enclosing `NetworkParam` must + also be specified by UUID. type: string type: object type: array uuid: - description: The UUID of the network. Required if you - omit the port attribute. + description: Optional UUID of the network. If specified + this will not be validated prior to server creation. + Required if `Subnets` specifies a subnet by UUID. type: string type: object type: array @@ -1475,7 +1478,7 @@ spec: Gateway of this router properties: filter: - description: Filters for optional network query + description: Filters for optional subnet query properties: cidr: type: string @@ -1521,8 +1524,10 @@ spec: type: string type: object uuid: - description: The UUID of the network. Required if you omit - the port attribute. + description: Optional UUID of the subnet. If specified this + will not be validated prior to server creation. If specified, + the enclosing `NetworkParam` must also be specified by + UUID. type: string type: object required: 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 f7fbeac564..874431602c 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackclustertemplates.yaml @@ -173,7 +173,7 @@ spec: items: properties: filter: - description: Filters for optional network + description: Filters for optional subnet query properties: cidr: @@ -220,14 +220,19 @@ spec: type: string type: object uuid: - description: The UUID of the network. - Required if you omit the port attribute. + description: Optional UUID of the subnet. + If specified this will not be validated + prior to server creation. If specified, + the enclosing `NetworkParam` must also + be specified by UUID. type: string type: object type: array uuid: - description: The UUID of the network. Required - if you omit the port attribute. + description: Optional UUID of the network. If + specified this will not be validated prior + to server creation. Required if `Subnets` + specifies a subnet by UUID. type: string type: object type: array @@ -463,7 +468,7 @@ spec: for the Gateway of this router properties: filter: - description: Filters for optional network query + description: Filters for optional subnet query properties: cidr: type: string @@ -509,8 +514,10 @@ spec: type: string type: object uuid: - description: The UUID of the network. Required if - you omit the port attribute. + description: Optional UUID of the subnet. If specified + this will not be validated prior to server creation. + If specified, the enclosing `NetworkParam` must + also be specified by UUID. type: string type: object required: 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 90a7bd4805..e017bfbbe5 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachines.yaml @@ -487,7 +487,7 @@ spec: items: properties: filter: - description: Filters for optional network query + description: Filters for optional subnet query properties: cidr: type: string @@ -533,14 +533,17 @@ spec: type: string type: object uuid: - description: The UUID of the network. Required if you - omit the port attribute. + description: Optional UUID of the subnet. If specified + this will not be validated prior to server creation. + If specified, the enclosing `NetworkParam` must also + be specified by UUID. type: string type: object type: array uuid: - description: The UUID of the network. Required if you omit the - port attribute. + description: Optional UUID of the network. If specified this + will not be validated prior to server creation. Required if + `Subnets` specifies a subnet by UUID. type: string type: object type: array 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 f82d2dd9e3..970a8dab37 100644 --- a/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml +++ b/config/crd/bases/infrastructure.cluster.x-k8s.io_openstackmachinetemplates.yaml @@ -432,7 +432,7 @@ spec: items: properties: filter: - description: Filters for optional network query + description: Filters for optional subnet query properties: cidr: type: string @@ -478,14 +478,17 @@ spec: type: string type: object uuid: - description: The UUID of the network. Required - if you omit the port attribute. + description: Optional UUID of the subnet. If specified + this will not be validated prior to server creation. + If specified, the enclosing `NetworkParam` must + also be specified by UUID. type: string type: object type: array uuid: - description: The UUID of the network. Required if you - omit the port attribute. + description: Optional UUID of the network. If specified + this will not be validated prior to server creation. + Required if `Subnets` specifies a subnet by UUID. type: string type: object type: array diff --git a/pkg/cloud/services/compute/instance.go b/pkg/cloud/services/compute/instance.go index e91522c73e..3dece454a6 100644 --- a/pkg/cloud/services/compute/instance.go +++ b/pkg/cloud/services/compute/instance.go @@ -332,6 +332,13 @@ func (s *Service) getServerNetworks(networkParams []infrav1.NetworkParam) ([]inf for _, subnet := range networkParam.Subnets { // Don't lookup subnet if it was specified explicitly by UUID if subnet.UUID != "" { + // If subnet was supplied by UUID then network + // must also have been supplied by UUID. + if netID == "" { + return fmt.Errorf("validation error adding network for subnet %s: "+ + "network uuid must be specified when subnet uuid is specified", subnet.UUID) + } + addSubnet(netID, subnet.UUID) continue } diff --git a/pkg/cloud/services/compute/instance_test.go b/pkg/cloud/services/compute/instance_test.go index 1771685104..6bc36cbf1f 100644 --- a/pkg/cloud/services/compute/instance_test.go +++ b/pkg/cloud/services/compute/instance_test.go @@ -328,6 +328,18 @@ func TestService_getServerNetworks(t *testing.T) { }, wantErr: true, }, + { + name: "Subnet UUID without network", + networkParams: []infrav1.NetworkParam{ + {Subnets: []infrav1.SubnetParam{ + {UUID: subnetA1UUID}, + }}, + }, + want: nil, + expect: func(m *mock_networking.MockNetworkClientMockRecorder) { + }, + wantErr: true, + }, } for _, tt := range tests {