Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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
11 changes: 10 additions & 1 deletion cli/azd/pkg/azapi/azure_resource_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,13 @@ const (
AzureResourceTypeRoleAssignment AzureResourceType = "Microsoft.Authorization/roleAssignments"

//nolint:lll
AzureResourceTypeMachineLearningEndpoint AzureResourceType = "Microsoft.MachineLearningServices/workspaces/onlineEndpoints"
AzureResourceTypeMachineLearningEndpoint AzureResourceType = "Microsoft.MachineLearningServices/workspaces/onlineEndpoints"
//nolint:lll
AzureResourceTypeCognitiveServiceAccountDeployment AzureResourceType = "Microsoft.CognitiveServices/accounts/deployments"
//nolint:lll
AzureResourceTypeCognitiveServiceAccountProject AzureResourceType = "Microsoft.CognitiveServices/accounts/projects"
//nolint:lll
AzureResourceTypeCognitiveServiceAccountCapabilityHost AzureResourceType = "Microsoft.CognitiveServices/accounts/capabilityHosts"
)

// GetResourceTypeDisplayName retrieves the display name for the given resource type.
Expand Down Expand Up @@ -123,6 +128,10 @@ func GetResourceTypeDisplayName(resourceType AzureResourceType) string {
return "Azure AI Services"
case AzureResourceTypeCognitiveServiceAccountDeployment:
return "Azure AI Services Model Deployment"
case AzureResourceTypeCognitiveServiceAccountProject:
return "Foundry project"
case AzureResourceTypeCognitiveServiceAccountCapabilityHost:
return "Foundry capability host"
case AzureResourceTypeSearchService:
return "Search service"
case AzureResourceTypeVideoIndexer:
Expand Down
19 changes: 18 additions & 1 deletion cli/azd/pkg/infra/azure_resource_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,13 @@ func (rm *AzureResourceManager) GetResourceTypeDisplayName(
} else {
return resourceTypeDisplayName, nil
}
} else if resourceType == azapi.AzureResourceTypeCognitiveServiceAccount {
} else if resourceType == azapi.AzureResourceTypeCognitiveServiceAccount ||
resourceType == azapi.AzureResourceTypeCognitiveServiceAccountProject {
// For project resources, we can return the display name directly
if resourceType == azapi.AzureResourceTypeCognitiveServiceAccountProject {
return "Foundry project", nil
}

resourceTypeDisplayName, err := rm.getCognitiveServiceResourceTypeDisplayName(ctx, subscriptionId, resourceId)

if err != nil {
Expand Down Expand Up @@ -277,6 +283,13 @@ func (rm *AzureResourceManager) getCognitiveServiceResourceTypeDisplayName(
subscriptionId string,
resourceId string,
) (string, error) {
// Check if this is a Foundry project resource (child resource) based on path
// This handles cases where the resource type is Microsoft.CognitiveServices/accounts
// but the resource ID points to a project
if strings.Contains(resourceId, "/projects/") {
return "Foundry project", nil
}

resource, err := rm.resourceService.GetResource(ctx, subscriptionId, resourceId, cognitiveServiceApiVersion)

if err != nil {
Expand All @@ -287,6 +300,10 @@ func (rm *AzureResourceManager) getCognitiveServiceResourceTypeDisplayName(
return "Azure OpenAI", nil
} else if strings.Contains(resource.Kind, "FormRecognizer") {
return "Document Intelligence", nil
} else if strings.Contains(resource.Kind, "AIHub") {
return "Foundry", nil
} else if strings.Contains(resource.Kind, "AIServices") {
return "Foundry", nil
} else {
return "Azure AI Services", nil
}
Expand Down
135 changes: 135 additions & 0 deletions cli/azd/pkg/infra/azure_resource_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,141 @@ func TestFindResourceGroupForEnvironment(t *testing.T) {
}
}

func TestGetResourceTypeDisplayNameForCognitiveServices(t *testing.T) {
const SUBSCRIPTION_ID = "273f1e6b-6c19-4c9e-8b67-5fbe78b14063"

tests := []struct {
name string
resourceId string
resourceType azapi.AzureResourceType
kind string
expectedName string
}{
{
name: "Azure OpenAI",
resourceId: fmt.Sprintf(
"/subscriptions/%s/resourceGroups/test-rg/providers/Microsoft.CognitiveServices/accounts/test-openai",
SUBSCRIPTION_ID,
),
resourceType: azapi.AzureResourceTypeCognitiveServiceAccount,
kind: "OpenAI",
expectedName: "Azure OpenAI",
},
{
name: "Document Intelligence (FormRecognizer)",
resourceId: fmt.Sprintf(
"/subscriptions/%s/resourceGroups/test-rg/providers/"+
"Microsoft.CognitiveServices/accounts/test-formrecognizer",
SUBSCRIPTION_ID,
),
resourceType: azapi.AzureResourceTypeCognitiveServiceAccount,
kind: "FormRecognizer",
expectedName: "Document Intelligence",
},
{
name: "Foundry (AIServices)",
resourceId: fmt.Sprintf(
"/subscriptions/%s/resourceGroups/test-rg/providers/Microsoft.CognitiveServices/accounts/test-foundry",
SUBSCRIPTION_ID,
),
resourceType: azapi.AzureResourceTypeCognitiveServiceAccount,
kind: "AIServices",
expectedName: "Foundry",
},
{
name: "Foundry (AIHub)",
resourceId: fmt.Sprintf(
"/subscriptions/%s/resourceGroups/test-rg/providers/Microsoft.CognitiveServices/accounts/test-aihub",
SUBSCRIPTION_ID,
),
resourceType: azapi.AzureResourceTypeCognitiveServiceAccount,
kind: "AIHub",
expectedName: "Foundry",
},
{
name: "Foundry project (account resource type)",
resourceId: fmt.Sprintf(
"/subscriptions/%s/resourceGroups/test-rg/providers/"+
"Microsoft.CognitiveServices/accounts/test-foundry/projects/test-project",
SUBSCRIPTION_ID,
),
resourceType: azapi.AzureResourceTypeCognitiveServiceAccount,
kind: "AIServices",
expectedName: "Foundry project",
},
{
name: "Foundry project (project resource type)",
resourceId: fmt.Sprintf(
"/subscriptions/%s/resourceGroups/test-rg/providers/"+
"Microsoft.CognitiveServices/accounts/test-foundry/projects/test-project",
SUBSCRIPTION_ID,
),
resourceType: azapi.AzureResourceTypeCognitiveServiceAccountProject,
kind: "AIServices",
expectedName: "Foundry project",
},
{
name: "Azure AI Services (CognitiveServices)",
resourceId: fmt.Sprintf(
"/subscriptions/%s/resourceGroups/test-rg/providers/Microsoft.CognitiveServices/accounts/test-cogservices",
SUBSCRIPTION_ID,
),
resourceType: azapi.AzureResourceTypeCognitiveServiceAccount,
kind: "CognitiveServices",
expectedName: "Azure AI Services",
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
mockContext := mocks.NewMockContext(context.Background())
resourceService := azapi.NewResourceService(
mockContext.SubscriptionCredentialProvider,
mockContext.ArmClientOptions,
)
deploymentService := mockazapi.NewStandardDeploymentsFromMockContext(mockContext)

mockContext.HttpClient.When(func(request *http.Request) bool {
return request.Method == http.MethodGet &&
strings.Contains(request.URL.Path, "/Microsoft.CognitiveServices/accounts/")
}).RespondFn(func(request *http.Request) (*http.Response, error) {
response := map[string]interface{}{
"id": tt.resourceId,
"name": "test-resource",
"type": "Microsoft.CognitiveServices/accounts",
"location": "eastus2",
"kind": tt.kind,
}

body, err := json.Marshal(response)
if err != nil {
return nil, err
}

return &http.Response{
StatusCode: http.StatusOK,
Body: io.NopCloser(bytes.NewReader(body)),
Request: &http.Request{
Method: http.MethodGet,
URL: request.URL,
},
}, nil
})

arm := NewAzureResourceManager(resourceService, deploymentService)
displayName, err := arm.GetResourceTypeDisplayName(
*mockContext.Context,
SUBSCRIPTION_ID,
tt.resourceId,
tt.resourceType,
)

require.NoError(t, err)
require.Equal(t, tt.expectedName, displayName)
})
}
}

func TestGetResourceTypeDisplayNameForRedisEnterprise(t *testing.T) {
const SUBSCRIPTION_ID = "273f1e6b-6c19-4c9e-8b67-5fbe78b14063"

Expand Down
Loading