Skip to content

Commit

Permalink
Disable/enable PortSecurity at 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 Jul 15, 2021
1 parent c73f022 commit be7d601
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 13 deletions.
3 changes: 2 additions & 1 deletion api/v1alpha4/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ type PortOpts struct {
ProjectID string `json:"projectId,omitempty"`
SecurityGroups *[]string `json:"securityGroups,omitempty"`
AllowedAddressPairs []AddressPair `json:"allowedAddressPairs,omitempty"`

// Disables the PortSecurity at the network level. If disabled, PortSecurity is also disabled for all ports.
DisablePortSecurity bool `json:"disablePortSecurity,omitempty"`
// The ID of the host where the port is allocated
HostID string `json:"hostId,omitempty"`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1264,6 +1264,11 @@ spec:
type: array
description:
type: string
disablePortSecurity:
description: Disables the PortSecurity at the network
level. If disabled, PortSecurity is also disabled
for all ports.
type: boolean
fixedIPs:
description: Specify pairs of subnet and/or IP address.
These should be subnets of the network with the given
Expand Down Expand Up @@ -1693,6 +1698,11 @@ spec:
type: array
description:
type: string
disablePortSecurity:
description: Disables the PortSecurity at the network
level. If disabled, PortSecurity is also disabled
for all ports.
type: boolean
fixedIPs:
description: Specify pairs of subnet and/or IP address.
These should be subnets of the network with the given
Expand Down Expand Up @@ -1958,6 +1968,10 @@ spec:
type: array
description:
type: string
disablePortSecurity:
description: Disables the PortSecurity at the network level.
If disabled, PortSecurity is also disabled for all ports.
type: boolean
fixedIPs:
description: Specify pairs of subnet and/or IP address. These
should be subnets of the network with the given NetworkID.
Expand Down Expand Up @@ -2102,6 +2116,10 @@ spec:
type: array
description:
type: string
disablePortSecurity:
description: Disables the PortSecurity at the network level.
If disabled, PortSecurity is also disabled for all ports.
type: boolean
fixedIPs:
description: Specify pairs of subnet and/or IP address. These
should be subnets of the network with the given NetworkID.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,10 @@ spec:
type: array
description:
type: string
disablePortSecurity:
description: Disables the PortSecurity at the network level.
If disabled, PortSecurity is also disabled for all ports.
type: boolean
fixedIPs:
description: Specify pairs of subnet and/or IP address. These
should be subnets of the network with the given NetworkID.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,11 @@ spec:
type: array
description:
type: string
disablePortSecurity:
description: Disables the PortSecurity at the network
level. If disabled, PortSecurity is also disabled
for all ports.
type: boolean
fixedIPs:
description: Specify pairs of subnet and/or IP address.
These should be subnets of the network with the given
Expand Down
7 changes: 7 additions & 0 deletions docs/book/src/clusteropenstack/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,13 @@ A floating IP is created and associated to the bastion host automatically, but y

If `managedSecurityGroups: true`, security group rule opening 22/tcp is added to security groups for bastion, controller, and worker nodes respectively. Otherwise, you have to add `securityGroups` to the `bastion` in `OpenStackCluster` spec and `OpenStackMachineTemplate` spec template respectively.

If PortSecurity disable for all ports either by setting `OpenStackCluster.spec.disablePortSecurity: true` or for each port individually, `managedSecurityGroups: false` is the only valid option. The following is not a valid coonfiguration and is not supported.

```
OpenStackCluster.spec.disablePortSecurity: true
OpenStackCluster.spec.managedSecurityGroups: true
```

### Obtain floating IP address of the bastion node

Once the workload cluster is up and running after being configured for an SSH bastion host, you can use the kubectl get openstackcluster command to look up the floating IP address of the bastion host (make sure the kubectl context is set to the management cluster). The output will look something like this:
Expand Down
4 changes: 2 additions & 2 deletions pkg/cloud/services/compute/bastion.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ func (s *Service) CreateBastion(openStackCluster *infrav1.OpenStackCluster, clus
}}
}
input.Networks = &nets

out, err := s.createInstance(openStackCluster, clusterName, input)
networkLevelPortSecurityDisabled := openStackCluster.Spec.DisablePortSecurity
out, err := s.createInstance(openStackCluster, clusterName, input, networkLevelPortSecurityDisabled)
if err != nil {
return nil, err
}
Expand Down
56 changes: 46 additions & 10 deletions pkg/cloud/services/compute/instance.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import (
netext "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/attributestags"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/portsbinding"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/portsecurity"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/security/groups"
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/trunks"
"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
Expand Down Expand Up @@ -65,6 +66,11 @@ const (
timeoutInstanceDelete = 5 * time.Minute
)

var portWithPortSecurityExtensions struct {
ports.Port
portsecurity.PortSecurityExt
}

func (s *Service) CreateInstance(openStackCluster *infrav1.OpenStackCluster, machine *clusterv1.Machine, openStackMachine *infrav1.OpenStackMachine, clusterName string, userData string) (instance *infrav1.Instance, err error) {
if openStackMachine == nil {
return nil, fmt.Errorf("create Options need be specified to create instace")
Expand Down Expand Up @@ -131,8 +137,8 @@ func (s *Service) CreateInstance(openStackCluster *infrav1.OpenStackCluster, mac
return nil, err
}
input.Networks = nets

out, err := s.createInstance(openStackMachine, clusterName, input)
networkLevelPortSecurityDisabled := openStackCluster.Spec.DisablePortSecurity
out, err := s.createInstance(openStackMachine, clusterName, input, networkLevelPortSecurityDisabled)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -174,12 +180,15 @@ func (s *Service) constructNetworks(openStackCluster *infrav1.OpenStackCluster,
Subnet: &infrav1.Subnet{
ID: openStackCluster.Status.Network.Subnet.ID,
},
PortOpts: &infrav1.PortOpts{
DisablePortSecurity: openStackCluster.Spec.DisablePortSecurity,
},
}}
}
return &nets, nil
}

func (s *Service) createInstance(eventObject runtime.Object, clusterName string, instance *infrav1.Instance) (*infrav1.Instance, error) {
func (s *Service) createInstance(eventObject runtime.Object, clusterName string, instance *infrav1.Instance, networkLevelPortSecurityDisabled bool) (*infrav1.Instance, error) {
accessIPv4 := ""
portList := []servers.Network{}

Expand All @@ -189,7 +198,7 @@ func (s *Service) createInstance(eventObject runtime.Object, clusterName string,
}

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, networkLevelPortSecurityDisabled)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -423,7 +432,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, networkDisabledPortSecurity bool) (*ports.Port, error) {
mc := metrics.NewMetricPrometheusContext("port", "list")
allPages, err := ports.List(s.networkClient, ports.ListOpts{
Name: portName,
Expand Down Expand Up @@ -462,6 +471,10 @@ func (s *Service) getOrCreatePort(eventObject runtime.Object, clusterName string
securityGroups = instanceSecurityGroups
}

if networkDisabledPortSecurity {
portOpts.DisablePortSecurity = true
record.Eventf(eventObject, "Port inherited network level PortSecurity policy", "port: %s", portName)
}
createOpts := ports.CreateOpts{
Name: portName,
NetworkID: net.ID,
Expand All @@ -474,13 +487,18 @@ func (s *Service) getOrCreatePort(eventObject runtime.Object, clusterName string
AllowedAddressPairs: []ports.AddressPair{},
}

for _, ap := range portOpts.AllowedAddressPairs {
createOpts.AllowedAddressPairs = append(createOpts.AllowedAddressPairs, ports.AddressPair{
IPAddress: ap.IPAddress,
MACAddress: ap.MACAddress,
})
if !portOpts.DisablePortSecurity {
for _, ap := range portOpts.AllowedAddressPairs {
createOpts.AllowedAddressPairs = append(createOpts.AllowedAddressPairs, ports.AddressPair{
IPAddress: ap.IPAddress,
MACAddress: ap.MACAddress,
})
}
}

if portOpts.DisablePortSecurity {
createOpts.SecurityGroups = &[]string{}
}
fixedIPs := make([]ports.IP, 0, len(portOpts.FixedIPs)+1)
for _, fixedIP := range portOpts.FixedIPs {
fixedIPs = append(fixedIPs, ports.IP{
Expand Down Expand Up @@ -508,6 +526,24 @@ 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.DisablePortSecurity {
err = ports.Get(s.networkClient, port.ID).ExtractInto(&portWithPortSecurityExtensions)
if err != nil {
return nil, fmt.Errorf("unable to retrieve por %s: %v", port.Name, err)
}
if portWithPortSecurityExtensions.PortSecurityEnabled {
iFalse := false
portUpdateOpts := ports.UpdateOpts{}
updateOpts := portsecurity.PortUpdateOptsExt{
UpdateOptsBuilder: portUpdateOpts,
PortSecurityEnabled: &iFalse,
}
err := ports.Update(s.networkClient, port.ID, updateOpts).ExtractInto(&portWithPortSecurityExtensions)
if err != nil {
return nil, fmt.Errorf("unable to disable portSecurity at port level: %v", err)
}
}
}
return port, nil
}

Expand Down

0 comments on commit be7d601

Please sign in to comment.