-
Notifications
You must be signed in to change notification settings - Fork 76
/
helper.go
147 lines (130 loc) · 6.25 KB
/
helper.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
// SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Gardener contributors
//
// SPDX-License-Identifier: Apache-2.0
package helper
import (
"fmt"
v1beta1constants "github.com/gardener/gardener/pkg/apis/core/v1beta1/constants"
"k8s.io/utils/ptr"
api "github.com/gardener/gardener-extension-provider-azure/pkg/apis/azure"
"github.com/gardener/gardener-extension-provider-azure/pkg/azure"
)
// FindSubnetByPurposeAndZone takes a list of subnets and tries to find the first entry whose purpose matches with the given purpose.
// Optionally, if the zone argument is not nil, the Zone field of a candidate subnet must match that value.
// FindSubnetByPurposeAndZone returns the index of the subnet in the array and the subnet object.
// If no such entry is found then an error will be returned.
func FindSubnetByPurposeAndZone(subnets []api.Subnet, purpose api.Purpose, zone *string) (int, *api.Subnet, error) {
for index, subnet := range subnets {
if subnet.Purpose == purpose && (zone == nil || (subnet.Zone != nil && *subnet.Zone == *zone)) {
return index, &subnet, nil
}
}
errMsg := fmt.Sprintf("cannot find subnet with purpose %q", purpose)
if zone != nil {
errMsg += fmt.Sprintf(" and zone %q", *zone)
}
return 0, nil, fmt.Errorf(errMsg)
}
// FindSecurityGroupByPurpose takes a list of security groups and tries to find the first entry
// whose purpose matches with the given purpose. If no such entry is found then an error will be
// returned.
func FindSecurityGroupByPurpose(securityGroups []api.SecurityGroup, purpose api.Purpose) (*api.SecurityGroup, error) {
for _, securityGroup := range securityGroups {
if securityGroup.Purpose == purpose {
return &securityGroup, nil
}
}
return nil, fmt.Errorf("cannot find security group with purpose %q", purpose)
}
// FindRouteTableByPurpose takes a list of route tables and tries to find the first entry
// whose purpose matches with the given purpose. If no such entry is found then an error will be
// returned.
func FindRouteTableByPurpose(routeTables []api.RouteTable, purpose api.Purpose) (*api.RouteTable, error) {
for _, routeTable := range routeTables {
if routeTable.Purpose == purpose {
return &routeTable, nil
}
}
return nil, fmt.Errorf("cannot find route table with purpose %q", purpose)
}
// FindAvailabilitySetByPurpose takes a list of availability sets and tries to find the first entry
// whose purpose matches with the given purpose. If no such entry is found then an error will be
// returned.
func FindAvailabilitySetByPurpose(availabilitySets []api.AvailabilitySet, purpose api.Purpose) (*api.AvailabilitySet, error) {
for _, availabilitySet := range availabilitySets {
if availabilitySet.Purpose == purpose {
return &availabilitySet, nil
}
}
return nil, fmt.Errorf("cannot find availability set with purpose %q", purpose)
}
// FindMachineImage takes a list of machine images and tries to find the first entry
// whose name, version, architecture and zone matches with the given name, version, and zone. If no such entry is
// found then an error will be returned.
func FindMachineImage(machineImages []api.MachineImage, name, version string, architecture *string) (*api.MachineImage, error) {
for _, machineImage := range machineImages {
if machineImage.Architecture == nil {
machineImage.Architecture = ptr.To(v1beta1constants.ArchitectureAMD64)
}
if machineImage.Name == name && machineImage.Version == version && ptr.Equal(architecture, machineImage.Architecture) {
return &machineImage, nil
}
}
return nil, fmt.Errorf("no machine image found with name %q, architecture %q and version %q", name, *architecture, version)
}
// FindDomainCountByRegion takes a region and the domain counts and finds the count for the given region.
func FindDomainCountByRegion(domainCounts []api.DomainCount, region string) (int32, error) {
for _, domainCount := range domainCounts {
if domainCount.Region == region {
return domainCount.Count, nil
}
}
return 0, fmt.Errorf("could not find a domain count for region %s", region)
}
// FindImageFromCloudProfile takes a list of machine images, and the desired image name and version. It tries
// to find the image with the given name, architecture and version. If it cannot be found then an error
// is returned.
func FindImageFromCloudProfile(cloudProfileConfig *api.CloudProfileConfig, imageName, imageVersion string, architecture *string) (*api.MachineImage, error) {
if cloudProfileConfig != nil {
for _, machineImage := range cloudProfileConfig.MachineImages {
if machineImage.Name != imageName {
continue
}
for _, version := range machineImage.Versions {
if imageVersion == version.Version && ptr.Equal(architecture, version.Architecture) {
return &api.MachineImage{
Name: imageName,
Version: version.Version,
URN: version.URN,
ID: version.ID,
SharedGalleryImageID: version.SharedGalleryImageID,
CommunityGalleryImageID: version.CommunityGalleryImageID,
AcceleratedNetworking: version.AcceleratedNetworking,
Architecture: version.Architecture,
}, nil
}
}
}
}
return nil, fmt.Errorf("no machine image found with name %q, architecture %q and version %q", imageName, *architecture, imageVersion)
}
// IsVmoRequired determines if VMO is required.
func IsVmoRequired(infrastructureStatus *api.InfrastructureStatus) bool {
return !infrastructureStatus.Zoned && len(infrastructureStatus.AvailabilitySets) == 0
}
// HasShootVmoAlphaAnnotation determines if the passed Shoot annotations contain instruction to use VMO.
func HasShootVmoAlphaAnnotation(shootAnnotations map[string]string) bool {
value, exists := shootAnnotations[azure.ShootVmoUsageAnnotation]
if exists && value == "true" {
return true
}
return false
}
// InfrastructureZoneToString translates the zone from the string format used in Gardener core objects to the int32 format used by the Azure provider extension.
func InfrastructureZoneToString(zone int32) string {
return fmt.Sprintf("%d", zone)
}
// IsUsingSingleSubnetLayout returns true if the infrastructure configuration is using a network setup with a single subnet.
func IsUsingSingleSubnetLayout(config *api.InfrastructureConfig) bool {
return len(config.Networks.Zones) == 0
}