Skip to content

Commit

Permalink
provide egress CIDRs via infrastructure state
Browse files Browse the repository at this point in the history
Provide the CIDR blocks of the shoots egress via the shoots
infrastructure-resource, for both Terraform- and flow-based
reconciliation.
Also update tests.
  • Loading branch information
AndreasBurger committed May 29, 2024
1 parent b203cc7 commit c856147
Show file tree
Hide file tree
Showing 7 changed files with 85 additions and 10 deletions.
2 changes: 1 addition & 1 deletion pkg/controller/infrastructure/flow_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -184,5 +184,5 @@ func (f *FlowReconciler) migrateFromTerraform(ctx context.Context, infra *extens
// we will use a specific "marker" to make the reconciler aware of existing resources. This will prevent the reconciler from skipping the deletion flow.
state.Data[infraflow.CreatedResourcesExistKey] = "true"

return state, infrainternal.PatchProviderStatusAndState(ctx, f.client, infra, nil, &runtime.RawExtension{Object: state})
return state, infrainternal.PatchProviderStatusAndState(ctx, f.client, infra, nil, &runtime.RawExtension{Object: state}, nil)
}
38 changes: 38 additions & 0 deletions pkg/controller/infrastructure/infraflow/ensurer.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"errors"
"fmt"

"github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v5"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v4"
Expand Down Expand Up @@ -512,6 +513,9 @@ func (fctx *FlowContext) ensureNatGateways(ctx context.Context) error {
return joinError
}

ipClient, _ := fctx.factory.PublicIP()
ipAddresses := []string{}

for name, nat := range toReconcile {
nat, err := c.CreateOrUpdate(ctx, fctx.adapter.ResourceGroupName(), name, *nat)
if err != nil {
Expand All @@ -523,8 +527,26 @@ func (fctx *FlowContext) ensureNatGateways(ctx context.Context) error {
continue
}
fctx.whiteboard.GetChild(KindNatGateway.String()).Set(name, *nat.ID)

for _, ip := range nat.Properties.PublicIPAddresses {
resourceId, err := arm.ParseResourceID(*ip.ID)
if err != nil {
joinError = errors.Join(joinError, err)
continue
}
ipObj, err := ipClient.Get(ctx, fctx.adapter.ResourceGroupName(), resourceId.Name, nil)
if err != nil {
joinError = errors.Join(joinError, err)
continue
}
if ipObj.Properties.IPAddress != nil {
ipAddresses = append(ipAddresses, *ipObj.Properties.IPAddress)
}
}
}

fctx.whiteboard.GetChild(KindNatGateway.String()).SetObject(KeyPublicIPAddresses, ipAddresses)

return joinError
}

Expand Down Expand Up @@ -729,6 +751,22 @@ func (fctx *FlowContext) GetInfrastructureState() *runtime.RawExtension {
}
}

// GetEgressIpCidrs retrieves the CIDRs of the IP ranges used for egress from the FlowContext
func (fctx *FlowContext) GetEgressIpCidrs() []string {
if fctx.whiteboard.HasChild(KindNatGateway.String()) && fctx.whiteboard.GetChild(KindNatGateway.String()).HasObject(KeyPublicIPAddresses) {
ipAddresses, ok := fctx.whiteboard.GetChild(KindNatGateway.String()).GetObject(KeyPublicIPAddresses).([]string)
if !ok {
return nil
}
cidrs := []string{}
for _, address := range ipAddresses {
cidrs = append(cidrs, address+"/32")
}
return cidrs
}
return nil
}

func (fctx *FlowContext) enrichStatusWithIdentity(_ context.Context, status *v1alpha1.InfrastructureStatus) error {
if identity := fctx.cfg.Identity; identity != nil {
status.Identity = &v1alpha1.IdentityStatus{
Expand Down
5 changes: 3 additions & 2 deletions pkg/controller/infrastructure/infraflow/flow_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,11 @@ func (fctx *FlowContext) Reconcile(ctx context.Context) error {

status, err := fctx.GetInfrastructureStatus(ctx)
state := fctx.GetInfrastructureState()
egressCidrs := fctx.GetEgressIpCidrs()
if err != nil {
return err
}
return infrainternal.PatchProviderStatusAndState(ctx, fctx.client, fctx.infra, status, state)
return infrainternal.PatchProviderStatusAndState(ctx, fctx.client, fctx.infra, status, state, egressCidrs)
}

func (fctx *FlowContext) buildReconcileGraph() *flow.Graph {
Expand Down Expand Up @@ -196,5 +197,5 @@ func (fctx *FlowContext) Delete(ctx context.Context) error {
}

func (fctx *FlowContext) persistState(ctx context.Context) error {
return infrainternal.PatchProviderStatusAndState(ctx, fctx.client, fctx.infra, nil, fctx.GetInfrastructureState())
return infrainternal.PatchProviderStatusAndState(ctx, fctx.client, fctx.infra, nil, fctx.GetInfrastructureState(), fctx.GetEgressIpCidrs())
}
5 changes: 5 additions & 0 deletions pkg/controller/infrastructure/infraflow/provider_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,11 @@ const (
KindVirtualNetwork AzureResourceKind = "Microsoft.Network/virtualNetworks"
)

const (
// KeyPublicIPAddresses is the key used to store public IP addresses in the FlowContext's whiteboard.
KeyPublicIPAddresses = "PublicIpAddresses"
)

const (
// TemplateAvailabilitySet the template for the ID of an availability set.
TemplateAvailabilitySet = "/subscriptions/%s/resourceGroups/%s/providers/Microsoft.Compute/availabilitySets/%s"
Expand Down
18 changes: 11 additions & 7 deletions pkg/controller/infrastructure/terraform_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,20 +132,24 @@ func (r *TerraformReconciler) reconcile(ctx context.Context, infra *extensionsv1
if err != nil {
return err
}
state, err := r.getState(ctx, tf, status)
terraformState, err := tf.GetRawState(ctx)
if err != nil {
return err
}
state, err := r.getState(terraformState, status)
if err != nil {
return err
}
egressCidrs, err := infrastructure.EgressCidrs(terraformState)
if err != nil {
return err
}

return infrastructure.PatchProviderStatusAndState(ctx, r.Client, infra, status, state)
return infrastructure.PatchProviderStatusAndState(ctx, r.Client, infra, status, state, egressCidrs)
}

// getState calculates the State resource after each reconciliation.
func (r *TerraformReconciler) getState(ctx context.Context, tf terraformer.Terraformer, status *v1alpha1.InfrastructureStatus) (*runtime.RawExtension, error) {
terraformState, err := tf.GetRawState(ctx)
if err != nil {
return nil, err
}
func (r *TerraformReconciler) getState(terraformState *terraformer.RawState, status *v1alpha1.InfrastructureStatus) (*runtime.RawExtension, error) {

stateByte, err := terraformState.Marshal()
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions pkg/internal/infrastructure/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,14 @@ func PatchProviderStatusAndState(
infra *extensionsv1alpha1.Infrastructure,
status *apiv1alpha1.InfrastructureStatus,
state *runtime.RawExtension,
egressCidrs []string,
) error {
patch := client.MergeFrom(infra.DeepCopy())
if status != nil {
infra.Status.ProviderStatus = &runtime.RawExtension{Object: status}
if egressCidrs != nil {
infra.Status.EgressCIDRs = egressCidrs
}
}
if state != nil {
infra.Status.State = state
Expand Down
23 changes: 23 additions & 0 deletions pkg/internal/infrastructure/terraform.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/gardener/gardener-extension-provider-azure/pkg/apis/azure/helper"
apiv1alpha1 "github.com/gardener/gardener-extension-provider-azure/pkg/apis/azure/v1alpha1"
"github.com/gardener/gardener-extension-provider-azure/pkg/azure"
"github.com/gardener/gardener-extension-provider-azure/pkg/controller/infrastructure/infraflow/shared"
)

const (
Expand Down Expand Up @@ -432,6 +433,28 @@ func ExtractTerraformState(ctx context.Context, tf terraformer.Terraformer, infr
return &tfState, nil
}

// EgressCidrs retrieves the Egress CIDRs from the Terraform state and returns them.
func EgressCidrs(terraformState *terraformer.RawState) ([]string, error) {
tfState, err := shared.UnmarshalTerraformStateFromTerraformer(terraformState)
if err != nil {
return nil, err
}
resources := tfState.FindManagedResourcesByType("azurerm_public_ip")

egressCidrs := []string{}
for _, resource := range resources {
for _, instance := range resource.Instances {
rawIpAddress := instance.Attributes["ip_address"]
ipAddress, ok := rawIpAddress.(string)
if !ok {
return nil, fmt.Errorf("error parsing '%v' as IP-address from Terraform state", rawIpAddress)
}
egressCidrs = append(egressCidrs, ipAddress+"/32")
}
}
return egressCidrs, nil
}

// StatusFromTerraformState computes an InfrastructureStatus from the given
// Terraform variables.
func StatusFromTerraformState(config *api.InfrastructureConfig, tfState *TerraformState) *apiv1alpha1.InfrastructureStatus {
Expand Down

0 comments on commit c856147

Please sign in to comment.