0

I'm writing a custom task to publish documents to the Azure API portal. I want the UI for the task to list out the available API Management services for a selected Subscription and Resource Group. According to this issue, this should technically be possible by specifying the endpointUrl inline with my datasource binding. I've tried to model the endpoint after the datasources in the Azure RM Web Deployment task, but I can't seem to get it working. In my task I am able to select my subscription, select my resource group, but the pickList for my custom data source is always empty. I'm not doing any explicit authentication in my task defintion, so I'm not sure if that's somehow related. Below are the inputs and dataSourceBindings for my task:

"inputs": [
    {
        "name": "ConnectedServiceName",
        "type": "connectedService:AzureRM",
        "label": "Azure RM Subscription",
        "defaultValue": "",
        "required": true,
        "helpMarkDown": "Select the Azure Resource Manager subscription for the deployment."
    },
    {
        "name": "ResourceGroupName",
        "label": "Resource Group",
        "type": "pickList",
        "required": true,
        "helpMarkDown": "Select resource group which contains the API portal"
    },
    {
        "name": "ApiPortalName",
        "type": "pickList",
        "label": "API Portals",
        "defaultValue": "",
        "required": true,
        "properties": {
            "EditableOptions": "True"
        },            
        "helpMarkDown": "Select the Azure Resource Manager subscription for the deployment."
    }
],
"dataSourceBindings": [
    {
        "target": "ResourceGroupName",
        "endpointId": "$(ConnectedServiceName)",
        "dataSourceName": "AzureResourceGroups"
    },
    {
      "name": "ApiPortals",
      "target": "ApiPortalName",
      "endpointId": "$(ConnectedServiceName)",
      "endpointUrl": "https://management.azure.com/subscriptions/$(endpoint.subscriptionId)/resourceGroups/$(ResourceGroupName)/providers/Microsoft.ApiManagement/service?api-version=2016-07-07",
      "resultSelector": "jsonpath:$.value[*].name",
      "parameters": {
          "ResourceGroupName": "$(ResourceGroupName)"
      }
    }

UPDATE

After inspecting the console in Chrome I received an error message indicating that I cannot call URLs that don't start with {{endpoint.url}}. I updated my task with {{endpoint.url}} at the root and I did see it attempt to make the API call I expected:

    {
      "name": "ApiPortals",
      "target": "ApiPortalName",
      "endpointId": "$(ConnectedServiceName)",
      "endpointUrl": "{{endpoint.url}}/subscriptions/$(endpoint.subscriptionId)/resourceGroups/$(ResourceGroupName)/providers/Microsoft.ApiManagement/service?api-version=2016-07-07",
      "resultSelector": "jsonpath:$.value[*].name",
      "parameters": {
          "ResourceGroupName": "$(ResourceGroupName)"
      }
    }

The problem now is that for some reason endpoint.url resolves to https://management.core.windows.net for Azure RM endpoint types. Azure RM APIs are hosted at https://management.azure.com. As a result I am receiving a 403 since my endpoint credentials are for an Azure RM Service Principal, not the Azure Classic Management APIs.

I've updated my Github Issue with this information as well. I believe this is a bug and endpoint.url for the Azure RM Service endpoint should resolve to https://management.azure.com. If you look at the data sources that are defined in the Azure RM Service Endpoint, they all reference APIs hosted at https://managemnet.azure.com not https://management.core.windows.net.

mclark1129
  • 7,532
  • 5
  • 48
  • 84
  • What does your extension.json look like? Your datasource must be defined there. – jessehouwing Jan 16 '17 at 15:25
  • Check out: https://github.com/Microsoft/vsts-tasks/issues/973 – jessehouwing Jan 16 '17 at 15:28
  • @jessehouwing Am I able to define a datasource outside of a custom service endpoint? I actually want to use the existing AzureRM subscription endpoint, but just extend it with additional datasources that don't come with it out the box. – mclark1129 Jan 16 '17 at 15:31
  • No clue. That is probably worth an issue on the `vsts-agent` repo or the `vsts-task-lib` repo. – jessehouwing Jan 16 '17 at 15:34
  • Try to capture the actual request via developer tool https://msdn.microsoft.com/en-us/library/gg130952(v=vs.85).aspx. – starian chen-MSFT Jan 17 '17 at 05:20
  • @starain-MSFT I actually have an issue open on the vsts-task repo (https://github.com/Microsoft/vsts-tasks/issues/3424) and I've updated it with request information that I am seeing. Looks to me like the problem is endpoint.url is potentially set to the classic API endpoint and not the RM endpoint. – mclark1129 Jan 17 '17 at 15:05

1 Answers1

1

Check Custom build task JSON schema, you cannot use "endpointUrl" and "resultSelector" for "dataSourceBindings" in task.json. There are used to define the custom service endpoint in vss-extension.json file. And you also missed the "dataSourceName" for "ApiPortals".

If you want to call the Rest API with URL and use the selector from task.json, you can use "sourceDefinitions" instead of "dataSourceBindings". Refer to my answer in this question for details. However, only basic authentication is supported with "sourceDefinitions" for now which means that this is not applicable to you scenario either.

So you need to create a custom service endpoint to achieve the feature you want for now.

Community
  • 1
  • 1
Eddie Chen - MSFT
  • 29,708
  • 2
  • 46
  • 60
  • @Eddie-MFST That's not entirely true. I am able to use `endpointUrl` providing the URL starts with `{{endpoint.url}}`. I've updated my question with additional information. – mclark1129 Jan 18 '17 at 16:36