Merge pull request #13113 from hierynomus/issue-12925

Allow PrefixList for sshAccess and kubernetesApiAccess
This commit is contained in:
Kubernetes Prow Robot 2022-02-15 07:20:03 -08:00 committed by GitHub
commit bffc60202c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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

@ -166,6 +166,7 @@ spec:
shutdownGracePeriodCriticalPods: 10s
kubernetesApiAccess:
- 1.1.1.0/24
- pl-44444444
kubernetesVersion: 1.21.0
masterInternalName: api.internal.complex.example.com
masterKubelet:
@ -198,6 +199,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)
}