Skip to content

Commit

Permalink
azure/provider.go: use Azure SDK to get ConfigMap params
Browse files Browse the repository at this point in the history
Using the Azure SDK, we don't need to provide AZURE_IMAGE_ID,
AZURE_SUBNET_ID and AZURE_NSG_ID to the ConfigMap.

If each query returns more than a result, return an error and let
the user specify the actual value needed in the ConfigMap.

Fixes: #1200

Signed-off-by: Emanuele Giuseppe Esposito <[email protected]>
  • Loading branch information
esposem committed Aug 29, 2023
1 parent 60fb3b0 commit 0737244
Show file tree
Hide file tree
Showing 2 changed files with 211 additions and 5 deletions.
6 changes: 3 additions & 3 deletions entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,13 @@ aws() {
}

azure() {
test_vars AZURE_CLIENT_ID AZURE_TENANT_ID AZURE_SUBSCRIPTION_ID AZURE_RESOURCE_GROUP AZURE_SUBNET_ID AZURE_IMAGE_ID
test_vars AZURE_CLIENT_ID AZURE_TENANT_ID AZURE_SUBSCRIPTION_ID AZURE_RESOURCE_GROUP AZURE_IMAGE_ID

[[ "${SSH_USERNAME}" ]] && optionals+="-ssh-username ${SSH_USERNAME} "
[[ "${DISABLECVM}" ]] && optionals+="-disable-cvm "
[[ "${AZURE_INSTANCE_SIZES}" ]] && optionals+="-instance-sizes ${AZURE_INSTANCE_SIZES} "
[[ "${AZURE_SUBNET_ID}" ]] && optionals+="-subnetid ${AZURE_SUBNET_ID} "
[[ "${AZURE_NSG_ID}" ]] && optionals+="-securitygroupid ${AZURE_NSG_ID} "
[[ "${TAGS}" ]] && optionals+="-tags ${TAGS} " # Custom tags applied to pod vm

set -x
Expand All @@ -67,8 +69,6 @@ azure() {
-instance-size "${AZURE_INSTANCE_SIZE}" \
-resourcegroup "${AZURE_RESOURCE_GROUP}" \
-vxlan-port 8472 \
-subnetid "${AZURE_SUBNET_ID}" \
-securitygroupid "${AZURE_NSG_ID}" \
-imageid "${AZURE_IMAGE_ID}" \
${optionals}
}
Expand Down
210 changes: 208 additions & 2 deletions pkg/adaptor/cloud/azure/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"github.com/Azure/azure-sdk-for-go/sdk/azcore/to"
armcompute "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2"
"github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources"
"github.com/avast/retry-go/v4"
"github.com/confidential-containers/cloud-api-adaptor/pkg/adaptor/cloud"
"github.com/confidential-containers/cloud-api-adaptor/pkg/util"
Expand All @@ -38,10 +39,38 @@ type azureProvider struct {
serviceConfig *Config
}

func NewProvider(config *Config) (cloud.Provider, error) {
// TODO: Add support for managed K8s - AKS and ARO
// AKS and ARO creates a separate resource group for the cluster resources and current code needs to be adapted to handle retrieving the cluster resource group and related settings
func (p *azureProvider) fetchConfigMapValues() error {
config := p.serviceConfig

logger.Printf("azure config %+v", config.Redact())
if config.ResourceGroupName == "" {
err := p.GetResourceGroup()
if err != nil {
return fmt.Errorf("getting ResourceGroup from azure: %w", err)
}
}

if config.SecurityGroupId == "" {
err := p.GetNSG(config.ResourceGroupName)
if err != nil {
return fmt.Errorf("getting NSG_ID from azure: %w", err)
}
}

if config.SubnetId == "" {
err := p.GetVirtualNetwork(config.ResourceGroupName)
if err != nil {
return fmt.Errorf("getting SubnetID from azure: %w", err)
}
}

return nil
}

func NewProvider(config *Config) (cloud.Provider, error) {

// Requires config.TenantId, config.ClientId and config.ClientSecret to be set
azureClient, err := NewAzureClient(*config)
if err != nil {
logger.Printf("creating azure client: %v", err)
Expand All @@ -53,6 +82,15 @@ func NewProvider(config *Config) (cloud.Provider, error) {
serviceConfig: config,
}

// Uses Azure sdk to get config.ResourceGroupName, config.SecurityGroupId,
// config.ImageId and config.SubnetId
if err = provider.fetchConfigMapValues(); err != nil {
return nil, err
}

logger.Printf("azure config %+v", config.Redact())

// Uses Azure sdk to get config.InstanceTypeSpecList
if err = provider.updateInstanceSizeSpecList(); err != nil {
return nil, err
}
Expand Down Expand Up @@ -450,3 +488,171 @@ func (p *azureProvider) updateInstanceSizeSpecList() error {
logger.Printf("instanceSizeSpecList (%v)", p.serviceConfig.InstanceSizeSpecList)
return nil
}

func _from_user_rg(managedby string, userrg string) bool {
parts := strings.Split(managedby, "/")
if len(parts) > 5 && parts[3] == "resourceGroups" {
return parts[4] == userrg
}
return false
}

func (p *azureProvider) GetResourceGroup() error {

resourcesClientFactory, err := armresources.NewClientFactory(p.serviceConfig.SubscriptionId, p.azureClient, nil)
if err != nil {
return fmt.Errorf("creating resource client factory:%w", err)
}

rgClient := resourcesClientFactory.NewResourceGroupsClient()
pager := rgClient.NewListPager(nil)
found := 0

for pager.More() {
nextResult, err := pager.NextPage(context.Background())
if err != nil {
return fmt.Errorf("getting ResourceGroup NextPage: %w", err)
}
if nextResult.ResourceGroupListResult.Value != nil {
for _, ResourceGroup := range nextResult.ResourceGroupListResult.Value {
if ResourceGroup.ManagedBy != nil {
rg_matches := _from_user_rg(*ResourceGroup.ManagedBy, p.serviceConfig.ResourceGroupName)
if rg_matches {
logger.Printf("ResourceGroup found: %v", (*ResourceGroup.Name))
if found == 0 {
p.serviceConfig.ResourceGroupName = *ResourceGroup.Name
logger.Printf("Using ResourceGroup %v", (*ResourceGroup.Name))
}
found++
}
}
}
}
}

if found > 1 {
logger.Printf("[warning] more than a ResourceGroup found! Defaulting to %v", p.serviceConfig.ResourceGroupName)
}

if found == 0 {
return fmt.Errorf("no ResourceGroup found! Please provide it manually with AZURE_RESOURCE_GROUP")
}

return nil
}

func (p *azureProvider) GetVirtualNetwork(resourceGroupName string) error {

virtualNetworksClient, err := armnetwork.NewVirtualNetworksClient(p.serviceConfig.SubscriptionId, p.azureClient, nil)
if err != nil {
return fmt.Errorf("getting virtualNetworksClient: %w", err)
}

found := 0
virtnet := ""

virtualNetworksClientNewListPager := virtualNetworksClient.NewListPager(resourceGroupName, nil)
for virtualNetworksClientNewListPager.More() {
nextResult, err := virtualNetworksClientNewListPager.NextPage(context.Background())
if err != nil {
return fmt.Errorf("getting virtual networks NextPage: %w", err)
}
if nextResult.VirtualNetworkListResult.Value != nil {
for _, VirtualNetwork := range nextResult.VirtualNetworkListResult.Value {
logger.Printf("Virtual network found: %v", *VirtualNetwork.Name)
if found == 0 {
virtnet = *VirtualNetwork.Name
logger.Printf("Using Virtual network %v", virtnet)
}
found++
}
}
}

if found > 1 {
logger.Printf("[warning] more than a Virtual network found! Defaulting to %v", virtnet)
}

if found == 0 {
return fmt.Errorf("no Virtual network found in ResourceGroup %v", resourceGroupName)
}

return p.GetSubnetID(resourceGroupName, virtnet)
}

func (p *azureProvider) GetSubnetID(resourceGroupName string, virtualNetworkName string) error {

subnetsClient, err := armnetwork.NewSubnetsClient(p.serviceConfig.SubscriptionId, p.azureClient, nil)
if err != nil {
return fmt.Errorf("getting NewSubnetsClient: %w", err)
}

found := 0

subnetsClientNewListPager := subnetsClient.NewListPager(resourceGroupName, virtualNetworkName, nil)
for subnetsClientNewListPager.More() {
nextResult, err := subnetsClientNewListPager.NextPage(context.Background())
if err != nil {
return fmt.Errorf("getting subnets NextPage: %w", err)
}
if nextResult.SubnetListResult.Value != nil {
for _, Subnet := range nextResult.SubnetListResult.Value {
logger.Printf("Subnet found: %v", *Subnet.Name)
if found == 0 {
p.serviceConfig.SubnetId = *Subnet.ID
logger.Printf("Using Subnet ID %v", *Subnet.ID)
}
found++
}

}
}

if found > 1 {
logger.Printf("[warning] more than a Subnet ID found for Virtual network %v! Defaulting to %v", virtualNetworkName, p.serviceConfig.SubnetId)
}

if found == 0 {
return fmt.Errorf("no Subnet ID found in Virtual network %v! Please provide it manually with AZURE_SUBNET_ID", virtualNetworkName)
}

return nil
}

func (p *azureProvider) GetNSG(resourceGroupName string) error {

securityGroupsClient, err := armnetwork.NewSecurityGroupsClient(p.serviceConfig.SubscriptionId, p.azureClient, nil)
if err != nil {
return fmt.Errorf("getting NewSecurityGroupsClient: %w", err)
}

found := 0

securityGroupsClientNewListPager := securityGroupsClient.NewListPager(resourceGroupName, nil)
for securityGroupsClientNewListPager.More() {
nextResult, err := securityGroupsClientNewListPager.NextPage(context.Background())
if err != nil {
return fmt.Errorf("getting NSG NextPage: %w", err)
}
if nextResult.SecurityGroupListResult.Value != nil {
for _, SecurityGroup := range nextResult.SecurityGroupListResult.Value {
logger.Printf("NSG found: %v", *SecurityGroup.ID)
if found == 0 {
p.serviceConfig.SecurityGroupId = *SecurityGroup.ID
logger.Printf("Using NSG %v", *SecurityGroup.ID)
}
found++
}
}
}

if found > 1 {
logger.Printf("[warning] more than a NSG found! Defaulting to %v", p.serviceConfig.SecurityGroupId)
}

if found == 0 {
return fmt.Errorf("no NSG found in ResourceGroup %v! Please provide it manually with AZURE_NSG_ID", resourceGroupName)
}

return nil
}

0 comments on commit 0737244

Please sign in to comment.