github.com/openshift/installer@v1.4.17/pkg/infrastructure/openstack/preprovision/securitygroups.go (about) 1 package preprovision 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/attributestags" 8 "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/security/groups" 9 "github.com/gophercloud/gophercloud/v2/openstack/networking/v2/extensions/security/rules" 10 "github.com/sirupsen/logrus" 11 12 "github.com/openshift/installer/pkg/asset/installconfig" 13 openstackdefaults "github.com/openshift/installer/pkg/types/openstack/defaults" 14 ) 15 16 const description = "Created By OpenShift Installer" 17 18 type protocol uint8 19 20 const ( 21 _ protocol = 1 << iota 22 tcp 23 udp 24 icmp 25 esp 26 vrrp 27 ) 28 29 func (p protocol) Protocols() []rules.RuleProtocol { 30 protocols := make([]rules.RuleProtocol, 0, 2) 31 if p&tcp == tcp { 32 protocols = append(protocols, rules.ProtocolTCP) 33 } 34 if p&udp == udp { 35 protocols = append(protocols, rules.ProtocolUDP) 36 } 37 if p&icmp == icmp { 38 protocols = append(protocols, rules.ProtocolICMP) 39 } 40 if p&esp == esp { 41 protocols = append(protocols, rules.ProtocolESP) 42 } 43 if p&vrrp == vrrp { 44 protocols = append(protocols, rules.RuleProtocol("112")) 45 } 46 return protocols 47 } 48 49 // SecurityGroups creates the master and worker security groups with the security group rules. 50 func SecurityGroups(ctx context.Context, installConfig *installconfig.InstallConfig, infraID string, mastersSchedulable bool) error { 51 networkClient, err := openstackdefaults.NewServiceClient(ctx, "network", openstackdefaults.DefaultClientOpts(installConfig.Config.Platform.OpenStack.Cloud)) 52 if err != nil { 53 return err 54 } 55 56 logrus.Debugf("Creating the security groups") 57 var masterGroup, workerGroup *groups.SecGroup 58 { 59 masterGroup, err = groups.Create(ctx, networkClient, groups.CreateOpts{ 60 Name: infraID + "-master", 61 Description: description, 62 }).Extract() 63 if err != nil { 64 return fmt.Errorf("failed to create the Control plane security group: %w", err) 65 } 66 67 // The Neutron call to add a tag 68 // (https://docs.openstack.org/api-ref/network/v2/#add-a-tag) 69 // doesn't accept all special characters. Here we use the 70 // "replace-all-tags" call instead, because it accepts a more 71 // robust JSON body. 72 // 73 // see: https://bugzilla.redhat.com/show_bug.cgi?id=2299208 74 if _, err := attributestags.ReplaceAll(ctx, networkClient, "security-groups", masterGroup.ID, attributestags.ReplaceAllOpts{ 75 Tags: []string{"openshiftClusterID=" + infraID}, 76 }).Extract(); err != nil { 77 return fmt.Errorf("failed to tag the Control plane security group: %w", err) 78 } 79 80 workerGroup, err = groups.Create(ctx, networkClient, groups.CreateOpts{ 81 Name: infraID + "-worker", 82 Description: description, 83 }).Extract() 84 if err != nil { 85 return fmt.Errorf("failed to create the Compute security group: %w", err) 86 } 87 88 // See comment above 89 if _, err := attributestags.ReplaceAll(ctx, networkClient, "security-groups", workerGroup.ID, attributestags.ReplaceAllOpts{ 90 Tags: []string{"openshiftClusterID=" + infraID}, 91 }).Extract(); err != nil { 92 return fmt.Errorf("failed to tag the Compute security group: %w", err) 93 } 94 } 95 96 logrus.Debugf("Creating the security group rules") 97 var ( 98 machineV4CIDRs = make([]string, 0, len(installConfig.Config.Networking.MachineNetwork)) 99 machineV6CIDRs = make([]string, 0, len(installConfig.Config.Networking.MachineNetwork)) 100 ) 101 for _, network := range installConfig.Config.Networking.MachineNetwork { 102 if network.CIDR.IPNet.IP.To4() != nil { 103 machineV4CIDRs = append(machineV4CIDRs, network.CIDR.IPNet.String()) 104 } else { 105 machineV6CIDRs = append(machineV6CIDRs, network.CIDR.IPNet.String()) 106 } 107 } 108 109 type service struct { 110 protocol 111 minPort int 112 maxPort int 113 } 114 115 var ( 116 serviceAPI = service{tcp | udp, 6443, 6443} 117 serviceDNS = service{tcp | udp, 53, 53} 118 serviceESP = service{protocol: esp} 119 serviceETCD = service{tcp, 2379, 2380} 120 serviceGeneve = service{udp, 6081, 6081} 121 serviceHTTP = service{tcp, 80, 80} 122 serviceHTTPS = service{tcp, 443, 443} 123 serviceICMP = service{protocol: icmp} 124 serviceIKE = service{udp, 500, 500} 125 serviceIKENat = service{udp, 4500, 4500} 126 serviceInternal = service{tcp | udp, 9000, 9999} 127 serviceKCM = service{tcp, 10257, 10257} 128 serviceKubeScheduler = service{tcp, 10259, 10259} 129 serviceKubelet = service{tcp, 10250, 10250} 130 serviceMCS = service{tcp, 22623, 22623} 131 serviceNodeport = service{tcp | udp, 30000, 32767} 132 serviceOVNDB = service{tcp, 6641, 6642} 133 serviceRouter = service{tcp, 1936, 1936} 134 serviceSSH = service{tcp, 22, 22} 135 serviceVRRP = service{protocol: vrrp} 136 serviceVXLAN = service{udp, 4789, 4789} 137 ) 138 139 addRules := func(ctx context.Context, ch chan<- rules.CreateOpts, securityGroupID string, s service, ipVersion rules.RuleEtherType, remoteCIDRs []string) { 140 for _, proto := range s.Protocols() { 141 for _, remoteCIDR := range remoteCIDRs { 142 select { 143 case ch <- rules.CreateOpts{ 144 Direction: rules.DirIngress, 145 Description: description, 146 EtherType: ipVersion, 147 SecGroupID: securityGroupID, 148 PortRangeMax: s.maxPort, 149 PortRangeMin: s.minPort, 150 Protocol: proto, 151 RemoteIPPrefix: remoteCIDR, 152 }: 153 case <-ctx.Done(): 154 return 155 } 156 } 157 } 158 } 159 160 ctx, cancel := context.WithCancel(ctx) 161 defer cancel() 162 163 // TODO(mandre) Explicitly enable egress 164 165 r := make(chan rules.CreateOpts) 166 go func() { 167 defer close(r) 168 169 // In this loop: security groups with a catch-all remote IP 170 for ipVersion, anyIP := range map[rules.RuleEtherType][]string{ 171 rules.EtherType4: {"0.0.0.0/0"}, 172 rules.EtherType6: func() []string { 173 switch len(machineV6CIDRs) { 174 case 0: 175 return []string{} 176 default: 177 return []string{"::/0"} 178 } 179 }(), 180 } { 181 addRules(ctx, r, masterGroup.ID, serviceAPI, ipVersion, anyIP) 182 addRules(ctx, r, masterGroup.ID, serviceICMP, ipVersion, anyIP) 183 addRules(ctx, r, workerGroup.ID, serviceHTTP, ipVersion, anyIP) 184 addRules(ctx, r, workerGroup.ID, serviceHTTPS, ipVersion, anyIP) 185 addRules(ctx, r, workerGroup.ID, serviceICMP, ipVersion, anyIP) 186 if mastersSchedulable { 187 addRules(ctx, r, masterGroup.ID, serviceHTTP, ipVersion, anyIP) 188 addRules(ctx, r, masterGroup.ID, serviceHTTPS, ipVersion, anyIP) 189 } 190 } 191 192 // In this loop: security groups with the machine CIDR as remote IPs 193 for ipVersion, CIDRs := range map[rules.RuleEtherType][]string{ 194 rules.EtherType4: machineV4CIDRs, 195 rules.EtherType6: machineV6CIDRs, 196 } { 197 // In this loop: rules that equally apply to masters and workers 198 for _, groupID := range [...]string{masterGroup.ID, workerGroup.ID} { 199 addRules(ctx, r, groupID, serviceESP, ipVersion, CIDRs) 200 addRules(ctx, r, groupID, serviceGeneve, ipVersion, CIDRs) 201 addRules(ctx, r, groupID, serviceIKE, ipVersion, CIDRs) 202 addRules(ctx, r, groupID, serviceInternal, ipVersion, CIDRs) 203 addRules(ctx, r, groupID, serviceKubelet, ipVersion, CIDRs) 204 addRules(ctx, r, groupID, serviceNodeport, ipVersion, CIDRs) 205 addRules(ctx, r, groupID, serviceSSH, ipVersion, CIDRs) 206 addRules(ctx, r, groupID, serviceVRRP, ipVersion, CIDRs) 207 addRules(ctx, r, groupID, serviceVXLAN, ipVersion, CIDRs) 208 } 209 210 addRules(ctx, r, masterGroup.ID, serviceDNS, ipVersion, CIDRs) 211 addRules(ctx, r, masterGroup.ID, serviceETCD, ipVersion, CIDRs) 212 addRules(ctx, r, masterGroup.ID, serviceKCM, ipVersion, CIDRs) 213 addRules(ctx, r, masterGroup.ID, serviceKubeScheduler, ipVersion, CIDRs) 214 addRules(ctx, r, masterGroup.ID, serviceMCS, ipVersion, CIDRs) 215 addRules(ctx, r, masterGroup.ID, serviceOVNDB, ipVersion, CIDRs) 216 addRules(ctx, r, workerGroup.ID, serviceRouter, ipVersion, CIDRs) 217 if mastersSchedulable { 218 addRules(ctx, r, masterGroup.ID, serviceRouter, ipVersion, CIDRs) 219 } 220 } 221 222 // IPv4-only rules 223 addRules(ctx, r, masterGroup.ID, serviceIKENat, rules.EtherType4, machineV4CIDRs) 224 addRules(ctx, r, workerGroup.ID, serviceIKENat, rules.EtherType4, machineV4CIDRs) 225 }() 226 227 for ruleCreateOpts := range r { 228 if _, err := rules.Create(ctx, networkClient, ruleCreateOpts).Extract(); err != nil { 229 return fmt.Errorf("failed to create the security group rule on group %q for %s %s on ports %d-%d: %w", ruleCreateOpts.SecGroupID, ruleCreateOpts.EtherType, ruleCreateOpts.Protocol, ruleCreateOpts.PortRangeMin, ruleCreateOpts.PortRangeMax, err) 230 } 231 } 232 return nil 233 }