Skip to content

Commit

Permalink
Allow Trunk configuration at a Port level.
Browse files Browse the repository at this point in the history
Signed-off-by: Anwar Hassen <[email protected]>
  • Loading branch information
Anwar Hassen committed Aug 5, 2021
1 parent 22f77e6 commit dd8dc0e
Show file tree
Hide file tree
Showing 7 changed files with 69 additions and 20 deletions.
2 changes: 2 additions & 0 deletions api/v1alpha4/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ type PortOpts struct {
ProjectID string `json:"projectId,omitempty"`
SecurityGroups *[]string `json:"securityGroups,omitempty"`
AllowedAddressPairs []AddressPair `json:"allowedAddressPairs,omitempty"`
// Enables and disables trunk at port level. If not provided, openStackMachine.Spec.Trunk is inherited.
Trunk *bool `json:"trunk,omitempty"`

// The ID of the host where the port is allocated
HostID string `json:"hostId,omitempty"`
Expand Down
5 changes: 5 additions & 0 deletions api/v1alpha4/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -1314,6 +1314,10 @@ spec:
type: array
tenantId:
type: string
trunk:
description: Enables and disables trunk at port level.
If not provided, openStackMachine.Spec.Trunk is inherited.
type: boolean
vnicType:
description: The virtual network interface card (vNIC)
type that is bound to the neutron port.
Expand Down Expand Up @@ -1755,6 +1759,10 @@ spec:
type: array
tenantId:
type: string
trunk:
description: Enables and disables trunk at port level.
If not provided, openStackMachine.Spec.Trunk is inherited.
type: boolean
vnicType:
description: The virtual network interface card (vNIC)
type that is bound to the neutron port.
Expand Down Expand Up @@ -2024,6 +2032,10 @@ spec:
type: array
tenantId:
type: string
trunk:
description: Enables and disables trunk at port level. If
not provided, openStackMachine.Spec.Trunk is inherited.
type: boolean
vnicType:
description: The virtual network interface card (vNIC) type
that is bound to the neutron port.
Expand Down Expand Up @@ -2205,6 +2217,10 @@ spec:
type: array
tenantId:
type: string
trunk:
description: Enables and disables trunk at port level. If
not provided, openStackMachine.Spec.Trunk is inherited.
type: boolean
vnicType:
description: The virtual network interface card (vNIC) type
that is bound to the neutron port.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,11 @@ spec:
type: array
tenantId:
type: string
trunk:
description: Enables and disables trunk at port
level. If not provided, openStackMachine.Spec.Trunk
is inherited.
type: boolean
vnicType:
description: The virtual network interface card
(vNIC) type that is bound to the neutron port.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -604,6 +604,10 @@ spec:
type: array
tenantId:
type: string
trunk:
description: Enables and disables trunk at port level. If not
provided, openStackMachine.Spec.Trunk is inherited.
type: boolean
vnicType:
description: The virtual network interface card (vNIC) type
that is bound to the neutron port.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,10 @@ spec:
type: array
tenantId:
type: string
trunk:
description: Enables and disables trunk at port level.
If not provided, openStackMachine.Spec.Trunk is inherited.
type: boolean
vnicType:
description: The virtual network interface card (vNIC)
type that is bound to the neutron port.
Expand Down
53 changes: 33 additions & 20 deletions pkg/cloud/services/compute/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,19 +152,24 @@ func (s *Service) constructNetworks(openStackCluster *infrav1.OpenStackCluster,
}
}
for i, port := range openStackMachine.Spec.Ports {
pOpts := &openStackMachine.Spec.Ports[i]
// No Trunk field specified for the port, inherits openStackMachine.Spec.Trunk.
if pOpts.Trunk == nil {
pOpts.Trunk = &openStackMachine.Spec.Trunk
}
if port.NetworkID != "" {
nets = append(nets, infrav1.Network{
ID: port.NetworkID,
Subnet: &infrav1.Subnet{},
PortOpts: &openStackMachine.Spec.Ports[i],
PortOpts: pOpts,
})
} else {
nets = append(nets, infrav1.Network{
ID: openStackCluster.Status.Network.ID,
Subnet: &infrav1.Subnet{
ID: openStackCluster.Status.Network.Subnet.ID,
},
PortOpts: &openStackMachine.Spec.Ports[i],
PortOpts: pOpts,
})
}
}
Expand All @@ -175,6 +180,9 @@ func (s *Service) constructNetworks(openStackCluster *infrav1.OpenStackCluster,
Subnet: &infrav1.Subnet{
ID: openStackCluster.Status.Network.Subnet.ID,
},
PortOpts: &infrav1.PortOpts{
Trunk: &openStackMachine.Spec.Trunk,
},
}}
}
return &nets, nil
Expand All @@ -188,24 +196,16 @@ func (s *Service) createInstance(eventObject runtime.Object, clusterName string,
if network.ID == "" {
return nil, fmt.Errorf("no network was found or provided. Please check your machine configuration and try again")
}

iTags := []string{}
if len(instance.Tags) > 0 {
iTags = instance.Tags
}
portName := getPortName(instance.Name, network.PortOpts, i)
port, err := s.getOrCreatePort(eventObject, clusterName, portName, network, instance.SecurityGroups)
port, err := s.getOrCreatePort(eventObject, clusterName, portName, network, instance.SecurityGroups, iTags)
if err != nil {
return nil, err
}

if instance.Trunk {
trunk, err := s.getOrCreateTrunk(eventObject, clusterName, instance.Name, port.ID)
if err != nil {
return nil, err
}

if err = s.replaceAllAttributesTags(eventObject, trunk.ID, instance.Tags); err != nil {
return nil, err
}
}

for _, fip := range port.FixedIPs {
if fip.SubnetID == instance.Subnet {
accessIPv4 = fip.IPAddress
Expand Down Expand Up @@ -424,7 +424,7 @@ func (s *Service) getServerNetworks(networkParams []infrav1.NetworkParam) ([]inf
return nets, nil
}

func (s *Service) getOrCreatePort(eventObject runtime.Object, clusterName string, portName string, net infrav1.Network, instanceSecurityGroups *[]string) (*ports.Port, error) {
func (s *Service) getOrCreatePort(eventObject runtime.Object, clusterName string, portName string, net infrav1.Network, instanceSecurityGroups *[]string, tags []string) (*ports.Port, error) {
mc := metrics.NewMetricPrometheusContext("port", "list")
allPages, err := ports.List(s.networkClient, ports.ListOpts{
Name: portName,
Expand Down Expand Up @@ -527,21 +527,34 @@ func (s *Service) getOrCreatePort(eventObject runtime.Object, clusterName string
}

record.Eventf(eventObject, "SuccessfulCreatePort", "Created port %s with id %s", port.Name, port.ID)
if portOpts.Trunk != nil && *portOpts.Trunk {
trunkDescription := names.GetDescription(clusterName)
trunk, err := s.getOrCreateTrunk(eventObject, trunkDescription, port.Name, port.ID)
if err != nil {
record.Warnf(eventObject, "FailedCreateTrunk", "Failed to create trunk for port %s: %v", portName, err)
return nil, err
}
if err = s.replaceAllAttributesTags(eventObject, trunk.ID, tags); err != nil {
record.Warnf(eventObject, "FailedReplaceTags", "Failed to replace trunk tags %s: %v", portName, err)
return nil, err
}
}

return port, nil
}

func (s *Service) getOrCreateTrunk(eventObject runtime.Object, clusterName, trunkName, portID string) (*trunks.Trunk, error) {
func (s *Service) getOrCreateTrunk(eventObject runtime.Object, description, trunkName, portID string) (*trunks.Trunk, error) {
mc := metrics.NewMetricPrometheusContext("trunk", "list")
allPages, err := trunks.List(s.networkClient, trunks.ListOpts{
Name: trunkName,
PortID: portID,
}).AllPages()
if mc.ObserveRequest(err) != nil {
return nil, fmt.Errorf("searching for existing trunk for server: %v", err)
return nil, fmt.Errorf("searching for existing trunk for port: %v", err)
}
trunkList, err := trunks.ExtractTrunks(allPages)
if err != nil {
return nil, fmt.Errorf("searching for existing trunk for server: %v", err)
return nil, fmt.Errorf("searching for existing trunk for port: %v", err)
}

if len(trunkList) != 0 {
Expand All @@ -551,7 +564,7 @@ func (s *Service) getOrCreateTrunk(eventObject runtime.Object, clusterName, trun
trunkCreateOpts := trunks.CreateOpts{
Name: trunkName,
PortID: portID,
Description: names.GetDescription(clusterName),
Description: description,
}

mc = metrics.NewMetricPrometheusContext("trunk", "create")
Expand Down

0 comments on commit dd8dc0e

Please sign in to comment.