mirror of https://github.com/kubernetes/kops.git
Merge pull request #15570 from hakman/azure_network_security
azure: Add support for network security groups
This commit is contained in:
commit
49a6ed4188
|
|
@ -17,8 +17,12 @@ limitations under the License.
|
|||
package azuremodel
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/azuretasks"
|
||||
"k8s.io/utils/net"
|
||||
)
|
||||
|
||||
// NetworkModelBuilder configures a Virtual Network and subnets.
|
||||
|
|
@ -41,14 +45,134 @@ func (b *NetworkModelBuilder) Build(c *fi.CloudupModelBuilderContext) error {
|
|||
}
|
||||
c.AddTask(networkTask)
|
||||
|
||||
nsgTask := &azuretasks.NetworkSecurityGroup{
|
||||
Name: fi.PtrTo(b.NameForVirtualNetwork()),
|
||||
Lifecycle: b.Lifecycle,
|
||||
ResourceGroup: b.LinkToResourceGroup(),
|
||||
Tags: map[string]*string{},
|
||||
}
|
||||
var sshAccessIPv4, sshAccessIPv6 []string
|
||||
for _, cidr := range b.Cluster.Spec.SSHAccess {
|
||||
switch net.IPFamilyOfCIDRString(cidr) {
|
||||
case net.IPv4:
|
||||
sshAccessIPv4 = append(sshAccessIPv4, cidr)
|
||||
case net.IPv6:
|
||||
sshAccessIPv6 = append(sshAccessIPv6, cidr)
|
||||
default:
|
||||
return fmt.Errorf("unknown IP family for CIDR: %q", cidr)
|
||||
}
|
||||
}
|
||||
if len(sshAccessIPv4) > 0 {
|
||||
nsgTask.SecurityRules = append(nsgTask.SecurityRules, &azuretasks.NetworkSecurityRule{
|
||||
Name: fi.PtrTo("AllowSSH"),
|
||||
Priority: fi.PtrTo[int32](100),
|
||||
Access: network.SecurityRuleAccessAllow,
|
||||
Direction: network.SecurityRuleDirectionInbound,
|
||||
Protocol: network.SecurityRuleProtocolTCP,
|
||||
SourceAddressPrefixes: &sshAccessIPv4,
|
||||
SourcePortRange: fi.PtrTo("*"),
|
||||
DestinationAddressPrefix: fi.PtrTo("*"),
|
||||
DestinationPortRange: fi.PtrTo("22"),
|
||||
})
|
||||
}
|
||||
if len(sshAccessIPv6) > 0 {
|
||||
nsgTask.SecurityRules = append(nsgTask.SecurityRules, &azuretasks.NetworkSecurityRule{
|
||||
Name: fi.PtrTo("AllowSSH_v6"),
|
||||
Priority: fi.PtrTo[int32](101),
|
||||
Access: network.SecurityRuleAccessAllow,
|
||||
Direction: network.SecurityRuleDirectionInbound,
|
||||
Protocol: network.SecurityRuleProtocolTCP,
|
||||
SourceAddressPrefixes: &sshAccessIPv6,
|
||||
SourcePortRange: fi.PtrTo("*"),
|
||||
DestinationAddressPrefix: fi.PtrTo("*"),
|
||||
DestinationPortRange: fi.PtrTo("22"),
|
||||
})
|
||||
}
|
||||
var k8sAccessIPv4, k8sAccessIPv6 []string
|
||||
for _, cidr := range b.Cluster.Spec.API.Access {
|
||||
switch net.IPFamilyOfCIDRString(cidr) {
|
||||
case net.IPv4:
|
||||
k8sAccessIPv4 = append(k8sAccessIPv4, cidr)
|
||||
case net.IPv6:
|
||||
k8sAccessIPv6 = append(k8sAccessIPv6, cidr)
|
||||
default:
|
||||
return fmt.Errorf("unknown IP family for CIDR: %q", cidr)
|
||||
}
|
||||
}
|
||||
if len(k8sAccessIPv4) > 0 {
|
||||
nsgTask.SecurityRules = append(nsgTask.SecurityRules, &azuretasks.NetworkSecurityRule{
|
||||
Name: fi.PtrTo("AllowKubernetesAPI"),
|
||||
Priority: fi.PtrTo[int32](200),
|
||||
Access: network.SecurityRuleAccessAllow,
|
||||
Direction: network.SecurityRuleDirectionInbound,
|
||||
Protocol: network.SecurityRuleProtocolTCP,
|
||||
SourceAddressPrefixes: &k8sAccessIPv4,
|
||||
SourcePortRange: fi.PtrTo("*"),
|
||||
DestinationAddressPrefix: fi.PtrTo("*"),
|
||||
DestinationPortRange: fi.PtrTo("443"),
|
||||
})
|
||||
}
|
||||
if len(k8sAccessIPv6) > 0 {
|
||||
nsgTask.SecurityRules = append(nsgTask.SecurityRules, &azuretasks.NetworkSecurityRule{
|
||||
Name: fi.PtrTo("AllowKubernetesAPI_v6"),
|
||||
Priority: fi.PtrTo[int32](201),
|
||||
Access: network.SecurityRuleAccessAllow,
|
||||
Direction: network.SecurityRuleDirectionInbound,
|
||||
Protocol: network.SecurityRuleProtocolTCP,
|
||||
SourceAddressPrefixes: &k8sAccessIPv6,
|
||||
SourcePortRange: fi.PtrTo("*"),
|
||||
DestinationAddressPrefix: fi.PtrTo("*"),
|
||||
DestinationPortRange: fi.PtrTo("443"),
|
||||
})
|
||||
}
|
||||
var nodePortAccessIPv4, nodePortAccessIPv6 []string
|
||||
for _, cidr := range b.Cluster.Spec.NodePortAccess {
|
||||
switch net.IPFamilyOfCIDRString(cidr) {
|
||||
case net.IPv4:
|
||||
nodePortAccessIPv4 = append(nodePortAccessIPv4, cidr)
|
||||
case net.IPv6:
|
||||
nodePortAccessIPv6 = append(nodePortAccessIPv6, cidr)
|
||||
default:
|
||||
return fmt.Errorf("unknown IP family for CIDR: %q", cidr)
|
||||
}
|
||||
}
|
||||
if len(nodePortAccessIPv4) > 0 {
|
||||
nsgTask.SecurityRules = append(nsgTask.SecurityRules, &azuretasks.NetworkSecurityRule{
|
||||
Name: fi.PtrTo("AllowNodePort"),
|
||||
Priority: fi.PtrTo[int32](300),
|
||||
Access: network.SecurityRuleAccessAllow,
|
||||
Direction: network.SecurityRuleDirectionInbound,
|
||||
Protocol: network.SecurityRuleProtocolTCP,
|
||||
SourceAddressPrefixes: &nodePortAccessIPv4,
|
||||
SourcePortRange: fi.PtrTo("*"),
|
||||
DestinationAddressPrefix: fi.PtrTo("*"),
|
||||
DestinationPortRange: fi.PtrTo("443"),
|
||||
})
|
||||
}
|
||||
if len(nodePortAccessIPv6) > 0 {
|
||||
nsgTask.SecurityRules = append(nsgTask.SecurityRules, &azuretasks.NetworkSecurityRule{
|
||||
Name: fi.PtrTo("AllowNodePort_v6"),
|
||||
Priority: fi.PtrTo[int32](301),
|
||||
Access: network.SecurityRuleAccessAllow,
|
||||
Direction: network.SecurityRuleDirectionInbound,
|
||||
Protocol: network.SecurityRuleProtocolTCP,
|
||||
SourceAddressPrefixes: &nodePortAccessIPv6,
|
||||
SourcePortRange: fi.PtrTo("*"),
|
||||
DestinationAddressPrefix: fi.PtrTo("*"),
|
||||
DestinationPortRange: fi.PtrTo("443"),
|
||||
})
|
||||
}
|
||||
c.AddTask(nsgTask)
|
||||
|
||||
for _, subnetSpec := range b.Cluster.Spec.Networking.Subnets {
|
||||
subnetTask := &azuretasks.Subnet{
|
||||
Name: fi.PtrTo(subnetSpec.Name),
|
||||
Lifecycle: b.Lifecycle,
|
||||
ResourceGroup: b.LinkToResourceGroup(),
|
||||
VirtualNetwork: b.LinkToVirtualNetwork(),
|
||||
CIDR: fi.PtrTo(subnetSpec.CIDR),
|
||||
Shared: fi.PtrTo(b.Cluster.SharedVPC()),
|
||||
Name: fi.PtrTo(subnetSpec.Name),
|
||||
Lifecycle: b.Lifecycle,
|
||||
ResourceGroup: b.LinkToResourceGroup(),
|
||||
VirtualNetwork: b.LinkToVirtualNetwork(),
|
||||
NetworkSecurityGroup: nsgTask,
|
||||
CIDR: fi.PtrTo(subnetSpec.CIDR),
|
||||
Shared: fi.PtrTo(b.Cluster.SharedVPC()),
|
||||
}
|
||||
c.AddTask(subnetTask)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,15 +31,16 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
typeResourceGroup = "ResourceGroup"
|
||||
typeVirtualNetwork = "VirtualNetwork"
|
||||
typeSubnet = "Subnet"
|
||||
typeRouteTable = "RouteTable"
|
||||
typeVMScaleSet = "VMScaleSet"
|
||||
typeDisk = "Disk"
|
||||
typeRoleAssignment = "RoleAssignment"
|
||||
typeLoadBalancer = "LoadBalancer"
|
||||
typePublicIPAddress = "PublicIPAddress"
|
||||
typeResourceGroup = "ResourceGroup"
|
||||
typeVirtualNetwork = "VirtualNetwork"
|
||||
typeNetworkSecurityGroup = "NetworkSecurityGroup"
|
||||
typeSubnet = "Subnet"
|
||||
typeRouteTable = "RouteTable"
|
||||
typeVMScaleSet = "VMScaleSet"
|
||||
typeDisk = "Disk"
|
||||
typeRoleAssignment = "RoleAssignment"
|
||||
typeLoadBalancer = "LoadBalancer"
|
||||
typePublicIPAddress = "PublicIPAddress"
|
||||
)
|
||||
|
||||
// ListResourcesAzure lists all resources for the cluster by quering Azure.
|
||||
|
|
@ -85,6 +86,7 @@ func (g *resourceGetter) listAll() ([]*resources.Resource, error) {
|
|||
fns := []func(ctx context.Context) ([]*resources.Resource, error){
|
||||
g.listResourceGroups,
|
||||
g.listVirtualNetworksAndSubnets,
|
||||
g.listNetworkSecurityGroups,
|
||||
g.listRouteTables,
|
||||
g.listVMScaleSetsAndRoleAssignments,
|
||||
g.listDisks,
|
||||
|
|
@ -209,6 +211,39 @@ func (g *resourceGetter) deleteSubnet(vnetName string, r *resources.Resource) er
|
|||
return g.cloud.Subnet().Delete(context.TODO(), g.resourceGroupName(), vnetName, r.Name)
|
||||
}
|
||||
|
||||
func (g *resourceGetter) listNetworkSecurityGroups(ctx context.Context) ([]*resources.Resource, error) {
|
||||
NetworkSecurityGroups, err := g.cloud.NetworkSecurityGroup().List(ctx, g.resourceGroupName())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var rs []*resources.Resource
|
||||
for i := range NetworkSecurityGroups {
|
||||
rs = append(rs, g.toNetworkSecurityGroupResource(&NetworkSecurityGroups[i]))
|
||||
}
|
||||
return rs, nil
|
||||
}
|
||||
|
||||
func (g *resourceGetter) toNetworkSecurityGroupResource(NetworkSecurityGroup *network.SecurityGroup) *resources.Resource {
|
||||
return &resources.Resource{
|
||||
Obj: NetworkSecurityGroup,
|
||||
Type: typeNetworkSecurityGroup,
|
||||
ID: *NetworkSecurityGroup.Name,
|
||||
Name: *NetworkSecurityGroup.Name,
|
||||
Deleter: func(_ fi.Cloud, r *resources.Resource) error {
|
||||
return g.deleteNetworkSecurityGroup(r)
|
||||
},
|
||||
Blocks: []string{
|
||||
toKey(typeResourceGroup, g.resourceGroupName()),
|
||||
},
|
||||
Shared: g.clusterInfo.AzureNetworkShared,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *resourceGetter) deleteNetworkSecurityGroup(r *resources.Resource) error {
|
||||
return g.cloud.NetworkSecurityGroup().Delete(context.TODO(), g.resourceGroupName(), r.Name)
|
||||
}
|
||||
|
||||
func (g *resourceGetter) listRouteTables(ctx context.Context) ([]*resources.Resource, error) {
|
||||
rts, err := g.cloud.RouteTable().List(ctx, g.resourceGroupName())
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ type AzureCloud interface {
|
|||
VirtualNetwork() VirtualNetworksClient
|
||||
Subnet() SubnetsClient
|
||||
RouteTable() RouteTablesClient
|
||||
NetworkSecurityGroup() NetworkSecurityGroupsClient
|
||||
VMScaleSet() VMScaleSetsClient
|
||||
VMScaleSetVM() VMScaleSetVMsClient
|
||||
Disk() DisksClient
|
||||
|
|
@ -59,20 +60,21 @@ type AzureCloud interface {
|
|||
}
|
||||
|
||||
type azureCloudImplementation struct {
|
||||
subscriptionID string
|
||||
location string
|
||||
tags map[string]string
|
||||
resourceGroupsClient ResourceGroupsClient
|
||||
vnetsClient VirtualNetworksClient
|
||||
subnetsClient SubnetsClient
|
||||
routeTablesClient RouteTablesClient
|
||||
vmscaleSetsClient VMScaleSetsClient
|
||||
vmscaleSetVMsClient VMScaleSetVMsClient
|
||||
disksClient DisksClient
|
||||
roleAssignmentsClient RoleAssignmentsClient
|
||||
networkInterfacesClient NetworkInterfacesClient
|
||||
loadBalancersClient LoadBalancersClient
|
||||
publicIPAddressesClient PublicIPAddressesClient
|
||||
subscriptionID string
|
||||
location string
|
||||
tags map[string]string
|
||||
resourceGroupsClient ResourceGroupsClient
|
||||
networkSecurityGroupsClient NetworkSecurityGroupsClient
|
||||
vnetsClient VirtualNetworksClient
|
||||
subnetsClient SubnetsClient
|
||||
routeTablesClient RouteTablesClient
|
||||
vmscaleSetsClient VMScaleSetsClient
|
||||
vmscaleSetVMsClient VMScaleSetVMsClient
|
||||
disksClient DisksClient
|
||||
roleAssignmentsClient RoleAssignmentsClient
|
||||
networkInterfacesClient NetworkInterfacesClient
|
||||
loadBalancersClient LoadBalancersClient
|
||||
publicIPAddressesClient PublicIPAddressesClient
|
||||
}
|
||||
|
||||
var _ fi.Cloud = &azureCloudImplementation{}
|
||||
|
|
@ -85,20 +87,21 @@ func NewAzureCloud(subscriptionID, location string, tags map[string]string) (Azu
|
|||
}
|
||||
|
||||
return &azureCloudImplementation{
|
||||
subscriptionID: subscriptionID,
|
||||
location: location,
|
||||
tags: tags,
|
||||
resourceGroupsClient: newResourceGroupsClientImpl(subscriptionID, authorizer),
|
||||
vnetsClient: newVirtualNetworksClientImpl(subscriptionID, authorizer),
|
||||
subnetsClient: newSubnetsClientImpl(subscriptionID, authorizer),
|
||||
routeTablesClient: newRouteTablesClientImpl(subscriptionID, authorizer),
|
||||
vmscaleSetsClient: newVMScaleSetsClientImpl(subscriptionID, authorizer),
|
||||
vmscaleSetVMsClient: newVMScaleSetVMsClientImpl(subscriptionID, authorizer),
|
||||
disksClient: newDisksClientImpl(subscriptionID, authorizer),
|
||||
roleAssignmentsClient: newRoleAssignmentsClientImpl(subscriptionID, authorizer),
|
||||
networkInterfacesClient: newNetworkInterfacesClientImpl(subscriptionID, authorizer),
|
||||
loadBalancersClient: newLoadBalancersClientImpl(subscriptionID, authorizer),
|
||||
publicIPAddressesClient: newPublicIPAddressesClientImpl(subscriptionID, authorizer),
|
||||
subscriptionID: subscriptionID,
|
||||
location: location,
|
||||
tags: tags,
|
||||
resourceGroupsClient: newResourceGroupsClientImpl(subscriptionID, authorizer),
|
||||
vnetsClient: newVirtualNetworksClientImpl(subscriptionID, authorizer),
|
||||
subnetsClient: newSubnetsClientImpl(subscriptionID, authorizer),
|
||||
routeTablesClient: newRouteTablesClientImpl(subscriptionID, authorizer),
|
||||
networkSecurityGroupsClient: newNetworkSecurityGroupsClientImpl(subscriptionID, authorizer),
|
||||
vmscaleSetsClient: newVMScaleSetsClientImpl(subscriptionID, authorizer),
|
||||
vmscaleSetVMsClient: newVMScaleSetVMsClientImpl(subscriptionID, authorizer),
|
||||
disksClient: newDisksClientImpl(subscriptionID, authorizer),
|
||||
roleAssignmentsClient: newRoleAssignmentsClientImpl(subscriptionID, authorizer),
|
||||
networkInterfacesClient: newNetworkInterfacesClientImpl(subscriptionID, authorizer),
|
||||
loadBalancersClient: newLoadBalancersClientImpl(subscriptionID, authorizer),
|
||||
publicIPAddressesClient: newPublicIPAddressesClientImpl(subscriptionID, authorizer),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
|
@ -286,6 +289,10 @@ func (c *azureCloudImplementation) RouteTable() RouteTablesClient {
|
|||
return c.routeTablesClient
|
||||
}
|
||||
|
||||
func (c *azureCloudImplementation) NetworkSecurityGroup() NetworkSecurityGroupsClient {
|
||||
return c.networkSecurityGroupsClient
|
||||
}
|
||||
|
||||
func (c *azureCloudImplementation) VMScaleSet() VMScaleSetsClient {
|
||||
return c.vmscaleSetsClient
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package azure
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network"
|
||||
"github.com/Azure/go-autorest/autorest"
|
||||
)
|
||||
|
||||
// NetworkSecurityGroupsClient is a client for managing Network Security Groups.
|
||||
type NetworkSecurityGroupsClient interface {
|
||||
CreateOrUpdate(ctx context.Context, resourceGroupName, NetworkSecurityGroupName string, parameters network.SecurityGroup) (*network.SecurityGroup, error)
|
||||
List(ctx context.Context, resourceGroupName string) ([]network.SecurityGroup, error)
|
||||
Delete(ctx context.Context, resourceGroupName, NetworkSecurityGroupName string) error
|
||||
}
|
||||
|
||||
type NetworkSecurityGroupsClientImpl struct {
|
||||
c *network.SecurityGroupsClient
|
||||
}
|
||||
|
||||
var _ NetworkSecurityGroupsClient = &NetworkSecurityGroupsClientImpl{}
|
||||
|
||||
func (c *NetworkSecurityGroupsClientImpl) CreateOrUpdate(ctx context.Context, resourceGroupName, NetworkSecurityGroupName string, parameters network.SecurityGroup) (*network.SecurityGroup, error) {
|
||||
future, err := c.c.CreateOrUpdate(ctx, resourceGroupName, NetworkSecurityGroupName, parameters)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error creating/updating Network Security Group: %w", err)
|
||||
}
|
||||
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil {
|
||||
return nil, fmt.Errorf("error waiting for Network Security Group create/update completion: %w", err)
|
||||
}
|
||||
asg, err := future.Result(*c.c)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error obtaining result for Network Security Group create/update: %w", err)
|
||||
}
|
||||
return &asg, err
|
||||
}
|
||||
|
||||
func (c *NetworkSecurityGroupsClientImpl) List(ctx context.Context, resourceGroupName string) ([]network.SecurityGroup, error) {
|
||||
var l []network.SecurityGroup
|
||||
for iter, err := c.c.ListComplete(ctx, resourceGroupName); iter.NotDone(); err = iter.NextWithContext(ctx) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
l = append(l, iter.Value())
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
func (c *NetworkSecurityGroupsClientImpl) Delete(ctx context.Context, resourceGroupName, NetworkSecurityGroupName string) error {
|
||||
future, err := c.c.Delete(ctx, resourceGroupName, NetworkSecurityGroupName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error deleting Network Security Group: %w", err)
|
||||
}
|
||||
if err := future.WaitForCompletionRef(ctx, c.c.Client); err != nil {
|
||||
return fmt.Errorf("error waiting for Network Security Group deletion completion: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newNetworkSecurityGroupsClientImpl(subscriptionID string, authorizer autorest.Authorizer) *NetworkSecurityGroupsClientImpl {
|
||||
c := network.NewSecurityGroupsClient(subscriptionID)
|
||||
c.Authorizer = authorizer
|
||||
return &NetworkSecurityGroupsClientImpl{
|
||||
c: &c,
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
Copyright 2023 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package azuretasks
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2022-05-01/network"
|
||||
"github.com/Azure/go-autorest/autorest/to"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
"k8s.io/kops/upup/pkg/fi/cloudup/azure"
|
||||
)
|
||||
|
||||
// NetworkSecurityGroup is an Azure Cloud Network Security Group
|
||||
// +kops:fitask
|
||||
type NetworkSecurityGroup struct {
|
||||
Name *string
|
||||
ID *string
|
||||
Lifecycle fi.Lifecycle
|
||||
ResourceGroup *ResourceGroup
|
||||
|
||||
SecurityRules []*NetworkSecurityRule
|
||||
|
||||
Tags map[string]*string
|
||||
}
|
||||
|
||||
var (
|
||||
_ fi.CloudupTask = &NetworkSecurityGroup{}
|
||||
_ fi.CompareWithID = &NetworkSecurityGroup{}
|
||||
_ fi.CloudupTaskNormalize = &NetworkSecurityGroup{}
|
||||
)
|
||||
|
||||
// CompareWithID returns the Name of the Network Security Group
|
||||
func (nsg *NetworkSecurityGroup) CompareWithID() *string {
|
||||
return nsg.ID
|
||||
}
|
||||
|
||||
// Find discovers the Network Security Group in the cloud provider
|
||||
func (nsg *NetworkSecurityGroup) Find(c *fi.CloudupContext) (*NetworkSecurityGroup, error) {
|
||||
cloud := c.T.Cloud.(azure.AzureCloud)
|
||||
l, err := cloud.NetworkSecurityGroup().List(context.TODO(), *nsg.ResourceGroup.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var found *network.SecurityGroup
|
||||
for _, v := range l {
|
||||
if *v.Name == *nsg.Name {
|
||||
found = &v
|
||||
break
|
||||
}
|
||||
}
|
||||
if found == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
actual := &NetworkSecurityGroup{
|
||||
Name: nsg.Name,
|
||||
Lifecycle: nsg.Lifecycle,
|
||||
ResourceGroup: &ResourceGroup{
|
||||
Name: nsg.ResourceGroup.Name,
|
||||
},
|
||||
ID: found.ID,
|
||||
Tags: found.Tags,
|
||||
}
|
||||
for _, rule := range *found.SecurityRules {
|
||||
nsr := &NetworkSecurityRule{
|
||||
Name: rule.Name,
|
||||
Priority: rule.Priority,
|
||||
Access: rule.Access,
|
||||
Direction: rule.Direction,
|
||||
Protocol: rule.Protocol,
|
||||
SourceAddressPrefix: rule.SourceAddressPrefix,
|
||||
SourceAddressPrefixes: rule.SourceAddressPrefixes,
|
||||
SourcePortRange: rule.SourcePortRange,
|
||||
DestinationAddressPrefix: rule.DestinationAddressPrefix,
|
||||
DestinationAddressPrefixes: rule.DestinationAddressPrefixes,
|
||||
DestinationPortRange: rule.DestinationPortRange,
|
||||
}
|
||||
actual.SecurityRules = append(actual.SecurityRules, nsr)
|
||||
}
|
||||
|
||||
nsg.ID = found.ID
|
||||
|
||||
return actual, nil
|
||||
}
|
||||
|
||||
func (nsg *NetworkSecurityGroup) Normalize(c *fi.CloudupContext) error {
|
||||
c.T.Cloud.(azure.AzureCloud).AddClusterTags(nsg.Tags)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Run implements fi.Task.Run.
|
||||
func (nsg *NetworkSecurityGroup) Run(c *fi.CloudupContext) error {
|
||||
return fi.CloudupDefaultDeltaRunMethod(nsg, c)
|
||||
}
|
||||
|
||||
// CheckChanges returns an error if a change is not allowed.
|
||||
func (*NetworkSecurityGroup) CheckChanges(a, e, changes *NetworkSecurityGroup) error {
|
||||
if a == nil {
|
||||
// Check if required fields are set when a new resource is created.
|
||||
if e.Name == nil {
|
||||
return fi.RequiredField("Name")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check if unchangeable fields won't be changed.
|
||||
if changes.Name != nil {
|
||||
return fi.CannotChangeField("Name")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// RenderAzure creates or updates a Network Security Group.
|
||||
func (*NetworkSecurityGroup) RenderAzure(t *azure.AzureAPITarget, a, e, changes *NetworkSecurityGroup) error {
|
||||
if a == nil {
|
||||
klog.Infof("Creating a new Network Security Group with name: %s", fi.ValueOf(e.Name))
|
||||
} else {
|
||||
klog.Infof("Updating a Network Security Group with name: %s", fi.ValueOf(e.Name))
|
||||
}
|
||||
|
||||
p := network.SecurityGroup{
|
||||
SecurityGroupPropertiesFormat: &network.SecurityGroupPropertiesFormat{
|
||||
SecurityRules: &[]network.SecurityRule{},
|
||||
},
|
||||
Location: to.StringPtr(t.Cloud.Region()),
|
||||
Name: to.StringPtr(*e.Name),
|
||||
Tags: e.Tags,
|
||||
}
|
||||
for _, nsr := range e.SecurityRules {
|
||||
securityRule := network.SecurityRule{
|
||||
Name: nsr.Name,
|
||||
SecurityRulePropertiesFormat: &network.SecurityRulePropertiesFormat{
|
||||
Priority: nsr.Priority,
|
||||
Access: nsr.Access,
|
||||
Direction: nsr.Direction,
|
||||
Protocol: nsr.Protocol,
|
||||
SourceAddressPrefix: nsr.SourceAddressPrefix,
|
||||
SourceAddressPrefixes: nsr.SourceAddressPrefixes,
|
||||
SourcePortRange: nsr.SourcePortRange,
|
||||
DestinationAddressPrefix: nsr.DestinationAddressPrefix,
|
||||
DestinationAddressPrefixes: nsr.DestinationAddressPrefixes,
|
||||
DestinationPortRange: nsr.DestinationPortRange,
|
||||
},
|
||||
}
|
||||
*p.SecurityRules = append(*p.SecurityRules, securityRule)
|
||||
}
|
||||
|
||||
nsg, err := t.Cloud.NetworkSecurityGroup().CreateOrUpdate(
|
||||
context.TODO(),
|
||||
*e.ResourceGroup.Name,
|
||||
*e.Name,
|
||||
p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
e.ID = nsg.ID
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NetworkSecurityRule represents a NetworkSecurityGroup rule.
|
||||
type NetworkSecurityRule struct {
|
||||
Name *string
|
||||
Priority *int32
|
||||
Access network.SecurityRuleAccess
|
||||
Direction network.SecurityRuleDirection
|
||||
Protocol network.SecurityRuleProtocol
|
||||
SourceAddressPrefix *string
|
||||
SourceAddressPrefixes *[]string
|
||||
SourcePortRange *string
|
||||
DestinationAddressPrefixes *[]string
|
||||
DestinationAddressPrefix *string
|
||||
DestinationPortRange *string
|
||||
}
|
||||
|
||||
var _ fi.CloudupHasDependencies = &NetworkSecurityRule{}
|
||||
|
||||
func (e *NetworkSecurityRule) GetDependencies(tasks map[string]fi.CloudupTask) []fi.CloudupTask {
|
||||
return nil
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
//go:build !ignore_autogenerated
|
||||
// +build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
// Code generated by fitask. DO NOT EDIT.
|
||||
|
||||
package azuretasks
|
||||
|
||||
import (
|
||||
"k8s.io/kops/upup/pkg/fi"
|
||||
)
|
||||
|
||||
// NetworkSecurityGroup
|
||||
|
||||
var _ fi.HasLifecycle = &NetworkSecurityGroup{}
|
||||
|
||||
// GetLifecycle returns the Lifecycle of the object, implementing fi.HasLifecycle
|
||||
func (o *NetworkSecurityGroup) GetLifecycle() fi.Lifecycle {
|
||||
return o.Lifecycle
|
||||
}
|
||||
|
||||
// SetLifecycle sets the Lifecycle of the object, implementing fi.SetLifecycle
|
||||
func (o *NetworkSecurityGroup) SetLifecycle(lifecycle fi.Lifecycle) {
|
||||
o.Lifecycle = lifecycle
|
||||
}
|
||||
|
||||
var _ fi.HasName = &NetworkSecurityGroup{}
|
||||
|
||||
// GetName returns the Name of the object, implementing fi.HasName
|
||||
func (o *NetworkSecurityGroup) GetName() *string {
|
||||
return o.Name
|
||||
}
|
||||
|
||||
// String is the stringer function for the task, producing readable output using fi.TaskAsString
|
||||
func (o *NetworkSecurityGroup) String() string {
|
||||
return fi.CloudupTaskAsString(o)
|
||||
}
|
||||
|
|
@ -31,10 +31,12 @@ type Subnet struct {
|
|||
Name *string
|
||||
Lifecycle fi.Lifecycle
|
||||
|
||||
ResourceGroup *ResourceGroup
|
||||
VirtualNetwork *VirtualNetwork
|
||||
CIDR *string
|
||||
Shared *bool
|
||||
ResourceGroup *ResourceGroup
|
||||
VirtualNetwork *VirtualNetwork
|
||||
NetworkSecurityGroup *NetworkSecurityGroup
|
||||
|
||||
CIDR *string
|
||||
Shared *bool
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
@ -65,7 +67,7 @@ func (s *Subnet) Find(c *fi.CloudupContext) (*Subnet, error) {
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
return &Subnet{
|
||||
fs := &Subnet{
|
||||
Name: s.Name,
|
||||
Lifecycle: s.Lifecycle,
|
||||
Shared: s.Shared,
|
||||
|
|
@ -76,7 +78,14 @@ func (s *Subnet) Find(c *fi.CloudupContext) (*Subnet, error) {
|
|||
Name: s.VirtualNetwork.Name,
|
||||
},
|
||||
CIDR: found.AddressPrefix,
|
||||
}, nil
|
||||
}
|
||||
if found.NetworkSecurityGroup != nil {
|
||||
fs.NetworkSecurityGroup = &NetworkSecurityGroup{
|
||||
ID: found.NetworkSecurityGroup.ID,
|
||||
}
|
||||
}
|
||||
|
||||
return fs, nil
|
||||
}
|
||||
|
||||
// Run implements fi.Task.Run.
|
||||
|
|
@ -109,12 +118,17 @@ func (*Subnet) RenderAzure(t *azure.AzureAPITarget, a, e, changes *Subnet) error
|
|||
klog.Infof("Updating a Subnet with name: %s", fi.ValueOf(e.Name))
|
||||
}
|
||||
|
||||
// TODO(kenji): Be able to specify security groups.
|
||||
subnet := network.Subnet{
|
||||
SubnetPropertiesFormat: &network.SubnetPropertiesFormat{
|
||||
AddressPrefix: e.CIDR,
|
||||
},
|
||||
}
|
||||
if e.NetworkSecurityGroup != nil {
|
||||
subnet.NetworkSecurityGroup = &network.SecurityGroup{
|
||||
ID: e.NetworkSecurityGroup.ID,
|
||||
}
|
||||
}
|
||||
|
||||
return t.Cloud.Subnet().CreateOrUpdate(
|
||||
context.TODO(),
|
||||
*e.ResourceGroup.Name,
|
||||
|
|
|
|||
|
|
@ -46,18 +46,19 @@ const (
|
|||
|
||||
// MockAzureCloud is a mock implementation of AzureCloud.
|
||||
type MockAzureCloud struct {
|
||||
Location string
|
||||
ResourceGroupsClient *MockResourceGroupsClient
|
||||
VirtualNetworksClient *MockVirtualNetworksClient
|
||||
SubnetsClient *MockSubnetsClient
|
||||
RouteTablesClient *MockRouteTablesClient
|
||||
VMScaleSetsClient *MockVMScaleSetsClient
|
||||
VMScaleSetVMsClient *MockVMScaleSetVMsClient
|
||||
DisksClient *MockDisksClient
|
||||
RoleAssignmentsClient *MockRoleAssignmentsClient
|
||||
NetworkInterfacesClient *MockNetworkInterfacesClient
|
||||
LoadBalancersClient *MockLoadBalancersClient
|
||||
PublicIPAddressesClient *MockPublicIPAddressesClient
|
||||
Location string
|
||||
ResourceGroupsClient *MockResourceGroupsClient
|
||||
VirtualNetworksClient *MockVirtualNetworksClient
|
||||
SubnetsClient *MockSubnetsClient
|
||||
RouteTablesClient *MockRouteTablesClient
|
||||
NetworkSecurityGroupsClient *MockNetworkSecurityGroupsClient
|
||||
VMScaleSetsClient *MockVMScaleSetsClient
|
||||
VMScaleSetVMsClient *MockVMScaleSetVMsClient
|
||||
DisksClient *MockDisksClient
|
||||
RoleAssignmentsClient *MockRoleAssignmentsClient
|
||||
NetworkInterfacesClient *MockNetworkInterfacesClient
|
||||
LoadBalancersClient *MockLoadBalancersClient
|
||||
PublicIPAddressesClient *MockPublicIPAddressesClient
|
||||
}
|
||||
|
||||
var _ azure.AzureCloud = &MockAzureCloud{}
|
||||
|
|
@ -78,6 +79,9 @@ func NewMockAzureCloud(location string) *MockAzureCloud {
|
|||
RouteTablesClient: &MockRouteTablesClient{
|
||||
RTs: map[string]network.RouteTable{},
|
||||
},
|
||||
NetworkSecurityGroupsClient: &MockNetworkSecurityGroupsClient{
|
||||
NSGs: map[string]network.SecurityGroup{},
|
||||
},
|
||||
VMScaleSetsClient: &MockVMScaleSetsClient{
|
||||
VMSSes: map[string]compute.VirtualMachineScaleSet{},
|
||||
},
|
||||
|
|
@ -195,6 +199,11 @@ func (c *MockAzureCloud) RouteTable() azure.RouteTablesClient {
|
|||
return c.RouteTablesClient
|
||||
}
|
||||
|
||||
// NetworkSecurityGroup returns the VM Scale Set client.
|
||||
func (c *MockAzureCloud) NetworkSecurityGroup() azure.NetworkSecurityGroupsClient {
|
||||
return c.NetworkSecurityGroupsClient
|
||||
}
|
||||
|
||||
// VMScaleSet returns the VM Scale Set client.
|
||||
func (c *MockAzureCloud) VMScaleSet() azure.VMScaleSetsClient {
|
||||
return c.VMScaleSetsClient
|
||||
|
|
@ -612,3 +621,49 @@ func (c *MockPublicIPAddressesClient) Delete(ctx context.Context, scope, publicI
|
|||
delete(c.PubIPs, publicIPAddressName)
|
||||
return nil
|
||||
}
|
||||
|
||||
// MockNetworkSecurityGroupsClient is a mock implementation of Network Security Group client.
|
||||
type MockNetworkSecurityGroupsClient struct {
|
||||
NSGs map[string]network.SecurityGroup
|
||||
}
|
||||
|
||||
var _ azure.NetworkSecurityGroupsClient = &MockNetworkSecurityGroupsClient{}
|
||||
|
||||
// CreateOrUpdate creates or updates a Network Security Group.
|
||||
func (c *MockNetworkSecurityGroupsClient) CreateOrUpdate(ctx context.Context, resourceGroupName, asgName string, parameters network.SecurityGroup) (*network.SecurityGroup, error) {
|
||||
// Ignore resourceGroupName for simplicity.
|
||||
if _, ok := c.NSGs[asgName]; ok {
|
||||
return nil, fmt.Errorf("update not supported")
|
||||
}
|
||||
parameters.Name = &asgName
|
||||
c.NSGs[asgName] = parameters
|
||||
return ¶meters, nil
|
||||
}
|
||||
|
||||
// List returns a slice of Network Security Groups.
|
||||
func (c *MockNetworkSecurityGroupsClient) List(ctx context.Context, resourceGroupName string) ([]network.SecurityGroup, error) {
|
||||
var l []network.SecurityGroup
|
||||
for _, nsg := range c.NSGs {
|
||||
l = append(l, nsg)
|
||||
}
|
||||
return l, nil
|
||||
}
|
||||
|
||||
// Get Returns a specified Network Security Group.
|
||||
func (c *MockNetworkSecurityGroupsClient) Get(ctx context.Context, resourceGroupName string, nsgName string) (*network.SecurityGroup, error) {
|
||||
asg, ok := c.NSGs[nsgName]
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
return &asg, nil
|
||||
}
|
||||
|
||||
// Delete deletes a specified Network Security Group.
|
||||
func (c *MockNetworkSecurityGroupsClient) Delete(ctx context.Context, resourceGroupName, nsgName string) error {
|
||||
// Ignore resourceGroupName for simplicity.
|
||||
if _, ok := c.NSGs[nsgName]; !ok {
|
||||
return fmt.Errorf("%s does not exist", nsgName)
|
||||
}
|
||||
delete(c.NSGs, nsgName)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue