Add example of a token with a policy to read allocs

Signed-off-by: josh <josh.timmons@hashicorp.com>
This commit is contained in:
josh
2023-06-05 21:00:29 -04:00
parent c0f49cec77
commit 2de03da519
3 changed files with 78 additions and 18 deletions
+1 -1
View File
@@ -47,4 +47,4 @@ export default async function createPlugin(
+ apiRouter.use('/nomad', await nomad(nomadEnv));
```
Note: for this backend to work, the `nomad` configuration described in the README of `@backstage/plugin-nomad` must be configured.
Note: for this backend to work, the `nomad` configuration described in the README of `@backstage/plugin-nomad` must be implemented.
+31 -15
View File
@@ -41,7 +41,7 @@ export async function createRouter(
resp.json({ status: 'ok' });
});
router.get('/v1/allocations', async (req, resp) => {
router.get('/v1/allocations', async (req, res) => {
// Check namespace argument
const namespace = (req.query.namespace as string) ?? '';
if (!namespace || namespace === '') {
@@ -53,23 +53,29 @@ export async function createRouter(
logger.debug(`request headers: namespace=${namespace} filter=${filter}`);
// Issue the request
const allocationsResp = await fetch(
`${addr}/v1/allocations?namespace=${encodeURIComponent(
namespace,
)}&filter=${encodeURIComponent(filter)}`,
{
method: 'GET',
headers: {
Accept: 'application/json',
'X-Nomad-Token': token || '',
},
const endpoint = `${addr}/v1/allocations?namespace=${encodeURIComponent(
namespace,
)}&filter=${encodeURIComponent(filter)}`;
const allocationsResp = await fetch(endpoint, {
method: 'GET',
headers: {
Accept: 'application/json',
'X-Nomad-Token': token || '',
},
);
});
// Check response
if (allocationsResp.status !== 200) {
const body = await allocationsResp.text();
logger.error(`failed to call /v1/allocations endpoint: ${body}`);
res.status(allocationsResp.status).send(body);
return;
}
// Deserialize and return
const allocationsBody = await allocationsResp.json();
logger.debug(`/v1/allocations response: ${allocationsBody}`);
resp.json(allocationsBody);
res.json(allocationsBody);
});
router.get('/v1/job/:job_id/versions', async (req, resp) => {
@@ -82,8 +88,10 @@ export async function createRouter(
// Get job ID
const jobID = (req.params.job_id as string) ?? '';
logger.info(`token: ${token}`);
// Issue the request
const versionsResp = await fetch(
const apiResp = await fetch(
`${addr}/v1/job/${jobID}/versions?namespace=${encodeURIComponent(
namespace,
)}`,
@@ -96,8 +104,16 @@ export async function createRouter(
},
);
// Check response
if (apiResp.status !== 200) {
const body = await apiResp.text();
logger.error(`failed to call /v1/job/:job_id/versions endpoint: ${body}`);
resp.status(apiResp.status).send(body);
return;
}
// Deserialize and return
const versionsBody = await versionsResp.json();
const versionsBody = await apiResp.json();
logger.debug(`/v1/job/:job_id/versions response: ${versionsBody}`);
resp.json(versionsBody);
});
+46 -2
View File
@@ -12,7 +12,7 @@ This plugin has a corresponding backend plugin required to call the Nomad cluste
### Features
At the time of writing, this plugin provides two components:
This plugin provides two components:
- a table to view recent [job versions](https://developer.hashicorp.com/nomad/docs/commands/job/history)
- a table to view [allocations for a job and/or group](https://developer.hashicorp.com/nomad/tutorials/manage-jobs/jobs-inspect)
@@ -25,7 +25,7 @@ You will need to have the backend Nomad plugin, `@backstage/plugin-nomad-backend
You will need a running Nomad cluster with an API address that is reachable from the `@backstage/plugin-nomad/backend` plugin [running in the back end](https://backstage.io/docs/overview/architecture-overview/#third-party-backed-plugins). You can follow [this tutorial](https://developer.hashicorp.com/nomad/tutorials/enterprise/production-deployment-guide-vm-with-consul) to learn how to deploy one.
If your Nomad cluster has ACLs enabled, you will need a `token` with at least [`list-jobs` and `read-jobs` capabilities](https://developer.hashicorp.com/nomad/tutorials/access-control/access-control-policies#namespace-rules). You can check [this tutorial](https://developer.hashicorp.com/nomad/tutorials/access-control/access-control-create-policy) for more info.
If your Nomad cluster has ACLs enabled, you will need a `token` with at least the [`list-jobs`capability](https://developer.hashicorp.com/nomad/tutorials/access-control/access-control-policies#namespace-rules). You can check [this tutorial](https://developer.hashicorp.com/nomad/tutorials/access-control/access-control-create-policy) for more info or the minimal [example below](#example-policy).
### Installation
@@ -121,3 +121,47 @@ const serviceEntityPage = (
#### Requirements
- `nomad.io/job-id` and/or `nomad.io/group` annotations must be set
## ACL Policy Example
Because this plugin uses API endpoints that require the `list-jobs` capability, the token you provide to the plugin's [`nomad` configuration](#configuration) needs at least that.
To create such a token you can create a policy like below. This policy applies to all namespaces:
```hcl
# backstage.policy.hcl
namespace "*" {
policy = "read"
}
node {
policy = "read"
}
```
And create a policy for it:
```bash
nomad acl policy apply backstage backstage.policy.hcl
```
Then create a client token for it:
```bash
nomad acl token create -name=backstage -policy=backstage
Accessor ID = 5e9fe97b-76c5-8803-21b8-083308dc6c11
Secret ID = 93e034ad-e504-42f9-129d-5d81be9f13d3
Name = backstage
Type = client
Global = false
Create Time = 2023-06-05 00:45:20.51905 +0000 UTC
Expiry Time = <none>
Create Index = 54
Modify Index = 54
Policies = [backstage]
Roles
<none>
```
In the example above, the `Secret ID` is the `token` to use in the [configuration](#configuration).