Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ require (
k8s.io/klog v1.0.0
k8s.io/klog/v2 v2.9.0
sigs.k8s.io/cluster-api v1.0.2
sigs.k8s.io/cluster-api-provider-openstack v0.5.1-0.20211208064945-172c23f148b0
sigs.k8s.io/cluster-api-provider-openstack v0.5.1-0.20211214023603-b936d98a83d6
sigs.k8s.io/controller-runtime v0.10.3
sigs.k8s.io/yaml v1.3.0
)
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1732,8 +1732,8 @@ sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.21/go.mod h1:LEScyz
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
sigs.k8s.io/cluster-api v1.0.2 h1:V2pzMUfyVv29vf6q5RVLuPIp8PAcnLYcBcH9bzoMDLY=
sigs.k8s.io/cluster-api v1.0.2/go.mod h1:/LkJXtsvhxTV4U0z1Y2Y1Gr2xebJ0/ce09Ab2M0XU/U=
sigs.k8s.io/cluster-api-provider-openstack v0.5.1-0.20211208064945-172c23f148b0 h1:+haTo0D3bJzbTG0bTA3Hcyv8aNVfMYh186SO7Xyc1eU=
sigs.k8s.io/cluster-api-provider-openstack v0.5.1-0.20211208064945-172c23f148b0/go.mod h1:DjUUwFBscjYRihaHOXVMtNlBBazsstagsGO72TrqUik=
sigs.k8s.io/cluster-api-provider-openstack v0.5.1-0.20211214023603-b936d98a83d6 h1:Yw23vTEMI9fjxC+rMaYlzP3TImDf7HQb8r3qy0ol4Vg=
sigs.k8s.io/cluster-api-provider-openstack v0.5.1-0.20211214023603-b936d98a83d6/go.mod h1:DjUUwFBscjYRihaHOXVMtNlBBazsstagsGO72TrqUik=
sigs.k8s.io/cluster-api/test v1.0.1-0.20211028151834-d72fd59c8483/go.mod h1:NISRUeCxvEa6qUhVtfWt0t/C9ljTzGT9joft0YeN+3s=
sigs.k8s.io/controller-runtime v0.9.6/go.mod h1:q6PpkM5vqQubEKUKOM6qr06oXGzOBcCby1DA9FbyZeA=
sigs.k8s.io/controller-runtime v0.10.3-0.20211011182302-43ea648ec318/go.mod h1:CQp8eyUQZ/Q7PJvnIrB6/hgfTC1kBkGylwsLgOQi1WY=
Expand Down
206 changes: 185 additions & 21 deletions pkg/apis/openstackproviderconfig/v1alpha1/convert.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
package v1alpha1

import (
"fmt"

"github.com/gophercloud/gophercloud/openstack/networking/v2/subnets"
machinev1 "github.com/openshift/api/machine/v1beta1"
capov1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1"
"sigs.k8s.io/cluster-api-provider-openstack/pkg/cloud/services/networking"
)

func (cps OpenstackClusterProviderSpec) toClusterSpec() capov1.OpenStackClusterSpec {
Expand Down Expand Up @@ -51,7 +55,166 @@ func NewOpenStackCluster(providerSpec OpenstackClusterProviderSpec, providerStat
}
}

func (ps OpenstackProviderSpec) toMachineSpec() capov1.OpenStackMachineSpec {
// Looks up a subnet in openstack and gets the ID of the network its attached to
func (filter SubnetFilter) getNetworkID(networkService *networking.Service) (string, error) {
listOpts := subnets.ListOpts(filter)
subnets, err := networkService.GetSubnetsByFilter(listOpts)
if err != nil {
return "", err
}

if len(subnets) != 1 {
return "", fmt.Errorf("subnet query must return only 1 subnet")
}
return subnets[0].NetworkID, nil
}

// Converts NetworkParams to capov1 portOpts
func (net NetworkParam) toCapov1PortOpt(apiVIP, ingressVIP string, trunk *bool, networkService *networking.Service) ([]capov1.PortOpts, error) {
ports := []capov1.PortOpts{}
addressPairs := []capov1.AddressPair{}
if !net.NoAllowedAddressPairs {
addressPairs = []capov1.AddressPair{
{
IPAddress: apiVIP,
},
{
IPAddress: ingressVIP,
},
}
}

// Flip the value of port security if not nil
// must preserve 3 use cases:
// nil: openstack default
// true: set explicitly to true
// false: set explicitly to false
disablePortSecurity := net.PortSecurity
if net.PortSecurity != nil {
ps := !*disablePortSecurity
disablePortSecurity = &ps
}

network := capov1.NetworkFilter{
ID: net.UUID,
Name: net.Filter.Name,
Description: net.Filter.Description,
ProjectID: net.Filter.ProjectID,
Tags: net.Filter.Tags,
TagsAny: net.Filter.TagsAny,
NotTags: net.Filter.NotTags,
NotTagsAny: net.Filter.NotTagsAny,
}
if network.ID == "" {
network.ID = net.Filter.ID
}

tags := net.PortTags

if network.ID == "" && (net.Filter == Filter{}) {
// Case: network is undefined and only has subnets
// Create a port for each subnet
for _, subnet := range net.Subnets {
if subnet.Filter.ID == "" {
subnet.Filter.ID = subnet.UUID
}

subnetID := subnet.UUID
if subnetID == "" {
subnetID = subnet.Filter.ID
}

fixedIP := []capov1.FixedIP{
{
Subnet: &capov1.SubnetFilter{
Name: subnet.Filter.Name,
Description: subnet.Filter.Description,
ProjectID: subnet.Filter.ProjectID,
IPVersion: subnet.Filter.IPVersion,
GatewayIP: subnet.Filter.GatewayIP,
CIDR: subnet.Filter.CIDR,
IPv6AddressMode: subnet.Filter.IPv6AddressMode,
IPv6RAMode: subnet.Filter.IPv6RAMode,
ID: subnetID,
Tags: subnet.Filter.Tags,
TagsAny: subnet.Filter.TagsAny,
NotTags: subnet.Filter.NotTags,
NotTagsAny: subnet.Filter.NotTagsAny,
},
},
}

portTags := append(tags, subnet.PortTags...)

port := capov1.PortOpts{
Network: &network,
AllowedAddressPairs: addressPairs,
Trunk: trunk,
DisablePortSecurity: disablePortSecurity,
VNICType: net.VNICType,
FixedIPs: fixedIP,
Tags: portTags,
}

// Fetch the UUID of the network subnet is attached to or the conversion will fail
// NOTE: limited to returning only 1 result, which deviates from CAPO api
// but resolves a lot of problems created by the previous api
netID, err := subnet.Filter.getNetworkID(networkService)
if err != nil {
return []capov1.PortOpts{}, err
}

port.Network.ID = netID
ports = append(ports, port)

}
} else {
// Case: network and subnet are defined
// Create a single port with an interface for each subnet
fixedIPs := make([]capov1.FixedIP, len(net.Subnets))
for i, subnet := range net.Subnets {
id := subnet.UUID
if id == "" {
id = subnet.Filter.ID
}

fixedIPs[i] = capov1.FixedIP{
Subnet: &capov1.SubnetFilter{
Name: subnet.Filter.Name,
Description: subnet.Filter.Description,
ProjectID: subnet.Filter.ProjectID,
IPVersion: subnet.Filter.IPVersion,
GatewayIP: subnet.Filter.GatewayIP,
CIDR: subnet.Filter.CIDR,
IPv6AddressMode: subnet.Filter.IPv6AddressMode,
IPv6RAMode: subnet.Filter.IPv6RAMode,
ID: id,
Tags: subnet.Filter.Tags,
TagsAny: subnet.Filter.TagsAny,
NotTags: subnet.Filter.NotTags,
NotTagsAny: subnet.Filter.NotTagsAny,
},
}
tags = append(tags, subnet.PortTags...)
}

port := capov1.PortOpts{
Network: &network,
AllowedAddressPairs: addressPairs,
Trunk: trunk,
DisablePortSecurity: disablePortSecurity,
VNICType: net.VNICType,
FixedIPs: fixedIPs,
Tags: tags,
}

ports = append(ports, port)
}

return ports, nil
}

func (ps OpenstackProviderSpec) toMachineSpec(apiVIP, ingressVIP string, networkService *networking.Service) (capov1.OpenStackMachineSpec, error) {
machineSpec := capov1.OpenStackMachineSpec{
CloudName: ps.CloudName,
Flavor: ps.Flavor,
Expand Down Expand Up @@ -90,10 +253,9 @@ func (ps OpenstackProviderSpec) toMachineSpec() capov1.OpenStackMachineSpec {
}
}

// TODO: close upstream/downstream feature gap: port security
for i, port := range ps.Ports {
machineSpec.Ports[i] = capov1.PortOpts{
NetworkID: port.NetworkID,
Network: &capov1.NetworkFilter{ID: port.NetworkID},
NameSuffix: port.NameSuffix,
Description: port.Description,
AdminStateUp: port.AdminStateUp,
Expand All @@ -108,46 +270,48 @@ func (ps OpenstackProviderSpec) toMachineSpec() capov1.OpenStackMachineSpec {
}

for fixedIPindex, fixedIP := range port.FixedIPs {
machineSpec.Ports[i].FixedIPs[fixedIPindex] = capov1.FixedIP(fixedIP)
machineSpec.Ports[i].FixedIPs[fixedIPindex] = capov1.FixedIP{
Subnet: &capov1.SubnetFilter{ID: fixedIP.SubnetID},
IPAddress: fixedIP.IPAddress,
}
}

for addrPairIndex, addrPair := range port.AllowedAddressPairs {
machineSpec.Ports[i].AllowedAddressPairs[addrPairIndex] = capov1.AddressPair(addrPair)
}
}

// TODO: close upstream/downstream feature gap or depricate feature in favor of ports interface: port tags, port security
for i, network := range ps.Networks {
machineSpec.Networks[i] = capov1.NetworkParam{
UUID: network.UUID,
FixedIP: network.FixedIp,
Filter: capov1.Filter(network.Filter),
Subnets: make([]capov1.SubnetParam, len(network.Subnets)),
}
for subnetIndex, subnet := range network.Subnets {
machineSpec.Networks[i].Subnets[subnetIndex] = capov1.SubnetParam{
UUID: subnet.UUID,
Filter: capov1.SubnetFilter(subnet.Filter),
}
portList := []capov1.PortOpts{}
for _, network := range ps.Networks {
ports, err := network.toCapov1PortOpt(apiVIP, ingressVIP, &ps.Trunk, networkService)
if err != nil {
return capov1.OpenStackMachineSpec{}, err
}
portList = append(portList, ports...)
}

return machineSpec
machineSpec.Ports = append(machineSpec.Ports, portList...)

return machineSpec, nil
}

func NewOpenStackMachine(machine *machinev1.Machine) (*capov1.OpenStackMachine, error) {
func NewOpenStackMachine(machine *machinev1.Machine, apiVIP, ingressVIP string, networkService *networking.Service) (*capov1.OpenStackMachine, error) {
providerSpec, err := MachineSpecFromProviderSpec(machine.Spec.ProviderSpec)
if err != nil {
return nil, err
}

machineSpec, err := providerSpec.toMachineSpec(apiVIP, ingressVIP, networkService)
if err != nil {
return nil, err
}

osMachine := &capov1.OpenStackMachine{
ObjectMeta: machine.ObjectMeta,
Spec: providerSpec.toMachineSpec(),
Spec: machineSpec,
}

// if machine api master label exists, add v1beta control plane label to the node
// TODO(egarcia): fix the go mods so that we can track cluster-api@main and import this
if osMachine.ObjectMeta.Labels["machine.openshift.io/cluster-api-machine-role"] == "master" {
osMachine.ObjectMeta.Labels["cluster.x-k8s.io/control-plane"] = ""
}
Expand Down
18 changes: 17 additions & 1 deletion pkg/machine/actuator.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
configclient "github.com/openshift/client-go/config/clientset/versioned/typed/config/v1"
maoMachine "github.com/openshift/machine-api-operator/pkg/controller/machine"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -144,8 +145,23 @@ func (oc *OpenstackClient) Create(ctx context.Context, machine *machinev1.Machin
return oc.handleMachineError(machine, maoMachine.CreateMachine("error creating bootstrap for %s: %v", machine.Name, err), createEventAction)
}

clusterInfra, err := oc.params.ConfigClient.Infrastructures().Get(context.TODO(), "cluster", metav1.GetOptions{})
if err != nil {
return fmt.Errorf("Failed to retrieve cluster Infrastructure object: %v", err)
}

networkService, err := osc.getNetworkService()
if err != nil {
return err
}

// Convert to capov1
osMachine, err := openstackconfigv1.NewOpenStackMachine(machine)
osMachine, err := openstackconfigv1.NewOpenStackMachine(
machine,
clusterInfra.Status.PlatformStatus.OpenStack.APIServerInternalIP,
clusterInfra.Status.PlatformStatus.OpenStack.IngressIP,
networkService,
)
if err != nil {
return err
}
Expand Down
4 changes: 1 addition & 3 deletions vendor/modules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -663,15 +663,13 @@ k8s.io/utils/pointer
k8s.io/utils/trace
# sigs.k8s.io/cluster-api v1.0.2 => sigs.k8s.io/cluster-api v1.0.2
## explicit
sigs.k8s.io/cluster-api/api/v1alpha4
sigs.k8s.io/cluster-api/api/v1beta1
sigs.k8s.io/cluster-api/errors
sigs.k8s.io/cluster-api/feature
sigs.k8s.io/cluster-api/util
sigs.k8s.io/cluster-api/util/version
# sigs.k8s.io/cluster-api-provider-openstack v0.5.1-0.20211208064945-172c23f148b0
# sigs.k8s.io/cluster-api-provider-openstack v0.5.1-0.20211214023603-b936d98a83d6
## explicit
sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha4
sigs.k8s.io/cluster-api-provider-openstack/api/v1beta1
sigs.k8s.io/cluster-api-provider-openstack/pkg/cloud/services/compute
sigs.k8s.io/cluster-api-provider-openstack/pkg/cloud/services/networking
Expand Down
Loading