Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: use iam client library to setup test #1173

Merged
merged 11 commits into from
Jun 9, 2021
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
"fast-text-encoding": "^1.0.0",
"gaxios": "^4.0.0",
"gcp-metadata": "^4.2.0",
"google-auth-library": "^7.0.4",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If these are just being used in samples, you would need to add them to samples/package.json. There should already be a reference to google-auth-library there, since it gets linked in as part of the tests.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1.
You just need to add the additional dependency, e.g. googleapis which can probably go here:

"google-auth-library": "^7.1.0",

"googleapis": "^73.0.0",
"gtoken": "^5.0.4",
"jws": "^4.0.0",
"lru-cache": "^6.0.0"
Expand Down
105 changes: 46 additions & 59 deletions samples/scripts/externalclient-setup.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,10 @@
const fs = require('fs');
const {promisify} = require('util');
const {GoogleAuth} = require('google-auth-library');
const {google} = require('googleapis');

const readFile = promisify(fs.readFile);
const iam = google.iam('v1');
JustinBeckwith marked this conversation as resolved.
Show resolved Hide resolved

/**
* Generates a random string of the specified length, optionally using the
Expand Down Expand Up @@ -141,23 +143,15 @@ async function main(config) {
const auth = new GoogleAuth({
scopes: 'https://www.googleapis.com/auth/cloud-platform',
});

// TODO: switch to using IAM client SDK once v1 API has all the v1beta
// changes.
// https://cloud.google.com/iam/docs/reference/rest/v1beta/projects.locations.workloadIdentityPools
// https://github.com/googleapis/google-api-nodejs-client/tree/master/src/apis/iam
const authClient = await auth.getClient();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can skip this line entirely and say google.options({auth}); and it will work just the same :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

google.options({auth: authClient});

// Create the workload identity pool.
response = await auth.request({
url:
`https://iam.googleapis.com/v1beta/projects/${projectId}/` +
`locations/global/workloadIdentityPools?workloadIdentityPoolId=${poolId}`,
method: 'POST',
data: {
displayName: 'Test workload identity pool',
description: 'Test workload identity pool for Node.js',
},
response = await iam.projects.locations.workloadIdentityPools.create({
parent: `projects/${projectId}/locations/global`,
workloadIdentityPoolId: poolId,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add a display name and description: https://github.com/googleapis/google-api-nodejs-client/blob/19bd611ca69f334b342565698a8ec8991e956580/src/apis/iam/v1.ts#L2412

This makes it easy to understand who created this pool (It will also work well in the Cloud Console UI).

});

// Populate the audience field. This will be used by the tests, specifically
// the credential configuration file.
const poolResourcePath = response.data.name.split('/operations')[0];
Expand All @@ -166,12 +160,10 @@ async function main(config) {

// Allow service account impersonation.
// Get the existing IAM policity bindings on the current service account.
response = await auth.request({
url:
`https://iam.googleapis.com/v1/projects/${projectId}/` +
`serviceAccounts/${clientEmail}:getIamPolicy`,
method: 'POST',
response = await iam.projects.serviceAccounts.getIamPolicy({
resource: `projects/${projectId}/serviceAccounts/${clientEmail}`,
});

const bindings = response.data.bindings || [];
// If not found, add roles/iam.workloadIdentityUser role binding to the
// workload identity pool member.
Expand Down Expand Up @@ -203,54 +195,49 @@ async function main(config) {
],
});
}
await auth.request({
url:
`https://iam.googleapis.com/v1/projects/${projectId}/` +
`serviceAccounts/${clientEmail}:setIamPolicy`,
method: 'POST',
data: {
await iam.projects.serviceAccounts.setIamPolicy({
resource: `projects/${projectId}/serviceAccounts/${clientEmail}`,
requestBody: {
policy: {
bindings,
},
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A lot of the lint errors can be fixed by running npm run fix.
You can also see the list of errors by running npm run lint. This is useful for the errors that require manual fixing.

},
});

// Create an OIDC provider. This will use the accounts.google.com issuer URL.
// This will use the STS audience as the OIDC token audience.
await auth.request({
url:
`https://iam.googleapis.com/v1beta/projects/${projectId}/` +
`locations/global/workloadIdentityPools/${poolId}/providers?` +
`workloadIdentityPoolProviderId=${oidcProviderId}`,
method: 'POST',
data: {
displayName: 'Test OIDC provider',
description: 'Test OIDC provider for Node.js',
attributeMapping: {
'google.subject': 'assertion.sub',
},
oidc: {
issuerUri: 'https://accounts.google.com',
allowedAudiences: [oidcAudience],
},
},
});
await iam.projects.locations.workloadIdentityPools.providers.create(
{
parent: `projects/${projectId}/locations/global/workloadIdentityPools/${poolId}`,
workloadIdentityPoolProviderId: oidcProviderId,
requestBody: {
displayName: 'Test OIDC provider',
description: 'Test OIDC provider for Node.js',
attributeMapping: {
'google.subject': 'assertion.sub',
},
oidc: {
issuerUri: 'https://accounts.google.com',
allowedAudiences: [oidcAudience],
},
}
}
);

// Create an AWS provider.
await auth.request({
url:
`https://iam.googleapis.com/v1beta/projects/${projectId}/` +
`locations/global/workloadIdentityPools/${poolId}/providers?` +
`workloadIdentityPoolProviderId=${awsProviderId}`,
method: 'POST',
data: {
displayName: 'Test AWS provider',
description: 'Test AWS provider for Node.js',
aws: {
accountId: config.awsAccountId,
},
},
});
await iam.projects.locations.workloadIdentityPools.providers.create(
{
parent: `projects/${projectId}/locations/global/workloadIdentityPools/${poolId}`,
workloadIdentityPoolProviderId: awsProviderId,
requestBody: {
displayName: 'Test AWS provider',
description: 'Test AWS provider for Node.js',
aws: {
accountId: config.awsAccountId,
},
}
}
);

return {
oidcAudience,
Expand Down Expand Up @@ -292,7 +279,7 @@ main(config)
console.log(`AUDIENCE_OIDC='${audiences.oidcAudience}'`);
console.log(`AUDIENCE_AWS='${audiences.awsAudience}'`);
console.log(
`AWS_ROLE_ARN='arn:aws::iam::${config.awsAccountId}:role/${config.awsRoleName}'`
`AWS_ROLE_ARN='arn:aws:iam::${config.awsAccountId}:role/${config.awsRoleName}'`
);
})
.catch(console.error);