import Adapter from './application'; import { inject as service } from '@ember/service'; import { SLUG_KEY } from 'consul-ui/models/token'; import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc'; import { NSPACE_KEY } from 'consul-ui/models/nspace'; import { env } from 'consul-ui/env'; import nonEmptySet from 'consul-ui/utils/non-empty-set'; let Namespace; if (env('CONSUL_NSPACES_ENABLED')) { Namespace = nonEmptySet('Namespace'); } else { Namespace = () => ({}); } // TODO: Update to use this.formatDatacenter() export default class TokenAdapter extends Adapter { @service('store') store; requestForQuery(request, { dc, ns, index, role, policy }) { return request` GET /v1/acl/tokens?${{ role, policy, dc }} ${{ ...this.formatNspace(ns), index, }} `; } requestForQueryRecord(request, { dc, ns, index, id }) { if (typeof id === 'undefined') { throw new Error('You must specify an id'); } return request` GET /v1/acl/token/${id}?${{ dc }} ${{ ...this.formatNspace(ns), index, }} `; } requestForCreateRecord(request, serialized, data) { const params = { ...this.formatDatacenter(data[DATACENTER_KEY]), }; return request` PUT /v1/acl/token?${params} ${{ Description: serialized.Description, Policies: serialized.Policies, Roles: serialized.Roles, ServiceIdentities: serialized.ServiceIdentities, NodeIdentities: serialized.NodeIdentities, Local: serialized.Local, ...Namespace(serialized.Namespace), }} `; } requestForUpdateRecord(request, serialized, data) { // TODO: here we check data['Rules'] not serialized['Rules'] data.Rules is // not undefined, and serialized.Rules is not null revisit this at some // point we should probably use serialized here // If a token has Rules, use the old API if (typeof data['Rules'] !== 'undefined') { // https://www.consul.io/api/acl/legacy.html#update-acl-token // as we are using the old API we don't need to specify a nspace return request` PUT /v1/acl/update?${this.formatDatacenter(data[DATACENTER_KEY])} ${serialized} `; } const params = { ...this.formatDatacenter(data[DATACENTER_KEY]), }; return request` PUT /v1/acl/token/${data[SLUG_KEY]}?${params} ${{ Description: serialized.Description, Policies: serialized.Policies, Roles: serialized.Roles, ServiceIdentities: serialized.ServiceIdentities, NodeIdentities: serialized.NodeIdentities, Local: serialized.Local, ...Namespace(serialized.Namespace), }} `; } requestForDeleteRecord(request, serialized, data) { const params = { ...this.formatDatacenter(data[DATACENTER_KEY]), ...this.formatNspace(data[NSPACE_KEY]), }; return request` DELETE /v1/acl/token/${data[SLUG_KEY]}?${params} `; } requestForSelf(request, serialized, { dc, index, secret }) { // TODO: Change here and elsewhere to use Authorization Bearer Token // https://github.com/hashicorp/consul/pull/4502 return request` GET /v1/acl/token/self?${{ dc }} X-Consul-Token: ${secret} Cache-Control: no-store ${{ index }} `; } requestForCloneRecord(request, serialized, data) { // this uses snapshots const id = data[SLUG_KEY]; if (typeof id === 'undefined') { throw new Error('You must specify an id'); } const params = { ...this.formatDatacenter(data[DATACENTER_KEY]), ...this.formatNspace(data[NSPACE_KEY]), }; return request` PUT /v1/acl/token/${id}/clone?${params} `; } // TODO: self doesn't get passed a snapshot right now ideally it would just // for consistency thing is its probably not the same shape as a // 'Token', plus we can't create Snapshots as they are private, see // services/store.js self(store, type, id, unserialized) { return this.rpc( function(adapter, request, serialized, data) { return adapter.requestForSelf(request, serialized, data); }, function(serializer, respond, serialized, data) { return serializer.respondForSelf(respond, serialized, data); }, unserialized, type.modelName ); } clone(store, type, id, snapshot) { return this.rpc( function(adapter, request, serialized, data) { return adapter.requestForCloneRecord(request, serialized, data); }, (serializer, respond, serialized, data) => { // here we just have to pass through the dc (like when querying) // eventually the id is created with this dc value and the id taken from the // json response of `acls/token/*/clone` const params = { ...this.formatDatacenter(data[DATACENTER_KEY]), ...this.formatNspace(data[NSPACE_KEY]), }; return serializer.respondForQueryRecord(respond, params); }, snapshot, type.modelName ); } }