Allow PrefixList for sshAccess and kubernetesApiAccess

Signed-off-by: Jeroen van Erp <jeroen@hierynomus.com>
This commit is contained in:
Jeroen van Erp 2022-01-16 23:28:56 +01:00
parent 7e645187bc
commit 255a0322c9
No known key found for this signature in database
GPG Key ID: EBE906E1F4ACA3B7
12 changed files with 221 additions and 122 deletions

View File

@ -401,79 +401,54 @@ func (m *MockEC2) AuthorizeSecurityGroupIngress(request *ec2.AuthorizeSecurityGr
m.SecurityGroupRules = make(map[string]*ec2.SecurityGroupRule)
}
newSecurityGroupRule := func(permission *ec2.IpPermission) (string, *ec2.SecurityGroupRule) {
n := len(m.SecurityGroupRules) + 1
id := fmt.Sprintf("sgr-%d", n)
rule := &ec2.SecurityGroupRule{
SecurityGroupRuleId: &id,
GroupId: sg.GroupId,
FromPort: permission.FromPort,
ToPort: permission.ToPort,
IsEgress: aws.Bool(false),
IpProtocol: permission.IpProtocol,
Tags: tagSpecificationsToTags(request.TagSpecifications, ec2.ResourceTypeSecurityGroupRule),
}
if permission.FromPort == nil {
rule.FromPort = aws.Int64(int64(-1))
}
if permission.ToPort == nil {
rule.ToPort = aws.Int64(int64(-1))
}
return id, rule
}
for _, permission := range request.IpPermissions {
for _, iprange := range permission.IpRanges {
n := len(m.SecurityGroupRules) + 1
id := fmt.Sprintf("sgr-%d", n)
rule := &ec2.SecurityGroupRule{
SecurityGroupRuleId: &id,
GroupId: sg.GroupId,
FromPort: permission.FromPort,
ToPort: permission.ToPort,
IsEgress: aws.Bool(false),
CidrIpv4: iprange.CidrIp,
IpProtocol: permission.IpProtocol,
Tags: tagSpecificationsToTags(request.TagSpecifications, ec2.ResourceTypeSecurityGroupRule),
}
if permission.FromPort == nil {
rule.FromPort = aws.Int64(int64(-1))
}
if permission.ToPort == nil {
rule.ToPort = aws.Int64(int64(-1))
}
id, rule := newSecurityGroupRule(permission)
rule.CidrIpv4 = iprange.CidrIp
m.SecurityGroupRules[id] = rule
}
for _, iprange := range permission.Ipv6Ranges {
n := len(m.SecurityGroupRules) + 1
id := fmt.Sprintf("sgr-%d", n)
rule := &ec2.SecurityGroupRule{
SecurityGroupRuleId: &id,
GroupId: sg.GroupId,
FromPort: permission.FromPort,
ToPort: permission.ToPort,
IsEgress: aws.Bool(false),
CidrIpv6: iprange.CidrIpv6,
IpProtocol: permission.IpProtocol,
Tags: tagSpecificationsToTags(request.TagSpecifications, ec2.ResourceTypeSecurityGroupRule),
}
if permission.FromPort == nil {
rule.FromPort = aws.Int64(int64(-1))
}
if permission.ToPort == nil {
rule.ToPort = aws.Int64(int64(-1))
}
id, rule := newSecurityGroupRule(permission)
rule.CidrIpv6 = iprange.CidrIpv6
m.SecurityGroupRules[id] = rule
}
for _, prefixListId := range permission.PrefixListIds {
id, rule := newSecurityGroupRule(permission)
rule.PrefixListId = prefixListId.PrefixListId
m.SecurityGroupRules[id] = rule
}
for _, group := range permission.UserIdGroupPairs {
n := len(m.SecurityGroupRules) + 1
id := fmt.Sprintf("sgr-%d", n)
rule := &ec2.SecurityGroupRule{
SecurityGroupRuleId: &id,
GroupId: sg.GroupId,
FromPort: permission.FromPort,
ToPort: permission.ToPort,
IsEgress: aws.Bool(false),
ReferencedGroupInfo: &ec2.ReferencedSecurityGroup{
GroupId: group.GroupId,
},
IpProtocol: permission.IpProtocol,
Tags: tagSpecificationsToTags(request.TagSpecifications, ec2.ResourceTypeSecurityGroupRule),
id, rule := newSecurityGroupRule(permission)
rule.ReferencedGroupInfo = &ec2.ReferencedSecurityGroup{
GroupId: group.GroupId,
}
if permission.FromPort == nil {
rule.FromPort = aws.Int64(int64(-1))
}
if permission.ToPort == nil {
rule.ToPort = aws.Int64(int64(-1))
}
m.SecurityGroupRules[id] = rule
}
}

View File

@ -257,6 +257,10 @@ spec:
- 12.34.56.78/32
```
{{ kops_feature_table(kops_added_default='1.23') }}
In AWS, instead of listing all CIDRs, it is possible to specify a pre-existing [AWS Prefix List](https://docs.aws.amazon.com/vpc/latest/userguide/managed-prefix-lists.html) ID.
## kubernetesApiAccess
This array configures the CIDRs that are able to access the kubernetes API. On AWS this is manifested as inbound security group rules on the ELB or master security groups.
@ -269,6 +273,10 @@ spec:
- 12.34.56.78/32
```
{{ kops_feature_table(kops_added_default='1.23') }}
In AWS, instead of listing all CIDRs, it is possible to specify a pre-existing [AWS Prefix List](https://docs.aws.amazon.com/vpc/latest/userguide/managed-prefix-lists.html) ID.
## cluster.spec Subnet Keys
### id

View File

@ -85,17 +85,35 @@ func validateClusterSpec(spec *kops.ClusterSpec, c *kops.Cluster, fieldPath *fie
// SSHAccess
for i, cidr := range spec.SSHAccess {
allErrs = append(allErrs, validateCIDR(cidr, fieldPath.Child("sshAccess").Index(i))...)
if strings.HasPrefix(cidr, "pl-") {
if kops.CloudProviderID(spec.CloudProvider) != kops.CloudProviderAWS {
allErrs = append(allErrs, field.Invalid(fieldPath.Child("sshAccess").Index(i), cidr, "Prefix List ID only supported for AWS"))
}
} else {
allErrs = append(allErrs, validateCIDR(cidr, fieldPath.Child("sshAccess").Index(i))...)
}
}
// KubernetesAPIAccess
for i, cidr := range spec.KubernetesAPIAccess {
allErrs = append(allErrs, validateCIDR(cidr, fieldPath.Child("kubernetesAPIAccess").Index(i))...)
if strings.HasPrefix(cidr, "pl-") {
if kops.CloudProviderID(spec.CloudProvider) != kops.CloudProviderAWS {
allErrs = append(allErrs, field.Invalid(fieldPath.Child("kubernetesAPIAccess").Index(i), cidr, "Prefix List ID only supported for AWS"))
}
} else {
allErrs = append(allErrs, validateCIDR(cidr, fieldPath.Child("kubernetesAPIAccess").Index(i))...)
}
}
// NodePortAccess
for i, cidr := range spec.NodePortAccess {
allErrs = append(allErrs, validateCIDR(cidr, fieldPath.Child("nodePortAccess").Index(i))...)
if strings.HasPrefix(cidr, "pl-") {
if kops.CloudProviderID(spec.CloudProvider) != kops.CloudProviderAWS {
allErrs = append(allErrs, field.Invalid(fieldPath.Child("nodePortAccess").Index(i), cidr, "Prefix List ID only supported for AWS"))
}
} else {
allErrs = append(allErrs, validateCIDR(cidr, fieldPath.Child("nodePortAccess").Index(i))...)
}
}
// AdditionalNetworkCIDRs

View File

@ -19,6 +19,7 @@ package awsmodel
import (
"fmt"
"sort"
"strings"
"time"
"k8s.io/apimachinery/pkg/util/sets"
@ -368,11 +369,7 @@ func (b *APILoadBalancerBuilder) Build(c *fi.ModelBuilderContext) error {
SecurityGroup: lbSG,
ToPort: fi.Int64(443),
}
if utils.IsIPv6CIDR(cidr) {
t.IPv6CIDR = fi.String(cidr)
} else {
t.CIDR = fi.String(cidr)
}
t.SetCidrOrPrefix(cidr)
AddDirectionalGroupRule(c, t)
}
@ -418,35 +415,36 @@ func (b *APILoadBalancerBuilder) Build(c *fi.ModelBuilderContext) error {
SecurityGroup: masterGroup.Task,
ToPort: fi.Int64(443),
}
if utils.IsIPv6CIDR(cidr) {
t.IPv6CIDR = fi.String(cidr)
} else {
t.CIDR = fi.String(cidr)
}
t.SetCidrOrPrefix(cidr)
AddDirectionalGroupRule(c, t)
}
// Allow ICMP traffic required for PMTU discovery
if utils.IsIPv6CIDR(cidr) {
c.AddTask(&awstasks.SecurityGroupRule{
if strings.HasPrefix(cidr, "pl-") {
// In case of a prefix list we do not add a rule for ICMP traffic for PMTU discovery.
// This would require calling out to AWS to check whether the prefix list is IPv4 or IPv6.
} else if utils.IsIPv6CIDR(cidr) {
// Allow ICMP traffic required for PMTU discovery
t := &awstasks.SecurityGroupRule{
Name: fi.String("icmpv6-pmtu-api-elb-" + cidr),
Lifecycle: b.SecurityLifecycle,
IPv6CIDR: fi.String(cidr),
FromPort: fi.Int64(-1),
Protocol: fi.String("icmpv6"),
SecurityGroup: masterGroup.Task,
ToPort: fi.Int64(-1),
})
}
t.SetCidrOrPrefix(cidr)
c.AddTask(t)
} else {
c.AddTask(&awstasks.SecurityGroupRule{
t := &awstasks.SecurityGroupRule{
Name: fi.String("icmp-pmtu-api-elb-" + cidr),
Lifecycle: b.SecurityLifecycle,
CIDR: fi.String(cidr),
FromPort: fi.Int64(3),
Protocol: fi.String("icmp"),
SecurityGroup: masterGroup.Task,
ToPort: fi.Int64(4),
})
}
t.SetCidrOrPrefix(cidr)
c.AddTask(t)
}
if b.Cluster.Spec.API != nil && b.Cluster.Spec.API.LoadBalancer != nil && b.Cluster.Spec.API.LoadBalancer.SSLCertificate != "" {
@ -459,11 +457,7 @@ func (b *APILoadBalancerBuilder) Build(c *fi.ModelBuilderContext) error {
SecurityGroup: masterGroup.Task,
ToPort: fi.Int64(8443),
}
if utils.IsIPv6CIDR(cidr) {
t.IPv6CIDR = fi.String(cidr)
} else {
t.CIDR = fi.String(cidr)
}
t.SetCidrOrPrefix(cidr)
c.AddTask(t)
}
}

View File

@ -26,7 +26,6 @@ import (
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awstasks"
"k8s.io/kops/upup/pkg/fi/utils"
)
const (
@ -219,11 +218,7 @@ func (b *BastionModelBuilder) Build(c *fi.ModelBuilderContext) error {
FromPort: fi.Int64(22),
ToPort: fi.Int64(22),
}
if utils.IsIPv6CIDR(sshAccess) {
t.IPv6CIDR = fi.String(sshAccess)
} else {
t.CIDR = fi.String(sshAccess)
}
t.SetCidrOrPrefix(sshAccess)
AddDirectionalGroupRule(c, t)
}

View File

@ -23,7 +23,6 @@ import (
"k8s.io/kops/pkg/apis/kops"
"k8s.io/kops/upup/pkg/fi"
"k8s.io/kops/upup/pkg/fi/cloudup/awstasks"
"k8s.io/kops/upup/pkg/fi/utils"
)
// ExternalAccessModelBuilder configures security group rules for external access
@ -71,11 +70,7 @@ func (b *ExternalAccessModelBuilder) Build(c *fi.ModelBuilderContext) error {
FromPort: fi.Int64(22),
ToPort: fi.Int64(22),
}
if utils.IsIPv6CIDR(sshAccess) {
t.IPv6CIDR = fi.String(sshAccess)
} else {
t.CIDR = fi.String(sshAccess)
}
t.SetCidrOrPrefix(sshAccess)
AddDirectionalGroupRule(c, t)
}
@ -89,11 +84,7 @@ func (b *ExternalAccessModelBuilder) Build(c *fi.ModelBuilderContext) error {
FromPort: fi.Int64(22),
ToPort: fi.Int64(22),
}
if utils.IsIPv6CIDR(sshAccess) {
t.IPv6CIDR = fi.String(sshAccess)
} else {
t.CIDR = fi.String(sshAccess)
}
t.SetCidrOrPrefix(sshAccess)
AddDirectionalGroupRule(c, t)
}
}
@ -116,11 +107,7 @@ func (b *ExternalAccessModelBuilder) Build(c *fi.ModelBuilderContext) error {
FromPort: fi.Int64(int64(nodePortRange.Base)),
ToPort: fi.Int64(int64(nodePortRange.Base + nodePortRange.Size - 1)),
}
if utils.IsIPv6CIDR(nodePortAccess) {
t.IPv6CIDR = fi.String(nodePortAccess)
} else {
t.CIDR = fi.String(nodePortAccess)
}
t.SetCidrOrPrefix(nodePortAccess)
c.AddTask(t)
}
{
@ -132,11 +119,7 @@ func (b *ExternalAccessModelBuilder) Build(c *fi.ModelBuilderContext) error {
FromPort: fi.Int64(int64(nodePortRange.Base)),
ToPort: fi.Int64(int64(nodePortRange.Base + nodePortRange.Size - 1)),
}
if utils.IsIPv6CIDR(nodePortAccess) {
t.IPv6CIDR = fi.String(nodePortAccess)
} else {
t.CIDR = fi.String(nodePortAccess)
}
t.SetCidrOrPrefix(nodePortAccess)
c.AddTask(t)
}
}
@ -159,11 +142,7 @@ func (b *ExternalAccessModelBuilder) Build(c *fi.ModelBuilderContext) error {
FromPort: fi.Int64(443),
ToPort: fi.Int64(443),
}
if utils.IsIPv6CIDR(apiAccess) {
t.IPv6CIDR = fi.String(apiAccess)
} else {
t.CIDR = fi.String(apiAccess)
}
t.SetCidrOrPrefix(apiAccess)
AddDirectionalGroupRule(c, t)
}
}

View File

@ -721,6 +721,42 @@
"CidrIp": "0.0.0.0/0"
}
},
"AWSEC2SecurityGroupIngressfrom00000ingresstcp22to22masterscomplexexamplecom": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"GroupId": {
"Ref": "AWSEC2SecurityGroupmasterscomplexexamplecom"
},
"FromPort": 22,
"ToPort": 22,
"IpProtocol": "tcp",
"SourcePrefixListId": "pl-66666666"
}
},
"AWSEC2SecurityGroupIngressfrom00000ingresstcp22to22nodescomplexexamplecom": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"GroupId": {
"Ref": "AWSEC2SecurityGroupnodescomplexexamplecom"
},
"FromPort": 22,
"ToPort": 22,
"IpProtocol": "tcp",
"SourcePrefixListId": "pl-66666666"
}
},
"AWSEC2SecurityGroupIngressfrom00000ingresstcp443to443masterscomplexexamplecom": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"GroupId": {
"Ref": "AWSEC2SecurityGroupmasterscomplexexamplecom"
},
"FromPort": 443,
"ToPort": 443,
"IpProtocol": "tcp",
"SourcePrefixListId": "pl-44444444"
}
},
"AWSEC2SecurityGroupIngressfrom111024ingresstcp443to443masterscomplexexamplecom": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
@ -963,6 +999,18 @@
"CidrIp": "1.1.1.0/24"
}
},
"AWSEC2SecurityGroupIngresstcpapipl44444444": {
"Type": "AWS::EC2::SecurityGroupIngress",
"Properties": {
"GroupId": {
"Ref": "AWSEC2SecurityGroupmasterscomplexexamplecom"
},
"FromPort": 8443,
"ToPort": 8443,
"IpProtocol": "tcp",
"SourcePrefixListId": "pl-44444444"
}
},
"AWSEC2SecurityGroupapielbcomplexexamplecom": {
"Type": "AWS::EC2::SecurityGroup",
"Properties": {

View File

@ -163,6 +163,7 @@ spec:
podManifestPath: /etc/kubernetes/manifests
kubernetesApiAccess:
- 1.1.1.0/24
- pl-44444444
kubernetesVersion: 1.21.0
masterInternalName: api.internal.complex.example.com
masterKubelet:
@ -192,6 +193,7 @@ spec:
serviceClusterIPRange: 100.64.0.0/13
sshAccess:
- 1.1.1.1/32
- pl-66666666
sshKeyName: ""
subnets:
- cidr: 172.20.32.0/19

View File

@ -21,6 +21,7 @@ spec:
bucket: access-log-example
kubernetesApiAccess:
- 1.1.1.0/24
- pl-44444444
channel: stable
cloudProvider: aws
cloudLabels:
@ -66,6 +67,7 @@ spec:
- 990F4193972F2BECF12DDEDA5237F9C952F20D9E
sshAccess:
- 1.1.1.1/32
- pl-66666666
sshKeyName: ""
target:
terraform:

View File

@ -21,6 +21,7 @@ spec:
bucket: access-log-example
kubernetesApiAccess:
- 1.1.1.0/24
- pl-44444444
channel: stable
cloudProvider: aws
cloudLabels:
@ -66,6 +67,8 @@ spec:
- 990F4193972F2BECF12DDEDA5237F9C952F20D9E
sshAccess:
- 1.1.1.1/32
- pl-66666666
sshKeyName: ""
target:
terraform:

View File

@ -857,6 +857,33 @@ resource "aws_security_group" "nodes-complex-example-com" {
vpc_id = aws_vpc.complex-example-com.id
}
resource "aws_security_group_rule" "from-0-0-0-0--0-ingress-tcp-22to22-masters-complex-example-com" {
from_port = 22
prefix_list_ids = ["pl-66666666"]
protocol = "tcp"
security_group_id = aws_security_group.masters-complex-example-com.id
to_port = 22
type = "ingress"
}
resource "aws_security_group_rule" "from-0-0-0-0--0-ingress-tcp-22to22-nodes-complex-example-com" {
from_port = 22
prefix_list_ids = ["pl-66666666"]
protocol = "tcp"
security_group_id = aws_security_group.nodes-complex-example-com.id
to_port = 22
type = "ingress"
}
resource "aws_security_group_rule" "from-0-0-0-0--0-ingress-tcp-443to443-masters-complex-example-com" {
from_port = 443
prefix_list_ids = ["pl-44444444"]
protocol = "tcp"
security_group_id = aws_security_group.masters-complex-example-com.id
to_port = 443
type = "ingress"
}
resource "aws_security_group_rule" "from-1-1-1-0--24-ingress-tcp-443to443-masters-complex-example-com" {
cidr_blocks = ["1.1.1.0/24"]
from_port = 443
@ -1064,6 +1091,15 @@ resource "aws_security_group_rule" "tcp-api-1-1-1-0--24" {
type = "ingress"
}
resource "aws_security_group_rule" "tcp-api-pl-44444444" {
from_port = 8443
prefix_list_ids = ["pl-44444444"]
protocol = "tcp"
security_group_id = aws_security_group.masters-complex-example-com.id
to_port = 8443
type = "ingress"
}
resource "aws_subnet" "us-east-1a-private-complex-example-com" {
availability_zone = "us-test-1a"
cidr_block = "172.20.64.0/19"

View File

@ -29,6 +29,7 @@ import (
"k8s.io/kops/upup/pkg/fi/cloudup/cloudformation"
"k8s.io/kops/upup/pkg/fi/cloudup/terraform"
"k8s.io/kops/upup/pkg/fi/cloudup/terraformWriter"
"k8s.io/kops/upup/pkg/fi/utils"
)
// +kops:fitask
@ -40,6 +41,7 @@ type SecurityGroupRule struct {
SecurityGroup *SecurityGroup
CIDR *string
IPv6CIDR *string
PrefixList *string
Protocol *string
// FromPort is the lower-bound (inclusive) of the port-range
@ -121,6 +123,9 @@ func (e *SecurityGroupRule) Find(c *fi.Context) (*SecurityGroupRule, error) {
if e.IPv6CIDR != nil {
actual.IPv6CIDR = e.IPv6CIDR
}
if e.PrefixList != nil {
actual.PrefixList = e.PrefixList
}
if e.SourceGroup != nil {
actual.SourceGroup = &SecurityGroup{ID: e.SourceGroup.ID}
}
@ -135,6 +140,16 @@ func (e *SecurityGroupRule) Find(c *fi.Context) (*SecurityGroupRule, error) {
return nil, nil
}
func (e *SecurityGroupRule) SetCidrOrPrefix(cidr string) {
if strings.HasPrefix(cidr, "pl-") {
e.PrefixList = &cidr
} else if utils.IsIPv6CIDR(cidr) {
e.IPv6CIDR = &cidr
} else {
e.CIDR = &cidr
}
}
func (e *SecurityGroupRule) matches(rule *ec2.SecurityGroupRule) bool {
matchFromPort := int64(-1)
if e.FromPort != nil {
@ -168,6 +183,10 @@ func (e *SecurityGroupRule) matches(rule *ec2.SecurityGroupRule) bool {
return false
}
if fi.StringValue(e.PrefixList) != fi.StringValue(rule.PrefixListId) {
return false
}
if e.SourceGroup != nil || rule.ReferencedGroupInfo != nil {
if e.SourceGroup == nil || rule.ReferencedGroupInfo == nil {
return false
@ -191,6 +210,9 @@ func (_ *SecurityGroupRule) CheckChanges(a, e, changes *SecurityGroupRule) error
if e.CIDR != nil && e.IPv6CIDR != nil {
return field.Forbidden(field.NewPath("CIDR/IPv6CIDR"), "Cannot set more than 1 CIDR or IPv6CIDR")
}
if e.PrefixList != nil && (e.CIDR != nil || e.IPv6CIDR != nil) {
return field.Forbidden(field.NewPath("PrefixList"), "Cannot set PrefixList when CIDR or IPv6CIDR is set")
}
}
if e.FromPort != nil && e.Protocol == nil {
@ -231,6 +253,10 @@ func (e *SecurityGroupRule) Description() string {
description = append(description, fmt.Sprintf("ipv6cidr=%s", *e.IPv6CIDR))
}
if e.PrefixList != nil {
description = append(description, fmt.Sprintf("prefixList=%s", *e.PrefixList))
}
return strings.Join(description, " ")
}
@ -265,6 +291,11 @@ func (_ *SecurityGroupRule) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Secu
ipPermission.IpRanges = []*ec2.IpRange{
{CidrIp: CIDR},
}
} else if e.PrefixList != nil {
PrefixList := e.PrefixList
ipPermission.PrefixListIds = []*ec2.PrefixListId{
{PrefixListId: PrefixList},
}
} else {
ipPermission.IpRanges = []*ec2.IpRange{
{CidrIp: aws.String("0.0.0.0/0")},
@ -320,6 +351,7 @@ type terraformSecurityGroupIngress struct {
Protocol *string `cty:"protocol"`
CIDRBlocks []string `cty:"cidr_blocks"`
IPv6CIDRBlocks []string `cty:"ipv6_cidr_blocks"`
PrefixListIDs []string `cty:"prefix_list_ids"`
}
func (_ *SecurityGroupRule) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *SecurityGroupRule) error {
@ -359,6 +391,9 @@ func (_ *SecurityGroupRule) RenderTerraform(t *terraform.TerraformTarget, a, e,
if e.IPv6CIDR != nil {
tf.IPv6CIDRBlocks = append(tf.IPv6CIDRBlocks, *e.IPv6CIDR)
}
if e.PrefixList != nil {
tf.PrefixListIDs = append(tf.PrefixListIDs, *e.PrefixList)
}
return t.RenderResource("aws_security_group_rule", *e.Name, tf)
}
@ -370,9 +405,10 @@ type cloudformationSecurityGroupIngress struct {
FromPort *int64 `json:"FromPort,omitempty"`
ToPort *int64 `json:"ToPort,omitempty"`
Protocol *string `json:"IpProtocol,omitempty"`
CidrIp *string `json:"CidrIp,omitempty"`
CidrIpv6 *string `json:"CidrIpv6,omitempty"`
Protocol *string `json:"IpProtocol,omitempty"`
CidrIp *string `json:"CidrIp,omitempty"`
CidrIpv6 *string `json:"CidrIpv6,omitempty"`
SourcePrefixListId *string `json:"SourcePrefixListId,omitempty"`
}
func (_ *SecurityGroupRule) RenderCloudformation(t *cloudformation.CloudformationTarget, a, e, changes *SecurityGroupRule) error {
@ -413,6 +449,9 @@ func (_ *SecurityGroupRule) RenderCloudformation(t *cloudformation.Cloudformatio
if e.IPv6CIDR != nil {
tf.CidrIpv6 = e.IPv6CIDR
}
if e.PrefixList != nil {
tf.SourcePrefixListId = e.PrefixList
}
return t.RenderResource(cfType, *e.Name, tf)
}