Skip to content

Commit

Permalink
fetch subnet value from infrastructure status
Browse files Browse the repository at this point in the history
  • Loading branch information
tedteng committed Apr 28, 2022
1 parent e5b5f98 commit 25feba9
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 59 deletions.
4 changes: 2 additions & 2 deletions pkg/controller/bastion/actuator.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,13 @@ func getPublicIP(ctx context.Context, factory azureclient.Factory, opt *Options)
return ip, nil
}

func getSubnet(ctx context.Context, factory azureclient.Factory, opt *Options) (*network.Subnet, error) {
func getSubnet(ctx context.Context, factory azureclient.Factory, vNet, subnetWork string, opt *Options) (*network.Subnet, error) {
subnetClient, err := factory.Subnet(ctx, opt.SecretReference)
if err != nil {
return nil, err
}

return subnetClient.Get(ctx, opt.ResourceGroupName, opt.VirtualNetwork, opt.Subnetwork, "")
return subnetClient.Get(ctx, opt.ResourceGroupName, vNet, subnetWork, "")
}

func deleteSecurityRuleDefinitionsByName(rulesArr *[]network.SecurityRule, namesToRemove ...string) bool {
Expand Down
36 changes: 31 additions & 5 deletions pkg/controller/bastion/actuator_reconcile.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import (
"net"
"time"

"github.com/gardener/gardener-extension-provider-azure/pkg/apis/azure"
"github.com/gardener/gardener-extension-provider-azure/pkg/apis/azure/helper"
azureclient "github.com/gardener/gardener-extension-provider-azure/pkg/azure/client"

"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2020-05-01/network"
Expand Down Expand Up @@ -52,6 +54,21 @@ func (a *actuator) Reconcile(ctx context.Context, bastion *extensionsv1alpha1.Ba
factory = azureclient.NewAzureClientFactory(a.client)
)

worker := &extensionsv1alpha1.Worker{}
err := a.client.Get(ctx, client.ObjectKey{Namespace: cluster.ObjectMeta.Name, Name: cluster.Shoot.Name}, worker)
if err != nil {
return err
}

if worker == nil || worker.Spec.InfrastructureProviderStatus == nil {
return errors.New("infrastructure Provider Status must be not empty for worker")
}

var infrastructureStatus *azure.InfrastructureStatus
if infrastructureStatus, err = helper.InfrastructureStatusFromRaw(worker.Spec.InfrastructureProviderStatus); err != nil {
return err
}

opt, err := DetermineOptions(bastion, cluster)
if err != nil {
return err
Expand All @@ -62,7 +79,15 @@ func (a *actuator) Reconcile(ctx context.Context, bastion *extensionsv1alpha1.Ba
return err
}

nic, err := ensureNic(ctx, factory, opt, publicIP)
if infrastructureStatus.Networks.Layout != "SingleSubnet" {
return fmt.Errorf("unsupported network layout %s", infrastructureStatus.Networks.Layout)
}

if infrastructureStatus.Networks.VNet.Name == "" || len(infrastructureStatus.Networks.Subnets) == 0 {
return errors.New("virtual name and subnet must be set")
}

nic, err := ensureNic(ctx, factory, opt, infrastructureStatus.Networks.VNet.Name, infrastructureStatus.Networks.Subnets[0].Name, publicIP)
if err != nil {
return err
}
Expand Down Expand Up @@ -257,7 +282,7 @@ func ensureComputeInstance(ctx context.Context, logger logr.Logger, bastion *ext
return nil
}

func ensureNic(ctx context.Context, factory azureclient.Factory, opt *Options, publicIP *network.PublicIPAddress) (*network.Interface, error) {
func ensureNic(ctx context.Context, factory azureclient.Factory, opt *Options, vNet, subnetWork string, publicIP *network.PublicIPAddress) (*network.Interface, error) {
nic, err := getNic(ctx, factory, opt)
if err != nil {
return nil, err
Expand All @@ -271,7 +296,7 @@ func ensureNic(ctx context.Context, factory azureclient.Factory, opt *Options, p

logger.Info("create new bastion compute instance nic")

subnet, err := getSubnet(ctx, factory, opt)
subnet, err := getSubnet(ctx, factory, vNet, subnetWork, opt)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -388,7 +413,7 @@ func addOrReplaceNsgRulesDefinition(existingRules *[]network.SecurityRule, desir

// filter rules intended to be replaced
for _, existentRule := range *existingRules {
if ruleExist(existentRule.Name, desiredRules) {
if RuleExist(existentRule.Name, desiredRules) {
continue
}
result = append(result, existentRule)
Expand All @@ -403,7 +428,8 @@ func addOrReplaceNsgRulesDefinition(existingRules *[]network.SecurityRule, desir
*existingRules = result
}

func ruleExist(ruleName *string, rules *[]network.SecurityRule) bool {
// RuleExist checks if the rule with the given name is present in the list of rules.
func RuleExist(ruleName *string, rules *[]network.SecurityRule) bool {
if ruleName == nil {
return false
}
Expand Down
2 changes: 0 additions & 2 deletions pkg/controller/bastion/bastion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,7 @@ var _ = Describe("Bastion test", func() {
Expect(err).To(Not(HaveOccurred()))

Expect(options.BastionInstanceName).To(Equal("cluster1-bastionName1-bastion-1cdc8"))
Expect(options.Subnetwork).To(Equal("cluster1-nodes"))
Expect(options.BastionPublicIPName).To(Equal("cluster1-bastionName1-bastion-1cdc8-public-ip"))
Expect(options.VirtualNetwork).To(Equal("cluster1"))
Expect(options.SecretReference).To(Equal(corev1.SecretReference{
Namespace: "cluster1",
Name: "cloudprovider",
Expand Down
6 changes: 1 addition & 5 deletions pkg/controller/bastion/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ const maxLengthForBaseName = 33
// Options contains provider-related information required for setting up
// a bastion instance. This struct combines precomputed values like the
// bastion instance name with the IDs of pre-existing cloud provider
// resources, like the nic name, subnet name etc.
// resources, like the nic name etc.
type Options struct {
BastionInstanceName string
BastionPublicIPName string
Expand All @@ -45,8 +45,6 @@ type Options struct {
NicName string
NicID string
DiskName string
Subnetwork string
VirtualNetwork string
SecretReference corev1.SecretReference
WorkersCIDR string
CIDRs []string
Expand Down Expand Up @@ -84,9 +82,7 @@ func DetermineOptions(bastion *extensionsv1alpha1.Bastion, cluster *controller.C

return &Options{
BastionInstanceName: baseResourceName,
Subnetwork: nodesResourceName(clusterName),
BastionPublicIPName: publicIPResourceName(baseResourceName),
VirtualNetwork: clusterName,
SecretReference: secretReference,
CIDRs: cidrs,
WorkersCIDR: workersCidr,
Expand Down
122 changes: 77 additions & 45 deletions test/integration/bastion/bastion_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/manager"

apisazure "github.com/gardener/gardener-extension-provider-azure/pkg/apis/azure"

"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2021-03-01/compute"
"github.com/Azure/azure-sdk-for-go/services/network/mgmt/2020-05-01/network"
"github.com/Azure/azure-sdk-for-go/services/resources/mgmt/2019-05-01/resources"
Expand All @@ -51,6 +53,7 @@ import (
networkingv1 "k8s.io/api/networking/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/utils/pointer"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/envtest"

Expand Down Expand Up @@ -151,23 +154,28 @@ var (
logger *logrus.Entry

extensionscluster *extensionsv1alpha1.Cluster
worker *extensionsv1alpha1.Worker
bastion *extensionsv1alpha1.Bastion
controllercluster *controller.Cluster
options *bastionctrl.Options
bastion *extensionsv1alpha1.Bastion
secret *corev1.Secret

testEnv *envtest.Environment
c client.Client
mgrCancel context.CancelFunc
clientSet *azureClientSet
name string
testEnv *envtest.Environment
c client.Client
mgrCancel context.CancelFunc
clientSet *azureClientSet
name string
vNetName string
subnetName string
)

var _ = BeforeSuite(func() {
randString, err := randomString()
Expect(err).NotTo(HaveOccurred())

name = fmt.Sprintf("azure-bastion-it--%s", randString)
vNetName = name
subnetName = vNetName + "-nodes"

myPublicIP, err = getMyPublicIPWithMask()
Expect(err).NotTo(HaveOccurred())
Expand All @@ -193,6 +201,7 @@ var _ = BeforeSuite(func() {
Paths: []string{
filepath.Join(repoRoot, "example", "20-crd-extensions.gardener.cloud_clusters.yaml"),
filepath.Join(repoRoot, "example", "20-crd-extensions.gardener.cloud_bastions.yaml"),
filepath.Join(repoRoot, "example", "20-crd-extensions.gardener.cloud_workers.yaml"),
},
},
}
Expand Down Expand Up @@ -227,6 +236,7 @@ var _ = BeforeSuite(func() {

extensionscluster, controllercluster = createClusters(name)
bastion, options = createBastion(controllercluster, name)
worker = createWorker(name)

secret = &corev1.Secret{
ObjectMeta: metav1.ObjectMeta{
Expand Down Expand Up @@ -259,7 +269,7 @@ var _ = Describe("Bastion tests", func() {

It("should successfully create and delete", func() {
resourceGroupName := name
vNetName := name

securityGroupName := name + "-workers"

By("setup Infrastructure")
Expand All @@ -271,7 +281,7 @@ var _ = Describe("Bastion tests", func() {
Expect(err).NotTo(HaveOccurred())

By("setup Virtual Network")
err = prepareNewVNet(ctx, logger, clientSet, resourceGroupName, vNetName, *region, VNetCIDR, sg)
err = prepareNewVNet(ctx, logger, clientSet, resourceGroupName, vNetName, subnetName, *region, VNetCIDR, sg)
Expect(err).NotTo(HaveOccurred())

framework.AddCleanupAction(func() {
Expand All @@ -280,9 +290,9 @@ var _ = Describe("Bastion tests", func() {
})

By("create namespace for test execution")
setupEnvironmentObjects(ctx, c, namespace(name), secret, extensionscluster)
setupEnvironmentObjects(ctx, c, namespace(name), secret, extensionscluster, worker)
framework.AddCleanupAction(func() {
teardownShootEnvironment(ctx, c, namespace(name), secret, extensionscluster)
teardownShootEnvironment(ctx, c, namespace(name), secret, extensionscluster, worker)
})

By("setup bastion")
Expand Down Expand Up @@ -413,9 +423,9 @@ func prepareSecurityGroup(ctx context.Context, logger *logrus.Entry, resourceGro
return future.Result(az.securityGroups)
}

func prepareNewVNet(ctx context.Context, logger *logrus.Entry, az *azureClientSet, groupName, vNetName, location, cidr string, nsg network.SecurityGroup) error {
logger.Infof("generating new VNet: %s/%s", groupName, vNetName)
vNetFuture, err := az.vnet.CreateOrUpdate(ctx, groupName, vNetName, network.VirtualNetwork{
func prepareNewVNet(ctx context.Context, logger *logrus.Entry, az *azureClientSet, resourceGroupName, vNetName, subnetName, location, cidr string, nsg network.SecurityGroup) error {
logger.Infof("generating new resource Group/VNet/subnetName: %s/%s/%s", resourceGroupName, vNetName, subnetName)
vNetFuture, err := az.vnet.CreateOrUpdate(ctx, resourceGroupName, vNetName, network.VirtualNetwork{
VirtualNetworkPropertiesFormat: &network.VirtualNetworkPropertiesFormat{
AddressSpace: &network.AddressSpace{
AddressPrefixes: &[]string{
Expand All @@ -424,7 +434,7 @@ func prepareNewVNet(ctx context.Context, logger *logrus.Entry, az *azureClientSe
},
Subnets: &[]network.Subnet{
{
Name: to.StringPtr(groupName + "-nodes"),
Name: to.StringPtr(subnetName),
SubnetPropertiesFormat: &network.SubnetPropertiesFormat{
AddressPrefix: to.StringPtr(cidr),
NetworkSecurityGroup: &nsg,
Expand Down Expand Up @@ -477,17 +487,24 @@ func namespace(name string) *corev1.Namespace {
}
}

func setupEnvironmentObjects(ctx context.Context, c client.Client, namespace *corev1.Namespace, secret *corev1.Secret, cluster *extensionsv1alpha1.Cluster) {
func setupEnvironmentObjects(ctx context.Context, c client.Client, namespace *corev1.Namespace, secret *corev1.Secret, cluster *extensionsv1alpha1.Cluster, worker *extensionsv1alpha1.Worker) {
Expect(c.Create(ctx, namespace)).To(Succeed())
Expect(c.Create(ctx, cluster)).To(Succeed())
Expect(c.Create(ctx, secret)).To(Succeed())

Expect(c.Create(ctx, worker)).To(Succeed())
}

func teardownShootEnvironment(ctx context.Context, c client.Client, namespace *corev1.Namespace, secret *corev1.Secret, cluster *extensionsv1alpha1.Cluster) {
func teardownShootEnvironment(ctx context.Context, c client.Client, namespace *corev1.Namespace, secret *corev1.Secret, cluster *extensionsv1alpha1.Cluster, worker *extensionsv1alpha1.Worker) {
Expect(client.IgnoreNotFound(c.Delete(ctx, worker))).To(Succeed())
Expect(client.IgnoreNotFound(c.Delete(ctx, secret))).To(Succeed())
Expect(client.IgnoreNotFound(c.Delete(ctx, cluster))).To(Succeed())
Expect(client.IgnoreNotFound(c.Delete(ctx, namespace))).To(Succeed())

}

func encode(obj runtime.Object) []byte {
data, _ := json.Marshal(obj)
return data
}

func createBastion(cluster *controller.Cluster, name string) (*extensionsv1alpha1.Bastion, *bastionctrl.Options) {
Expand Down Expand Up @@ -515,6 +532,35 @@ func createBastion(cluster *controller.Cluster, name string) (*extensionsv1alpha
return bastion, options
}

func createWorker(name string) *extensionsv1alpha1.Worker {
return &extensionsv1alpha1.Worker{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: name,
},
Spec: extensionsv1alpha1.WorkerSpec{
DefaultSpec: extensionsv1alpha1.DefaultSpec{
Type: azure.Type,
},
InfrastructureProviderStatus: &runtime.RawExtension{
Raw: encode(&apisazure.InfrastructureStatus{
Networks: apisazure.NetworkStatus{
Layout: apisazure.NetworkLayout("SingleSubnet"),
VNet: apisazure.VNetStatus{Name: vNetName},
Subnets: []apisazure.Subnet{
{
Purpose: apisazure.PurposeNodes,
Name: subnetName,
},
},
},
}),
},
Pools: []extensionsv1alpha1.WorkerPool{},
},
}
}

func createInfrastructureConfig() *azurev1alpha1.InfrastructureConfig {
return &azurev1alpha1.InfrastructureConfig{
TypeMeta: metav1.TypeMeta{
Expand All @@ -533,6 +579,10 @@ func createShoot(infrastructureConfig []byte) *gardencorev1beta1.Shoot {
APIVersion: "core.gardener.cloud/v1beta1",
Kind: "Shoot",
},

ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Spec: gardencorev1beta1.ShootSpec{
Region: *region,
SecretBindingName: v1beta1constants.SecretNameCloudProvider,
Expand Down Expand Up @@ -626,40 +676,22 @@ func verifyDeletion(ctx context.Context, az *azureClientSet, options *bastionctr
}

func checkSecurityRuleDoesNotExist(ctx context.Context, az *azureClientSet, options *bastionctrl.Options, securityRuleName string) {
_, err := az.securityRules.Get(ctx, options.ResourceGroupName, options.SecurityGroupName, securityRuleName)
//does not have authorization to performsecurityRules get due to global rule. use security group to check it.
sg, err := az.securityGroups.Get(ctx, options.ResourceGroupName, options.SecurityGroupName, "")
Expect(len(*sg.SecurityRules)).To(Equal(0))
Expect(ignoreAzureNotFoundError(err)).To(Succeed())
}

func checkSecurityRuleslExists(ctx context.Context, az *azureClientSet, options *bastionctrl.Options, securityRuleName string) {
nsgRule, err := az.securityRules.Get(ctx, options.ResourceGroupName, options.SecurityGroupName, securityRuleName)
Expect(err).NotTo(HaveOccurred())
Expect(*nsgRule.Name).To(Equal(securityRuleName))
}

func verifyCreation(ctx context.Context, az *azureClientSet, options *bastionctrl.Options) {
By("checkNSGExists")
// bastion NSG - Check Ingress / Egress firewalls created
checkSecurityRuleslExists(ctx, az, options, bastionctrl.NSGIngressAllowSSHResourceNameIPv4(options.BastionInstanceName))
checkSecurityRuleslExists(ctx, az, options, bastionctrl.NSGEgressDenyAllResourceName(options.BastionInstanceName))
checkSecurityRuleslExists(ctx, az, options, bastionctrl.NSGEgressAllowOnlyResourceName(options.BastionInstanceName))

By("checking NSG-allow-ssh rule SSHPortOpen,Public Source Ranges")
result, err := az.securityRules.Get(ctx, options.ResourceGroupName, options.SecurityGroupName, bastionctrl.NSGIngressAllowSSHResourceNameIPv4(options.BastionInstanceName))
By("RuleExist")
//does not have authorization to performsecurityRules get due to global rule. use security group to check it.
sg, err := az.securityGroups.Get(ctx, options.ResourceGroupName, options.SecurityGroupName, "")
Expect(err).NotTo(HaveOccurred())
Expect(*result.DestinationPortRange).To(Equal("22"))
Expect(*result.SourceAddressPrefixes).To(Equal([]string{myPublicIP}))
Expect(result.SourceAddressPrefix).To(BeNil())

By("checking Firewall-deny-all rule")
result, err = az.securityRules.Get(ctx, options.ResourceGroupName, options.SecurityGroupName, bastionctrl.NSGEgressDenyAllResourceName(options.BastionInstanceName))
Expect(err).NotTo(HaveOccurred())
Expect(result.Protocol).To(Equal(network.SecurityRuleProtocolAsterisk))
Expect(result.DestinationAddressPrefix).To(Equal(to.StringPtr("*")))

By("checking Firewall-egress-worker rule")
result, err = az.securityRules.Get(ctx, options.ResourceGroupName, options.SecurityGroupName, bastionctrl.NSGEgressAllowOnlyResourceName(options.BastionInstanceName))
Expect(err).NotTo(HaveOccurred())
Expect(*result.DestinationAddressPrefix).To(Equal(options.WorkersCIDR))
// bastion NSG - Check Ingress / Egress firewalls created
bastionctrl.RuleExist(pointer.StringPtr(bastionctrl.NSGIngressAllowSSHResourceNameIPv4(options.BastionInstanceName)), sg.SecurityRules)
bastionctrl.RuleExist(pointer.StringPtr(bastionctrl.NSGEgressDenyAllResourceName(options.BastionInstanceName)), sg.SecurityRules)
bastionctrl.RuleExist(pointer.StringPtr(bastionctrl.NSGEgressAllowOnlyResourceName(options.BastionInstanceName)), sg.SecurityRules)

By("checking bastion instance")
//bastion instance
Expand Down

0 comments on commit 25feba9

Please sign in to comment.