ui: Support for Node Identities (#8137)
* Add all the new data required for NodeIdentities * Add potential NodeIdentity to the token list component * Amend the policy-form/selector to allow node identity creation * Fix up CSS for radio buttons and select label * Add node-identity policy template component * Fix up and add acceptance tests for NodeIndentities * Make sure policy previews take node identities into account * Only show certain policy markup if those we have those policies * Potentially temporarily hide dt's that don't have icons yet
This commit is contained in:
parent
146afbe9a2
commit
c5d0216939
|
@ -50,6 +50,7 @@ export default Adapter.extend({
|
|||
Description: serialized.Description,
|
||||
Policies: serialized.Policies,
|
||||
ServiceIdentities: serialized.ServiceIdentities,
|
||||
NodeIdentities: serialized.NodeIdentities,
|
||||
...Namespace(serialized.Namespace),
|
||||
}}
|
||||
`;
|
||||
|
@ -66,6 +67,7 @@ export default Adapter.extend({
|
|||
Description: serialized.Description,
|
||||
Policies: serialized.Policies,
|
||||
ServiceIdentities: serialized.ServiceIdentities,
|
||||
NodeIdentities: serialized.NodeIdentities,
|
||||
...Namespace(serialized.Namespace),
|
||||
}}
|
||||
`;
|
||||
|
|
|
@ -53,6 +53,7 @@ export default Adapter.extend({
|
|||
Policies: serialized.Policies,
|
||||
Roles: serialized.Roles,
|
||||
ServiceIdentities: serialized.ServiceIdentities,
|
||||
NodeIdentities: serialized.NodeIdentities,
|
||||
Local: serialized.Local,
|
||||
...Namespace(serialized.Namespace),
|
||||
}}
|
||||
|
@ -84,6 +85,7 @@ export default Adapter.extend({
|
|||
Policies: serialized.Policies,
|
||||
Roles: serialized.Roles,
|
||||
ServiceIdentities: serialized.ServiceIdentities,
|
||||
NodeIdentities: serialized.NodeIdentities,
|
||||
Local: serialized.Local,
|
||||
...Namespace(serialized.Namespace),
|
||||
}}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<div role="group">
|
||||
<fieldset>
|
||||
<h2>Source</h2>
|
||||
<label data-test-source-element class="type-text{{if _item.error.SourceName ' has-error'}}">
|
||||
<label data-test-source-element class="type-select{{if _item.error.SourceName ' has-error'}}">
|
||||
<span>Source Service</span>
|
||||
<PowerSelectWithCreate
|
||||
@options={{_services}}
|
||||
|
@ -23,7 +23,7 @@
|
|||
<em>Search for an existing service, or enter any Service name.</em>
|
||||
</label>
|
||||
{{#if (env 'CONSUL_NSPACES_ENABLED')}}
|
||||
<label data-test-source-nspace class="type-text{{if _item.error.SourceNS ' has-error'}}">
|
||||
<label data-test-source-nspace class="type-select{{if _item.error.SourceNS ' has-error'}}">
|
||||
<span>Source Namespace</span>
|
||||
<PowerSelectWithCreate
|
||||
@options={{_nspaces}}
|
||||
|
@ -46,7 +46,7 @@
|
|||
</fieldset>
|
||||
<fieldset>
|
||||
<h2>Destination</h2>
|
||||
<label data-test-destination-element class="type-text{{if _item.error.DestinationName ' has-error'}}">
|
||||
<label data-test-destination-element class="type-select{{if _item.error.DestinationName ' has-error'}}">
|
||||
<span>Destination Service</span>
|
||||
<PowerSelectWithCreate
|
||||
@options={{_services}}
|
||||
|
@ -66,7 +66,7 @@
|
|||
<em>Search for an existing service, or enter any Service name.</em>
|
||||
</label>
|
||||
{{#if (env 'CONSUL_NSPACES_ENABLED')}}
|
||||
<label data-test-destination-nspace class="type-text{{if _item.error.DestinationNS ' has-error'}}">
|
||||
<label data-test-destination-nspace class="type-select{{if _item.error.DestinationNS ' has-error'}}">
|
||||
<span>Destination Namespace</span>
|
||||
<PowerSelectWithCreate
|
||||
@options={{_nspaces}}
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
</dd>
|
||||
</dl>
|
||||
{{/if}}
|
||||
<a href={{href-to 'dc.acls.tokens.edit' item.AccessorID}}>{{substr item.AccessorID -8}}</a>
|
||||
<a href={{href-to 'dc.acls.tokens.edit' item.AccessorID}}>{{substr item.AccessorID -8}}</a>
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="details">
|
||||
<dl>
|
||||
|
@ -23,7 +23,9 @@
|
|||
{{#let (get policies 'management') as |management|}}
|
||||
{{#if (gt management.length 0)}}
|
||||
<dl>
|
||||
<dt>Management</dt>
|
||||
<dt>
|
||||
Management
|
||||
</dt>
|
||||
<dd>
|
||||
{{#each (get policies 'management') as |item|}}
|
||||
<span data-test-policy class={{policy/typeof item}}>{{item.Name}}</span>
|
||||
|
@ -32,26 +34,34 @@
|
|||
</dl>
|
||||
{{/if}}
|
||||
{{/let}}
|
||||
{{#let (get policies 'identities') as |identities|}}
|
||||
{{#if (gt identities.length 0)}}
|
||||
<dl>
|
||||
<dt>Identities</dt>
|
||||
<dd>
|
||||
{{#each (append (get policies 'identities')) as |item|}}
|
||||
<span data-test-policy class={{policy/typeof item}}>Service Identity: {{item.Name}}</span>
|
||||
{{#each identities as |item|}}
|
||||
<span data-test-policy class={{policy/typeof item}}>{{if (eq item.template 'service-identity') 'Service' 'Node'}} Identity: {{item.Name}}</span>
|
||||
{{/each}}
|
||||
</dd>
|
||||
</dl>
|
||||
{{/if}}
|
||||
{{/let}}
|
||||
{{#let (append (get policies 'policies') item.Roles) as |policies|}}
|
||||
{{#if (gt policies.length 0)}}
|
||||
<dl>
|
||||
<dt>Rules</dt>
|
||||
<dd>
|
||||
{{#if (token/is-legacy item) }}
|
||||
Legacy tokens have embedded rules.
|
||||
{{ else }}
|
||||
{{#each (append (get policies 'policies') item.Roles) as |item|}}
|
||||
{{#each policies as |item|}}
|
||||
<span data-test-policy class={{policy/typeof item}}>{{item.Name}}</span>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
</dd>
|
||||
</dl>
|
||||
{{/if}}
|
||||
{{/let}}
|
||||
{{/let}}
|
||||
<dl>
|
||||
<dt>Description</dt>
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
node "{{name}}" {
|
||||
policy = "write"
|
||||
}
|
||||
service_prefix "" {
|
||||
policy = "read"
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend({
|
||||
tagName: '',
|
||||
});
|
|
@ -3,11 +3,11 @@
|
|||
{{#yield-slot name='template'}}
|
||||
{{else}}
|
||||
<header>
|
||||
Policy{{if allowServiceIdentity ' or service identity?' ''}}
|
||||
Policy{{if allowIdentity ' or identity?' ''}}
|
||||
</header>
|
||||
{{#if allowServiceIdentity}}
|
||||
{{#if allowIdentity}}
|
||||
<p>
|
||||
A Service Identity is default policy with a configurable service name. This saves you some time and effort you're using Consul for Connect features.
|
||||
Identities are default policies with configurable names. They save you some time and effort you're using Consul for Connect features.
|
||||
</p>
|
||||
{{! this should use radio-group }}
|
||||
<div role="radiogroup" class={{if item.error.Type ' has-error'}}>
|
||||
|
@ -34,17 +34,38 @@
|
|||
</label>
|
||||
<label class="type-text" data-test-rules>
|
||||
<span>Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a></span>
|
||||
{{#if (eq item.template '') }}
|
||||
{{#if (eq item.template 'service-identity')}}
|
||||
<CodeEditor @readonly={{true}} @name={{concat name "[Rules]"}} @syntax="hcl" @oninput={{action "change" (concat name "[Rules]")}}>
|
||||
{{~component 'service-identity' name=item.Name~}}
|
||||
</CodeEditor>
|
||||
{{else if (eq item.template 'node-identity')}}
|
||||
<CodeEditor @readonly={{true}} @name={{concat name "[Rules]"}} @syntax="hcl" @oninput={{action "change" (concat name "[Rules]")}}>
|
||||
{{~component 'node-identity' name=item.Name~}}
|
||||
</CodeEditor>
|
||||
{{else}}
|
||||
<CodeEditor @syntax="hcl" @class={{if item.error.Rules "error"}} @name={{concat name "[Rules]"}} @value={{item.Rules}} @onkeyup={{action "change" (concat name "[Rules]")}} />
|
||||
{{#if item.error.Rules}}
|
||||
<strong>{{item.error.Rules.validation}}</strong>
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<CodeEditor @readonly={{true}} @name={{concat name "[Rules]"}} @syntax="hcl" @oninput={{action "change" (concat name "[Rules]")}}>
|
||||
{{~component 'service-identity' name=item.Name~}}
|
||||
</CodeEditor>
|
||||
{{/if}}
|
||||
</label>
|
||||
{{#if (eq item.template 'node-identity')}}
|
||||
|
||||
<DataSource @src="/*/*/datacenters"
|
||||
@onchange={{action (mut datacenters) value="data"}}
|
||||
/>
|
||||
<label class="type-select" data-test-datacenter>
|
||||
<span>Datacenter</span>
|
||||
<PowerSelect
|
||||
@options={{map-by 'Name' datacenters}}
|
||||
@searchField="Name"
|
||||
@selected={{or item.Datacenter dc}}
|
||||
@searchPlaceholder="Type a datacenter name"
|
||||
@onChange={{action "change" "Datacenter"}} as |Name|>
|
||||
{{Name}}
|
||||
</PowerSelect>
|
||||
</label>
|
||||
{{else}}
|
||||
<div class="type-toggle">
|
||||
<span>Valid datacenters</span>
|
||||
<label>
|
||||
|
@ -52,10 +73,11 @@
|
|||
<span>All</span>
|
||||
</label>
|
||||
</div>
|
||||
{{#if isScoped }}
|
||||
{{#if isScoped }}
|
||||
<DataSource @src="/*/*/datacenters"
|
||||
@onchange={{action (mut datacenters) value="data"}}
|
||||
/>
|
||||
|
||||
<div class="checkbox-group" role="group">
|
||||
{{#each datacenters as |dc| }}
|
||||
<label class="type-checkbox">
|
||||
|
@ -72,6 +94,9 @@
|
|||
{{/if}}
|
||||
{{/each}}
|
||||
</div>
|
||||
|
||||
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
{{#if (eq item.template '') }}
|
||||
<label class="type-text">
|
||||
|
|
|
@ -4,7 +4,7 @@ import { get, set } from '@ember/object';
|
|||
export default FormComponent.extend({
|
||||
type: 'policy',
|
||||
name: 'policy',
|
||||
allowServiceIdentity: true,
|
||||
allowIdentity: true,
|
||||
classNames: ['policy-form'],
|
||||
|
||||
isScoped: false,
|
||||
|
@ -20,6 +20,10 @@ export default FormComponent.extend({
|
|||
name: 'Service Identity',
|
||||
template: 'service-identity',
|
||||
},
|
||||
{
|
||||
name: 'Node Identity',
|
||||
template: 'node-identity',
|
||||
},
|
||||
];
|
||||
},
|
||||
actions: {
|
||||
|
|
|
@ -8,7 +8,7 @@ export default (submitable, cancelable, radiogroup, text) => (
|
|||
prefix: 'policy',
|
||||
...submitable(),
|
||||
...cancelable(),
|
||||
...radiogroup('template', ['', 'service-identity'], 'policy'),
|
||||
...radiogroup('template', ['', 'service-identity', 'node-identity'], 'policy'),
|
||||
rules: {
|
||||
error: text('[data-test-rules] strong'),
|
||||
},
|
||||
|
|
|
@ -50,35 +50,48 @@
|
|||
<BlockSlot @name="row">
|
||||
<td class={{policy/typeof item}}>
|
||||
{{#if item.ID }}
|
||||
<a href={{href-to 'dc.acls.policies.edit' item.ID}}>{{item.Name}}</a>
|
||||
<a href={{href-to 'dc.acls.policies.edit' item.ID}}>{{item.Name}}</a>
|
||||
{{else}}
|
||||
<a name={{item.Name}}>{{item.Name}}</a>
|
||||
{{/if}}
|
||||
</td>
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="details">
|
||||
{{#if (eq item.template '')}}
|
||||
<DataSource
|
||||
@src={{concat '/' item.Namespace '/' dc '/policy/' item.ID}}
|
||||
@onchange={{action (mut loadedItem) value="data"}}
|
||||
@loading="lazy"
|
||||
/>
|
||||
{{/if}}
|
||||
{{#if (eq item.template '')}}
|
||||
<DataSource
|
||||
@src={{concat '/' item.Namespace '/' dc '/policy/' item.ID}}
|
||||
@onchange={{action (mut loadedItem) value="data"}}
|
||||
@loading="lazy"
|
||||
/>
|
||||
{{/if}}
|
||||
{{#if (eq item.template 'node-identity')}}
|
||||
<dl>
|
||||
<dt>Datacenter:</dt>
|
||||
<dd>
|
||||
{{item.Datacenter}}
|
||||
</dd>
|
||||
</dl>
|
||||
{{else}}
|
||||
<dl>
|
||||
<dt>Datacenters:</dt>
|
||||
<dd>
|
||||
{{join ', ' (policy/datacenters (or loadedItem item))}}
|
||||
</dd>
|
||||
</dl>
|
||||
{{/if}}
|
||||
<label class="type-text">
|
||||
<span>Rules <a href="{{env 'CONSUL_DOCS_URL'}}/guides/acl.html#rule-specification" rel="help noopener noreferrer" target="_blank">(HCL Format)</a></span>
|
||||
{{#if (eq item.template '')}}
|
||||
<CodeEditor @syntax="hcl" @readonly={{true}} @value={{or loadedItem.Rules item.Rules}} />
|
||||
{{else}}
|
||||
<CodeEditor @syntax="hcl" @readonly={{true}}>
|
||||
{{~component 'service-identity' name=item.Name~}}
|
||||
</CodeEditor>
|
||||
{{/if}}
|
||||
{{#if (eq item.template 'service-identity')}}
|
||||
<CodeEditor @syntax="hcl" @readonly={{true}}>
|
||||
{{~component 'service-identity' name=item.Name~}}
|
||||
</CodeEditor>
|
||||
{{else if (eq item.template 'node-identity')}}
|
||||
<CodeEditor @syntax="hcl" @readonly={{true}}>
|
||||
{{~component 'node-identity' name=item.Name~}}
|
||||
</CodeEditor>
|
||||
{{else}}
|
||||
<CodeEditor @syntax="hcl" @readonly={{true}} @value={{or loadedItem.Rules item.Rules}} />
|
||||
{{/if}}
|
||||
</label>
|
||||
<div>
|
||||
<ConfirmationDialog @message="Are you sure you want to remove this policy from this token?">
|
||||
|
|
|
@ -10,7 +10,7 @@ export default ChildSelectorComponent.extend({
|
|||
repo: service('repository/policy/component'),
|
||||
name: 'policy',
|
||||
type: 'policy',
|
||||
allowServiceIdentity: true,
|
||||
allowIdentity: true,
|
||||
classNames: ['policy-selector'],
|
||||
init: function() {
|
||||
this._super(...arguments);
|
||||
|
|
|
@ -3,14 +3,14 @@ import { get } from '@ember/object';
|
|||
|
||||
import minimizeModel from 'consul-ui/utils/minimizeModel';
|
||||
|
||||
const normalizeServiceIdentities = function(items) {
|
||||
const normalizeIdentities = function(items, template, name, dc) {
|
||||
return (items || []).map(function(item) {
|
||||
const policy = {
|
||||
template: 'service-identity',
|
||||
Name: item.ServiceName,
|
||||
template: template,
|
||||
Name: item[name],
|
||||
};
|
||||
if (typeof item.Datacenters !== 'undefined') {
|
||||
policy.Datacenters = item.Datacenters;
|
||||
if (typeof item[dc] !== 'undefined') {
|
||||
policy[dc] = item[dc];
|
||||
}
|
||||
return policy;
|
||||
});
|
||||
|
@ -25,17 +25,17 @@ const normalizePolicies = function(items) {
|
|||
};
|
||||
});
|
||||
};
|
||||
const serializeServiceIdentities = function(items) {
|
||||
const serializeIdentities = function(items, template, name, dc) {
|
||||
return items
|
||||
.filter(function(item) {
|
||||
return get(item, 'template') === 'service-identity';
|
||||
return get(item, 'template') === template;
|
||||
})
|
||||
.map(function(item) {
|
||||
const identity = {
|
||||
ServiceName: get(item, 'Name'),
|
||||
[name]: get(item, 'Name'),
|
||||
};
|
||||
if (get(item, 'Datacenters')) {
|
||||
identity.Datacenters = get(item, 'Datacenters');
|
||||
if (typeof get(item, dc) !== 'undefined') {
|
||||
identity[dc] = get(item, dc);
|
||||
}
|
||||
return identity;
|
||||
});
|
||||
|
@ -51,9 +51,18 @@ export default Mixin.create({
|
|||
respondForQueryRecord: function(respond, query) {
|
||||
return this._super(function(cb) {
|
||||
return respond((headers, body) => {
|
||||
body.Policies = normalizePolicies(body.Policies).concat(
|
||||
normalizeServiceIdentities(body.ServiceIdentities)
|
||||
);
|
||||
body.Policies = normalizePolicies(body.Policies)
|
||||
.concat(
|
||||
normalizeIdentities(
|
||||
body.ServiceIdentities,
|
||||
'service-identity',
|
||||
'ServiceName',
|
||||
'Datacenters'
|
||||
)
|
||||
)
|
||||
.concat(
|
||||
normalizeIdentities(body.NodeIdentities, 'node-identity', 'NodeName', 'Datacenter')
|
||||
);
|
||||
return cb(headers, body);
|
||||
});
|
||||
}, query);
|
||||
|
@ -64,9 +73,18 @@ export default Mixin.create({
|
|||
return cb(
|
||||
headers,
|
||||
body.map(function(item) {
|
||||
item.Policies = normalizePolicies(item.Policies).concat(
|
||||
normalizeServiceIdentities(item.ServiceIdentities)
|
||||
);
|
||||
item.Policies = normalizePolicies(item.Policies)
|
||||
.concat(
|
||||
normalizeIdentities(
|
||||
item.ServiceIdentities,
|
||||
'service-identity',
|
||||
'ServiceName',
|
||||
'Datacenters'
|
||||
)
|
||||
)
|
||||
.concat(
|
||||
normalizeIdentities(item.NodeIdentities, 'node-identity', 'NodeName', 'Datacenter')
|
||||
);
|
||||
return item;
|
||||
})
|
||||
);
|
||||
|
@ -75,7 +93,18 @@ export default Mixin.create({
|
|||
},
|
||||
serialize: function(snapshot, options) {
|
||||
const data = this._super(...arguments);
|
||||
data.ServiceIdentities = serializeServiceIdentities(data.Policies);
|
||||
data.ServiceIdentities = serializeIdentities(
|
||||
data.Policies,
|
||||
'service-identity',
|
||||
'ServiceName',
|
||||
'Datacenters'
|
||||
);
|
||||
data.NodeIdentities = serializeIdentities(
|
||||
data.Policies,
|
||||
'node-identity',
|
||||
'NodeName',
|
||||
'Datacenter'
|
||||
);
|
||||
data.Policies = minimizeModel(serializePolicies(data.Policies));
|
||||
return data;
|
||||
},
|
||||
|
|
|
@ -22,6 +22,11 @@ export default Model.extend({
|
|||
return [];
|
||||
},
|
||||
}),
|
||||
NodeIdentities: attr({
|
||||
defaultValue: function() {
|
||||
return [];
|
||||
},
|
||||
}),
|
||||
// frontend only for ordering where CreateIndex can't be used
|
||||
CreateTime: attr('date'),
|
||||
//
|
||||
|
|
|
@ -39,6 +39,11 @@ export default Model.extend({
|
|||
return [];
|
||||
},
|
||||
}),
|
||||
NodeIdentities: attr({
|
||||
defaultValue: function() {
|
||||
return [];
|
||||
},
|
||||
}),
|
||||
CreateTime: attr('date'),
|
||||
Hash: attr('string'),
|
||||
CreateIndex: attr('number'),
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
}
|
||||
%radio-group label > span {
|
||||
margin-left: 1em;
|
||||
margin-top: 0.2em;
|
||||
}
|
||||
%radio-group label,
|
||||
%radio-group label > span {
|
||||
|
|
|
@ -13,6 +13,11 @@
|
|||
.consul-token-list > ul > li:not(:first-child) {
|
||||
@extend %with-composite-row-intent;
|
||||
}
|
||||
/*TODO: This hides the icons-less dt's in the below lists as */
|
||||
/* they don't have tooltips */
|
||||
.consul-token-list > ul > li:not(:first-child) dt {
|
||||
display: none;
|
||||
}
|
||||
/* TODO: the service list has a 1px offset */
|
||||
.consul-service-list li > div:first-child > dl:first-child dd {
|
||||
margin-top: 1px;
|
||||
|
|
|
@ -20,6 +20,7 @@ label span {
|
|||
@extend %form-row;
|
||||
}
|
||||
%radio-group label,
|
||||
%main-content .type-select,
|
||||
%main-content .type-password,
|
||||
%main-content .type-text {
|
||||
@extend %form-element;
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<p>
|
||||
By adding policies to this namespaces, you will apply them to all tokens created within this namespace.
|
||||
</p>
|
||||
<PolicySelector @dc={{dc}} @nspace="default" @allowServiceIdentity={{false}} @items={{item.ACLs.PolicyDefaults}} />
|
||||
<PolicySelector @dc={{dc}} @nspace="default" @allowIdentity={{false}} @items={{item.ACLs.PolicyDefaults}} />
|
||||
</fieldset>
|
||||
{{/if}}
|
||||
<div>
|
||||
|
|
|
@ -6,6 +6,7 @@ Feature: dc / acls / policies / as many / add existing: Add existing policy
|
|||
---
|
||||
Policies: ~
|
||||
ServiceIdentities: ~
|
||||
NodeIdentities: ~
|
||||
---
|
||||
And 2 policy models from yaml
|
||||
---
|
||||
|
|
|
@ -6,6 +6,7 @@ Feature: dc / acls / policies / as many / add new: Add new policy
|
|||
---
|
||||
Policies: ~
|
||||
ServiceIdentities: ~
|
||||
NodeIdentities: ~
|
||||
---
|
||||
When I visit the [Model] page for yaml
|
||||
---
|
||||
|
@ -52,7 +53,6 @@ Feature: dc / acls / policies / as many / add new: Add new policy
|
|||
Then I fill in the policies.form with yaml
|
||||
---
|
||||
Name: New-Service-Identity
|
||||
Description: New Service Identity Description
|
||||
---
|
||||
And I click serviceIdentity on the policies.form
|
||||
And I click submit on the policies.form
|
||||
|
@ -73,6 +73,31 @@ Feature: dc / acls / policies / as many / add new: Add new policy
|
|||
| token |
|
||||
| role |
|
||||
-------------
|
||||
Scenario: Adding a new node identity as a child of [Model]
|
||||
Then I fill in the policies.form with yaml
|
||||
---
|
||||
Name: New-Node-Identity
|
||||
---
|
||||
And I click nodeIdentity on the policies.form
|
||||
And I click submit on the policies.form
|
||||
And I submit
|
||||
Then a PUT request was made to "/v1/acl/[Model]/key?dc=datacenter" from yaml
|
||||
---
|
||||
body:
|
||||
Namespace: @namespace
|
||||
NodeIdentities:
|
||||
- NodeName: New-Node-Identity
|
||||
Datacenter: datacenter
|
||||
---
|
||||
Then the url should be /datacenter/acls/[Model]s
|
||||
And "[data-notification]" has the "notification-update" class
|
||||
And "[data-notification]" has the "success" class
|
||||
Where:
|
||||
-------------
|
||||
| Model |
|
||||
| token |
|
||||
| role |
|
||||
-------------
|
||||
Scenario: Adding a new policy as a child of [Model] and getting an error
|
||||
Given the url "/v1/acl/policy" responds with from yaml
|
||||
---
|
||||
|
@ -113,3 +138,15 @@ Feature: dc / acls / policies / as many / add new: Add new policy
|
|||
| token |
|
||||
| role |
|
||||
-------------
|
||||
Scenario: Try to edit the Node Identity using the code editor
|
||||
And I click nodeIdentity on the policies.form
|
||||
Then I can't fill in the policies.form with yaml
|
||||
---
|
||||
Rules: key {}
|
||||
---
|
||||
Where:
|
||||
-------------
|
||||
| Model |
|
||||
| token |
|
||||
| role |
|
||||
-------------
|
||||
|
|
|
@ -6,8 +6,8 @@ Feature: dc / acls / policies / as many / list: List
|
|||
---
|
||||
ServiceIdentities:
|
||||
- ServiceName: Service-Identity
|
||||
- ServiceName: Service-Identity 2
|
||||
- ServiceName: Service-Identity 3
|
||||
NodeIdentities:
|
||||
- NodeName: Node-Identity
|
||||
Policies:
|
||||
- Name: Policy
|
||||
ID: 0000
|
||||
|
@ -22,8 +22,8 @@ Feature: dc / acls / policies / as many / list: List
|
|||
[Model]: key
|
||||
---
|
||||
Then the url should be /datacenter/acls/[Model]s/key
|
||||
# ServiceIdentities turn into policies
|
||||
Then I see 6 policy models on the policies component
|
||||
# Identities turn into policies
|
||||
Then I see 5 policy models on the policies component
|
||||
Where:
|
||||
-------------
|
||||
| Model |
|
||||
|
|
|
@ -5,6 +5,7 @@ Feature: dc / acls / policies / as many / remove: Remove
|
|||
And 1 [Model] model from yaml
|
||||
---
|
||||
ServiceIdentities: ~
|
||||
NodeIdentities: ~
|
||||
Policies:
|
||||
- Name: Policy
|
||||
ID: 00000000-0000-0000-0000-000000000001
|
||||
|
|
|
@ -6,6 +6,7 @@ Feature: dc / acls / tokens / clone: Cloning an ACL token
|
|||
---
|
||||
AccessorID: token
|
||||
SecretID: ee52203d-989f-4f7a-ab5a-2bef004164ca
|
||||
Legacy: ~
|
||||
---
|
||||
Scenario: Cloning an ACL token from the listing page
|
||||
When I visit the tokens page for yaml
|
||||
|
|
|
@ -4,16 +4,27 @@ export const createPolicies = function(item) {
|
|||
template: '',
|
||||
...item,
|
||||
};
|
||||
}).concat(
|
||||
item.ServiceIdentities.map(function(item) {
|
||||
const policy = {
|
||||
template: 'service-identity',
|
||||
Name: item.ServiceName,
|
||||
};
|
||||
if (typeof item.Datacenters !== 'undefined') {
|
||||
policy.Datacenters = item.Datacenters;
|
||||
}
|
||||
return policy;
|
||||
})
|
||||
);
|
||||
})
|
||||
.concat(
|
||||
item.ServiceIdentities.map(function(item) {
|
||||
const policy = {
|
||||
template: 'service-identity',
|
||||
Name: item.ServiceName,
|
||||
};
|
||||
if (typeof item.Datacenters !== 'undefined') {
|
||||
policy.Datacenters = item.Datacenters;
|
||||
}
|
||||
return policy;
|
||||
})
|
||||
)
|
||||
.concat(
|
||||
item.NodeIdentities.map(function(item) {
|
||||
const policy = {
|
||||
template: 'node-identity',
|
||||
Name: item.NodeName,
|
||||
Datacenter: item.Datacenter,
|
||||
};
|
||||
return policy;
|
||||
})
|
||||
);
|
||||
};
|
||||
|
|
|
@ -1211,9 +1211,9 @@
|
|||
js-yaml "^3.13.1"
|
||||
|
||||
"@hashicorp/consul-api-double@^3.0.0":
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@hashicorp/consul-api-double/-/consul-api-double-3.0.0.tgz#a1ad94f33e006d01cebf2b22d1f87efef1756ece"
|
||||
integrity sha512-wB1YgDBN3eOvNWRzSOc2k0eVE7C8YHFC5rJEdNWWTzjOokj6zDr40g2yLiaDMXl21XQs5LE8kNstEe8pf2+JUQ==
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@hashicorp/consul-api-double/-/consul-api-double-3.1.0.tgz#6f0cfc32d99b6f0c876d473ff8fdc489b7403904"
|
||||
integrity sha512-TsRvkBJTzMaXlSyaFT4HU+Phhk+7K2kWPmnuM41cqkHsCLfoTllQ37avQyLYGM/57yfd0ajbI4M6IKoYJnQUWg==
|
||||
|
||||
"@hashicorp/ember-cli-api-double@^3.1.0":
|
||||
version "3.1.0"
|
||||
|
|
Loading…
Reference in New Issue