Azure-sdk-for-js: Unit tests err: The user, group or application

Created on 16 Sep 2020  ·  4Comments  ·  Source: Azure/azure-sdk-for-js

  • @azure/keyvault-secrets, @azure/identity
  • Package Version:
    @azure/identity: ^1.1.0,
    @azure/keyvault-secrets: ^4.1.0

  • Operating system: Linux/Ubuntu 20

    • node version: node 14.0.1
  • [ yes] typescript

    • version: ^4.0.2

Describe the bug
I want to write some unit tests using mocha.

script to run.

~json
"test": "cross-env TS_NODE_COMPILER_OPTIONS = '{\" module \ ": \" commonjs \ "}' AZURE_KEY_VAULT_URL = \" https: //x100.vault.azure.net \ "mocha -r ts-node / register './src/tests/*/.ts' "
~

console output:
~bash
(node:41767) UnhandledPromiseRejectionWarning: RestError: The user, group or application 'appid=04b07795-8ddb-461a-bbee-02f9e1bf7b46;oid=ab496a36-ebe6-44c2-8a76-21cea6313870;numgroups=4;iss=https://sts.windows.net/b91c98b1-d543-428b-9469-f5f8f25bc37b/' does not have secrets get permission on key vault 'x100;location=northeurope'. For help resolving this issue, please see https://go.microsoft.com/fwlink/?linkid=2125287
at new RestError (/home/idontsudo/job/functions-utils/node_modules/@azure/core-http/dist/index.js:2237:28)
at /home/idontsudo/job/functions-utils/node_modules/@azure/core-http/dist/index.js:3030:25
at processTicksAndRejections (internal/process/task_queues.js:93:5)
(Use node --trace-warnings ... to show where the warning was created)
(node:41767) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag --unhandled-rejections=strict (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 5)
(node:41767) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
~

My code.

~~~javascript
import { SQLClient, SQLPool, SQLConnectionConfig, getEnv } from '../exports'; // this will be your custom import
import { expect } from 'chai';
import { ConnectionConfig } from 'tedious';

describe('Options tests', () => {
/**@problem Готовим тестовое SQL подключение;
*/

it('checking default options', async (done) => {
    let _SQL_JETTI_SM_POOL: SQLPool
    const sqlConnString = await getEnv('SQL-CONN-SM');
    const sqlConn: SQLConnectionConfig = JSON.parse(sqlConnString);
    _SQL_JETTI_SM_POOL = new SQLPool(sqlConn);
    console.log(_SQL_JETTI_SM_POOL)
    done()
});

});
~~~

I want to test code that tied to "@azure/identity", "@azure/keyvault-secrets".

In general, as I understand it, the problem is that I do not run this test through the func start command. And func start at start complements process.env part of the authorization information is taken from there. Could you help me and indicate what this information is?

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Additional context
Add any other context about the problem here.

customer-reported needs-team-attention question

Most helpful comment

PLUS+++

All 4 comments

PLUS+++

Hello! @IDONTSUDO (and @kostia7alania)

I'll be doing my best to help you.

My first guess is that this seems to be an issue with the environment variables.

With the parameters you've sent, it isn't clear to me how things are working together. I'll first write about what I don't understand from your issue, then I'll provide a next step that you can try, just in case it helps us find a quick solution, then I'll provide a code scenario that should work, so that you can try with something more narrowly defined first.

What I don't understand from the issue:

  • At least while I'm writing this, the test code you shared doesn't show how you're using neither @azure/identity nor @azure/keyvault-secrets.

This is what I'm reading:

import { SQLClient, SQLPool, SQLConnectionConfig, getEnv } from '../exports'; // this will be your custom import
import { expect } from 'chai';
import { ConnectionConfig } from 'tedious';

describe('Options tests', () => {
    /**@problem Готовим тестовое SQL подключение;
     */

    it('checking default options', async (done) => {
        let _SQL_JETTI_SM_POOL: SQLPool
        const sqlConnString = await getEnv('SQL-CONN-SM');
        const sqlConn: SQLConnectionConfig = JSON.parse(sqlConnString);
        _SQL_JETTI_SM_POOL = new SQLPool(sqlConn);
        console.log(_SQL_JETTI_SM_POOL)
        done()
    });
});

Where are you using the Azure clients? What am I missing? Any help is appreciated.

What you can try right now:

  • In your test code, before any of the tests run, echo your environment variables, with something like console.log(process.env). The idea is that you should be able to confirm that the environment variables you're sending are being received as expected.

A sample that should work:

While @azure/identity provides DefaultAzureCredential, which is a wrapper for several credentials that the Azure services have already available when one deploys, for this sample, we'll be using the EnvironmentCredential (more information can be seen here: identity#environment-variables).

The EnvironmentCredential works with Azure Active Directory (more on AAD authentication here), and requires the following environment variables to be populated:

AZURE_CLIENT_ID=<service principal's app id>
AZURE_TENANT_ID=<id of the principal's Azure Active Directory tenant>
AZURE_CLIENT_SECRET=<one of the service principal's client secrets>

Assuming we have the environment variables ready, let's write a code snippet using both @azure/identity and @azure/keyvault-secrets.

Let's copy the following code snippet in a new file, in a new folder. We can call this file index.js:

const { SecretClient } = require("@azure/keyvault-secrets");
const { EnvironmentCredential } = require("@azure/identity");

async function main() {
  const credential = new EnvironmentCredential();
  const client = new SecretClient("<keyvault-url>", credential);

  const secretName = "top-secret";
  const result = await client.setSecret(secretName, "top-secret-value");
  console.log("result: ", result);

  const secret = await client.getSecret(secretName);
  console.log("secret: ", secret);
}

main().catch((err) => {
  console.log("error code: ", err.code);
  console.log("error message: ", err.message);
  console.log("error stack: ", err.stack);
});

Make sure to specify an appropriate value for <keyvault-url>.

Once that file is created, in a new folder, make sure to add a package.json. We can do this by running npm run init in the folder where index.js is. Fill the information requested by that command as you might (it'll be fine if you just press enter all the way), then make sure to install both @azure/identity and @azure/keyvault-secrets with npm install --save @azure/identity @azure/keyvault-secrets.

Since you're in Ubuntu, you should be able to run the code above with something like the following command:

AZURE_CLIENT_ID="<service principal's app id>" \
AZURE_TENANT_ID="<id of the principal's Azure Active Directory tenant>" \
AZURE_CLIENT_SECRET="<one of the service principal's client secrets>" \
node index.js

If this fails, please apply the following change to review your environment variables:

+ console.log({
+   AZURE_CLIENT_ID: process.env.AZURE_CLIENT_ID,
+   AZURE_TENANT_ID: process.env.AZURE_TENANT_ID,
+   AZURE_CLIENT_SECRET: process.env.AZURE_CLIENT_SECRET,
+ });
async function main() {

Please do not paste your environment variable values in this issue.

It's worth noting that this previous sample shows that we should be able to read the process.env variables as expected, meaning that what we send is what we should see, independently of the rest of the script. See that we would be logging them before we even define the main function.


Does this help?

Thank you for your time! We appreciate your interest in using our clients.

I'll be ready to answer any reply.

thx!

@IDONTSUDO (and @kostia7alania), and others,

Come back anytime! We'll be here, ready to help! 👍

Was this page helpful?
0 / 5 - 0 ratings