Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix reconciliation of user managed public IPs in flow #1051

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions pkg/azure/client/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,3 +82,8 @@ type ContainerDeleteFunc[T any] interface {
type ContainerCheckExistenceFunc[T any] interface {
CheckExistence(ctx context.Context, container string) (bool, error)
}

// UpdateTags updates the tags of a resource.
type UpdateTags interface {
UpdateTags(ctx context.Context, name, resourceGroupName string, tags map[string]*string) error
}
14 changes: 14 additions & 0 deletions pkg/azure/client/mock/mocks.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions pkg/azure/client/publicip.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,15 @@ func (c *PublicIPClient) List(ctx context.Context, resourceGroupName string) ([]
return ips, nil
}

// UpdateTags will add tags to a network Public IP Address.
func (c *PublicIPClient) UpdateTags(ctx context.Context, name, resourceGroupName string, tags map[string]*string) error {
_, err := c.client.UpdateTags(ctx, resourceGroupName, name, armnetwork.TagsObject{Tags: tags}, nil)
if err != nil {
return FilterNotFoundError(err)
}
return nil
}

// Delete will delete a network Public IP Address.
func (c *PublicIPClient) Delete(ctx context.Context, resourceGroupName, name string) error {
future, err := c.client.BeginDelete(ctx, resourceGroupName, name, nil)
Expand Down
1 change: 1 addition & 0 deletions pkg/azure/client/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ type PublicIP interface {
CreateOrUpdateFunc[armnetwork.PublicIPAddress]
DeleteFunc[armnetwork.PublicIPAddress]
ListFunc[armnetwork.PublicIPAddress]
UpdateTags
}

// NetworkInterface represents an Azure Network Interface k8sClient.
Expand Down
5 changes: 5 additions & 0 deletions pkg/controller/infrastructure/infraflow/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,9 @@ const (
ChildKeyMigration = "migration"
// ChildKeyComplete is a key to indicate whether a task is complete.
ChildKeyComplete = "complete"

// IgnoredByGardenerTag is the tag used to mark resources managed by Gardener.
// It's used for an edge case where public IPs that are customer managed + migrated
// from terraform + reside in our RG + have the shoot prefix name.
IgnoredByGardenerTag = "managedByGardener"
)
35 changes: 34 additions & 1 deletion pkg/controller/infrastructure/infraflow/ensurer.go
Original file line number Diff line number Diff line change
Expand Up @@ -365,9 +365,40 @@ func (fctx *FlowContext) ensureSecurityGroup(ctx context.Context) (*armnetwork.S

// EnsurePublicIps reconciles the public IPs for the shoot.
func (fctx *FlowContext) EnsurePublicIps(ctx context.Context) error {
// as a workaround for problems encountered during the tf migration public user IPs are annotated
// with the IgnoredByGardenerTag because they are otherwise deleted by the flow reconciler.
err := fctx.tagUserIp(ctx)
if err != nil {
return err
}
return errors.Join(fctx.ensurePublicIps(ctx), fctx.ensureUserPublicIps(ctx))
}

// tagUserIp tags public IPs under the following conditions:
// - the IP is customer managed
// - the IP got migrated from terraform
// - the IP resides in our RG and
// - the IPs name has the shoot prefix.
func (fctx *FlowContext) tagUserIp(ctx context.Context) error {
natGatewayCfg := fctx.cfg.Networks.NatGateway
if natGatewayCfg != nil && natGatewayCfg.Enabled {
for _, ipRef := range natGatewayCfg.IPAddresses {
if fctx.adapter.HasShootPrefix(&ipRef.Name) && fctx.adapter.ResourceGroupName() == ipRef.ResourceGroup {
c, err := fctx.factory.PublicIP()
if err != nil {
return err
}
updateTags := map[string]*string{IgnoredByGardenerTag: to.Ptr("true")}
err = c.UpdateTags(ctx, ipRef.ResourceGroup, ipRef.Name, updateTags)
if err != nil {
return err
}
}
}
}
return nil
}

func (fctx *FlowContext) ensureUserPublicIps(ctx context.Context) error {
c, err := fctx.factory.PublicIP()
if err != nil {
Expand Down Expand Up @@ -415,7 +446,9 @@ func (fctx *FlowContext) ensurePublicIps(ctx context.Context) error {
currentIPs = Filter(currentIPs, func(address *armnetwork.PublicIPAddress) bool {
// filter only these IpConfigs prefixed by the cluster name and that do not contain the CCM tags.
return fctx.adapter.HasShootPrefix(address.Name) &&
(address.Tags[azure.CCMServiceTagKey] == nil && address.Tags[azure.CCMLegacyServiceTagKey] == nil)
address.Tags[azure.CCMServiceTagKey] == nil &&
address.Tags[azure.CCMLegacyServiceTagKey] == nil &&
address.Tags[IgnoredByGardenerTag] == nil
})
// obtain an indexed list of current IPs
nameToCurrentIps := ToMap(currentIPs, func(t *armnetwork.PublicIPAddress) string {
Expand Down
Loading