VMware Cloud Community
xian_
Expert
Expert

ABX - JavaScript Promise

I'm trying to use Integrated API Authentication of ABX​ from JavaScript but could not find a way to get it working in vRA 8.1

I'm trying to rewrite the following Python code, that works perfectly:

def handler(context, inputs):

    r = context.request("/deployment/api/deployments", "GET", "")

    print(r)

    return r["content"].decode("utf-8")

This lists all my deployments, so far OK.

Now with Javascript:

exports.handler = function handler(context, inputs) {

  req = context.request("/deployment/api/deployments", "GET", "");

  console.log(req);

  return {result: 0};

};

All I got is a JavaScript Promise:

Promise { <pending> }

I tried to get the result with .then() function, async function definition, await with different syntax variations without any luck. Anyone is familiar with JavaScript Promise construct or could get this simple code working?

0 Kudos
2 Replies
SteveC54
Contributor
Contributor

Hello,

So a few things to cover unfortunately here.

- context.request is not a supported feature in all scenarios (if you run your action via a Subscription, it will fail as session is not provided in that context).

- I would suggest just require'ing the http/https/url libraries yourself and making the call from scratch with credentials.

however, if you still wanted to get this to work, could you supply the context?

Assuming you are running this on_prem ?

If so, then a ".then" would work fine. See example below.

The problem here, is this is not just javascript, it is node.js which is all about asynchronous code and call backs. I believe the version that is running in vRA 8.1 though has support for Async/Await, which could make the code cleaner.

  1. exports.handler = function handler(context, inputs) {
    1.   req = context.request("/deployment/api/deployments", "GET", "");
    2.   req.then(function(response) {
    3.                console.log(response);
  2.                 return response;
  3.           });

};

0 Kudos
xian_
Expert
Expert

Hi Steve,

unfortunately your code fails without error messages. I added a few more lines to log the context itself:

exports.handler = function handler(context, inputs) { 

  req = context.request("/deployment/api/deployments", "GET", "");

  console.log(JSON.stringify(context, null, 2));

  console.log(req);

  req.then(function(response) { 

               console.log(response); 

               return response; 

          }); 

};

The output:

{

  "context": {},

  "action_trigger": "event",

  "proxy": {

    "host": "10.244.4.51",

    "port": "3128",

    "no_proxy_hosts": "docker-registry.prelude.svc.cluster.local,localhost,*.cluster.local,10.244.*,192.*,172.16.*,vra-k8s.local,kubernetes,kubernetes.default.svc.cluster.local,vra8-1.dev.local,172.16.232.151,*.dev.local"

  }

}

Promise { <pending> }

I know this is NodeJS and I was looking for the correct syntax to get the result of this async call. As I wrote I tried a couple of ways but none worked.

----

Wrt. context session:

I was testing with my ABX with simply pressing the Test button so far (that worked). So I started to test my (working Python) ABX (below) from EBS and from Service Broker and you are right: Smiley Sad

def handler(context, inputs):

    print(context.__dict__)

    r = context.request("/deployment/api/deployments", "GET", "")

    print(r)

    return r["content"].decode("utf-8")

Logs when triggered from event (context then request output 401 not authorized😞

{

  'inputs': {

    'requestType': 'BLUEPRINT',

    'catalogItemVersion': '',

    'blueprintVersion': '',

    'description': '',

    'contextId': '82c4d638-0781-43eb-8445-3da1729e6121',

    'eventType': 'CREATE_DEPLOYMENT',

    'userName': 'user1',

    'blueprintId': 'e25b6982-f6c1-4699-913b-cf3b3f83ca54',

    'orgId': '05b138db-c915-41fb-8354-284329e9e9c8',

    'catalogItemId': '',

    'deploymentId': '95f7950a-3049-44ab-8bc1-2ce99e4bc7cc',

    'requestInputs': {

      'cluster_id': 'o7'

    },

    'id': 'a1a52b9e-fcdd-4893-afee-db75a4252998',

    'projectName': 'Project1',

    '__metadata': {

      'headers': {

        'uberctx-parent-id': '2fc085d1-462f-47d0-8ee8-e4c07ce3ef7b',

        'uberctx-org-id': '05b138db-c915-41fb-8354-284329e9e9c8',

        'uber-trace-id': '9f7007c8bbee40a2bcbbaeb6ae8f6484:1fd7191848df43409033efa01350d91e:2fc085d1-462f-47d0-8ee8-e4c07ce3ef7b:0',

        'blocking': 'false',

        'runnableType': 'extensibility.abx',

        'uberctx-user-id': 'tango-blueprint-ezhPoTQFZMWG1B1Z',

        'sampling-decision': 'false',

        'eventTraceEntryId': 'd48e8738-fc34-4d6b-9e3e-5efea77b3ea2',

        'runnableId': '8a748050718767300171d19f0804012e'

      },

      'correlationType': 'Deployment',

      'eventType': 'EVENT',

      'eventTopicId': 'deployment.request.pre',

      'userName': 'user1',

      'orgId': '05b138db-c915-41fb-8354-284329e9e9c8',

      'timeStamp': 'May 4, 2020 9:21:06 PM',

      'sourceType': 'Deployment',

      'correlationId': '95f7950a-3049-44ab-8bc1-2ce99e4bc7cc',

      'sourceIdentity': 'Deployment'

    },

    'failureMessage': '',

    'projectId': '22a712bc-5c9e-4784-a55c-0b3719134190',

    'status': ''

  },

  'ctx': {

    '__server.saas.enabled': False

  },

  'callback_url': 'https://vra8.corp.local/abx/api/resources/action-runs/8a748050718767300171e191a83101d6/complete',

  'action_trigger': 'event',

  'request': <functionContext.initialize.<locals>.execute_delegateat0x7f40c1beed08>,

  'sample_method': <boundmethodsample_methodof<__main__.Contextobjectat0x7f40c3a58390>>,

  'proxy': {

    'host': '10.244.4.51',

    'port': '3128',

    'no_proxy_hosts': 'docker-registry.prelude.svc.cluster.local,localhost,*.cluster.local,10.244.*,192.*,172.16.*,vra-k8s.local,kubernetes,kubernetes.default.svc.cluster.local,vra8.corp.local,172.16.232.151,*.corp.local'

  }

}

Unable to perform proxy call because HTTP Error 401: Unauthorized.

Logs when triggered from Service Broker (as a catalog item): I can get the deployments via the API (authenticated correctly with contex.request() )

{

  'inputs': {

    '__metadata': {

     

    }

  },

  'ctx': {

    '__server.saas.enabled': False

  },

  'callback_url': 'https://vra8.corp.local/abx/api/resources/action-runs/8a748050718767300171e18cf2e901d1/complete',

  'action_trigger': 'api',

  'request': <functionContext.initialize.<locals>.execute_delegateat0x7f74807e9d08>,

  'sample_method': <boundmethodsample_methodof<__main__.Contextobjectat0x7f7482af3390>>,

  'proxy': {

    'host': '10.244.4.51',

    'port': '3128',

    'no_proxy_hosts': 'docker-registry.prelude.svc.cluster.local,localhost,*.cluster.local,10.244.*,192.*,172.16.*,vra-k8s.local,kubernetes,kubernetes.default.svc.cluster.local,vra8.corp.local,172.16.232.151,*.corp.local'

  }

}

{

  'content': b'{"content":[{"id":"cb0fb37d-96fa-4415-8372-11fa8c1a92d6","name":"h3","orgId":"05b138db-c915-41fb-8354-284329e9e9c8", ...

The reason I wanted to use context.request is I do not have to deal with credentials, as it is using the current user's credentials so I do not have to store it anywhere. I do not see a decent secret management for ABX, unfortunately.

0 Kudos