Skip to content

Commit

Permalink
Merge pull request #3469 from newrelic-forks/cherry-pick-3414-to-rele…
Browse files Browse the repository at this point in the history
…ase-1.7

[release-1.7] update SDKImageToImage func to handle different image types
  • Loading branch information
k8s-ci-robot authored Apr 21, 2023
2 parents 955962e + 9c552b9 commit cc7c34b
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 15 deletions.
105 changes: 99 additions & 6 deletions azure/converters/vmss.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ limitations under the License.
package converters

import (
"regexp"

"github.com/Azure/azure-sdk-for-go/services/compute/mgmt/2021-11-01/compute"
"github.com/Azure/go-autorest/autorest/to"
"k8s.io/utils/pointer"
Expand All @@ -25,6 +27,13 @@ import (
"sigs.k8s.io/cluster-api-provider-azure/azure"
)

const (
// RegExpStrCommunityGalleryID is a regexp string used for matching community gallery IDs and capturing specific values.
RegExpStrCommunityGalleryID = `/CommunityGalleries/(?P<gallery>.*)/Images/(?P<name>.*)/Versions/(?P<version>.*)`
// RegExpStrComputeGalleryID is a regexp string used for matching compute gallery IDs and capturing specific values.
RegExpStrComputeGalleryID = `/subscriptions/(?P<subID>.*)/resourceGroups/(?P<rg>.*)/providers/Microsoft.Compute/galleries/(?P<gallery>.*)/images/(?P<name>.*)/versions/(?P<version>.*)`
)

// SDKToVMSS converts an Azure SDK VirtualMachineScaleSet to the AzureMachinePool type.
func SDKToVMSS(sdkvmss compute.VirtualMachineScaleSet, sdkinstances []compute.VirtualMachineScaleSetVM) *azure.VMSS {
vmss := &azure.VMSS{
Expand Down Expand Up @@ -150,8 +159,53 @@ func SDKToVMSSVM(sdkInstance compute.VirtualMachineScaleSetVM) *azure.VMSSVM {

// SDKImageToImage converts a SDK image reference to infrav1.Image.
func SDKImageToImage(sdkImageRef *compute.ImageReference, isThirdPartyImage bool) infrav1.Image {
if sdkImageRef.ID != nil {
return IDImageRefToImage(*sdkImageRef.ID)
}
// community gallery image
if sdkImageRef.CommunityGalleryImageID != nil {
return cgImageRefToImage(*sdkImageRef.CommunityGalleryImageID)
}
// shared gallery image
if sdkImageRef.SharedGalleryImageID != nil {
return sgImageRefToImage(*sdkImageRef.SharedGalleryImageID)
}
// marketplace image
return mpImageRefToImage(sdkImageRef, isThirdPartyImage)
}

// GetOrchestrationMode returns the compute.OrchestrationMode for the given infrav1.OrchestrationModeType.
func GetOrchestrationMode(modeType infrav1.OrchestrationModeType) compute.OrchestrationMode {
if modeType == infrav1.FlexibleOrchestrationMode {
return compute.OrchestrationModeFlexible
}
return compute.OrchestrationModeUniform
}

// IDImageRefToImage converts an ID to a infrav1.Image with ComputerGallery set or ID, depending on the structure of the ID.
func IDImageRefToImage(id string) infrav1.Image {
// compute gallery image
if ok, params := getParams(RegExpStrComputeGalleryID, id); ok {
return infrav1.Image{
ComputeGallery: &infrav1.AzureComputeGalleryImage{
Gallery: params["gallery"],
Name: params["name"],
Version: params["version"],
SubscriptionID: pointer.String(params["subID"]),
ResourceGroup: pointer.String(params["rg"]),
},
}
}

// specific image
return infrav1.Image{
ID: &id,
}
}

// mpImageRefToImage converts a marketplace gallery ImageReference to an infrav1.Image.
func mpImageRefToImage(sdkImageRef *compute.ImageReference, isThirdPartyImage bool) infrav1.Image {
return infrav1.Image{
ID: sdkImageRef.ID,
Marketplace: &infrav1.AzureMarketplaceImage{
ImagePlan: infrav1.ImagePlan{
Publisher: to.String(sdkImageRef.Publisher),
Expand All @@ -164,10 +218,49 @@ func SDKImageToImage(sdkImageRef *compute.ImageReference, isThirdPartyImage bool
}
}

// GetOrchestrationMode returns the compute.OrchestrationMode for the given infrav1.OrchestrationModeType.
func GetOrchestrationMode(modeType infrav1.OrchestrationModeType) compute.OrchestrationMode {
if modeType == infrav1.FlexibleOrchestrationMode {
return compute.OrchestrationModeFlexible
// cgImageRefToImage converts a community gallery ImageReference to an infrav1.Image.
func cgImageRefToImage(id string) infrav1.Image {
if ok, params := getParams(RegExpStrCommunityGalleryID, id); ok {
return infrav1.Image{
ComputeGallery: &infrav1.AzureComputeGalleryImage{
Gallery: params["gallery"],
Name: params["name"],
Version: params["version"],
},
}
}
return compute.OrchestrationModeUniform
return infrav1.Image{}
}

// sgImageRefToImage converts a shared gallery ImageReference to an infrav1.Image.
func sgImageRefToImage(id string) infrav1.Image {
if ok, params := getParams(RegExpStrComputeGalleryID, id); ok {
return infrav1.Image{
SharedGallery: &infrav1.AzureSharedGalleryImage{
SubscriptionID: params["subID"],
ResourceGroup: params["rg"],
Gallery: params["gallery"],
Name: params["name"],
Version: params["version"],
},
}
}
return infrav1.Image{}
}

func getParams(regStr, str string) (matched bool, params map[string]string) {
re := regexp.MustCompile(regStr)
match := re.FindAllStringSubmatch(str, -1)

if len(match) == 1 {
params = make(map[string]string)
for i, name := range re.SubexpNames() {
if i > 0 && i <= len(match[0]) {
params[name] = match[0][i]
}
}
matched = true
}

return matched, params
}
72 changes: 63 additions & 9 deletions azure/converters/vmss_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,8 +181,7 @@ func Test_SDKToVMSSVM(t *testing.T) {
ID: "/subscriptions/foo/resourceGroups/my_resource_group/providers/bar",
Name: "instance-000001",
Image: infrav1.Image{
ID: to.StringPtr("imageID"),
Marketplace: &infrav1.AzureMarketplaceImage{},
ID: to.StringPtr("imageID"),
},
State: "Creating",
},
Expand Down Expand Up @@ -223,28 +222,25 @@ func Test_SDKImageToImage(t *testing.T) {
Image infrav1.Image
}{
{
Name: "minimal image",
Name: "id image",
SDKImageRef: &compute.ImageReference{
ID: to.StringPtr("imageID"),
},
IsThirdParty: false,
Image: infrav1.Image{
ID: to.StringPtr("imageID"),
Marketplace: &infrav1.AzureMarketplaceImage{},
ID: to.StringPtr("imageID"),
},
},
{
Name: "marketplace image",
SDKImageRef: &compute.ImageReference{
ID: to.StringPtr("imageID"),
Publisher: to.StringPtr("publisher"),
Offer: to.StringPtr("offer"),
Sku: to.StringPtr("sku"),
Version: to.StringPtr("version"),
},
IsThirdParty: true,
Image: infrav1.Image{
ID: to.StringPtr("imageID"),
Marketplace: &infrav1.AzureMarketplaceImage{
ImagePlan: infrav1.ImagePlan{
Publisher: "publisher",
Expand All @@ -256,6 +252,65 @@ func Test_SDKImageToImage(t *testing.T) {
},
},
},
{
Name: "shared gallery image",
SDKImageRef: &compute.ImageReference{
SharedGalleryImageID: to.StringPtr("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Compute/galleries/gallery/images/image/versions/version"),
},
Image: infrav1.Image{
SharedGallery: &infrav1.AzureSharedGalleryImage{
SubscriptionID: "subscription",
ResourceGroup: "rg",
Gallery: "gallery",
Name: "image",
Version: "version",
},
},
},
{
Name: "community gallery image",
SDKImageRef: &compute.ImageReference{
CommunityGalleryImageID: to.StringPtr("/CommunityGalleries/gallery/Images/image/Versions/version"),
},
Image: infrav1.Image{
ComputeGallery: &infrav1.AzureComputeGalleryImage{
Gallery: "gallery",
Name: "image",
Version: "version",
},
},
},
{
Name: "compute gallery image",
SDKImageRef: &compute.ImageReference{
ID: to.StringPtr("/subscriptions/subscription/resourceGroups/rg/providers/Microsoft.Compute/galleries/gallery/images/image/versions/version"),
},
Image: infrav1.Image{
ComputeGallery: &infrav1.AzureComputeGalleryImage{
Gallery: "gallery",
Name: "image",
Version: "version",
SubscriptionID: to.StringPtr("subscription"),
ResourceGroup: to.StringPtr("rg"),
},
},
},
{
Name: "compute gallery image not formatted as expected",
SDKImageRef: &compute.ImageReference{
ID: to.StringPtr("/compute/gallery/not/formatted/as/expected"),
},
Image: infrav1.Image{
ID: to.StringPtr("/compute/gallery/not/formatted/as/expected"),
},
},
{
Name: "community gallery image not formatted as expected",
SDKImageRef: &compute.ImageReference{
CommunityGalleryImageID: to.StringPtr("/community/gallery/not/formatted/as/expected"),
},
Image: infrav1.Image{},
},
}

for _, c := range cases {
Expand Down Expand Up @@ -319,8 +374,7 @@ func Test_SDKVMToVMSSVM(t *testing.T) {
Expected: &azure.VMSSVM{
ID: "vmID3",
Image: infrav1.Image{
ID: to.StringPtr("imageID"),
Marketplace: &infrav1.AzureMarketplaceImage{},
ID: to.StringPtr("imageID"),
},
Name: "vmwithstorage",
State: "Creating",
Expand Down
11 changes: 11 additions & 0 deletions azure/scope/machinepoolmachine.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"k8s.io/utils/pointer"
infrav1 "sigs.k8s.io/cluster-api-provider-azure/api/v1beta1"
"sigs.k8s.io/cluster-api-provider-azure/azure"
"sigs.k8s.io/cluster-api-provider-azure/azure/converters"
infrav1exp "sigs.k8s.io/cluster-api-provider-azure/exp/api/v1beta1"
"sigs.k8s.io/cluster-api-provider-azure/util/futures"
"sigs.k8s.io/cluster-api-provider-azure/util/tele"
Expand Down Expand Up @@ -542,6 +543,16 @@ func (s *MachinePoolMachineScope) hasLatestModelApplied(ctx context.Context) (bo
return false, errors.New("machinepoolscope image must not be nil")
}

// check if image.ID is actually a compute gallery image
if s.instance.Image.ComputeGallery != nil && image.ID != nil {
newImage := converters.IDImageRefToImage(*image.ID)

// this means the ID was a compute gallery image ID
if newImage.ComputeGallery != nil {
return reflect.DeepEqual(s.instance.Image, newImage), nil
}
}

// if the images match, then the VM is of the same model
return reflect.DeepEqual(s.instance.Image, *image), nil
}
Expand Down

0 comments on commit cc7c34b

Please sign in to comment.