ui: Add simple intention check interface to per service intentions (#8899)
This commit is contained in:
parent
3e89a88aec
commit
80f9d53781
|
@ -1,111 +0,0 @@
|
|||
<DataWriter
|
||||
@sink={{concat '/' dc '/' nspace '/intention/'}}
|
||||
@type="intention"
|
||||
@ondelete={{action ondelete}}
|
||||
as |writer|>
|
||||
<BlockSlot @name="content">
|
||||
{{#if (gt items.length 0)}}
|
||||
|
||||
<TabularCollection class="consul-intention-list"
|
||||
@items={{items}}
|
||||
@rowHeight={{59}}
|
||||
as |item index|>
|
||||
<BlockSlot @name="header">
|
||||
<th class="source">Source</th>
|
||||
<th class="intent"> </th>
|
||||
<th class="destination">Destination</th>
|
||||
<th class="permissions">
|
||||
Permissions
|
||||
<span>
|
||||
<Tooltip>Permissions intercept an Intention's traffic using L7 criteria, such as path prefixes and http headers.</Tooltip>
|
||||
</span>
|
||||
</th>
|
||||
<th class="meta"> </th>
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="row">
|
||||
<td class="source" data-test-intention={{item.ID}}>
|
||||
<a href={{href-to (or routeName 'dc.intentions.edit') item.ID}} data-test-intention-source={{item.SourceName}}>
|
||||
{{#if (eq item.SourceName '*') }}
|
||||
All Services (*)
|
||||
{{else}}
|
||||
{{item.SourceName}}
|
||||
{{/if}}
|
||||
{{! TODO: slugify }}
|
||||
<em class={{concat 'nspace-' (or item.SourceNS 'default')}}>{{or item.SourceNS 'default'}}</em>
|
||||
</a>
|
||||
</td>
|
||||
{{#let (or item.Action "L7 rules") as |intent|}}
|
||||
<td class="intent intent-{{slugify intent}}" data-test-intention-action={{intent}}>
|
||||
<strong>{{capitalize intent}}</strong>
|
||||
</td>
|
||||
{{/let}}
|
||||
<td class="destination" data-test-intention-destination="{{item.DestinationName}}">
|
||||
<span>
|
||||
{{#if (eq item.DestinationName '*') }}
|
||||
All Services (*)
|
||||
{{else}}
|
||||
{{item.DestinationName}}
|
||||
{{/if}}
|
||||
{{! TODO: slugify }}
|
||||
<em class={{concat 'nspace-' (or item.DestinationNS 'default')}}>{{or item.DestinationNS 'default'}}</em>
|
||||
</span>
|
||||
</td>
|
||||
<td class="permissions">
|
||||
{{#if (gt item.Permissions.length 0)}}
|
||||
<span>{{pluralize item.Permissions.length 'Permission'}}</span>
|
||||
{{/if}}
|
||||
</td>
|
||||
<td class="meta">
|
||||
{{#if item.IsManagedByCRD}}
|
||||
<ConsulExternalSource @item={{item}} @label="Managed by CRD" />
|
||||
{{/if}}
|
||||
</td>
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="actions" as |index change checked|>
|
||||
<PopoverMenu @expanded={{if (eq checked index) true false}} @onchange={{action change index}} @keyboardAccess={{false}}>
|
||||
<BlockSlot @name="trigger">
|
||||
More
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="menu" as |confirm send keypressClick change|>
|
||||
{{#if item.IsEditable}}
|
||||
<li role="none">
|
||||
<a role="menuitem" tabindex="-1" href={{href-to (or routeName 'dc.intentions.edit') item.ID}}>Edit</a>
|
||||
</li>
|
||||
<li role="none" class="dangerous">
|
||||
<label for={{confirm}} role="menuitem" tabindex="-1" onkeypress={{keypressClick}} data-test-delete>Delete</label>
|
||||
<div role="menu">
|
||||
<div class="confirmation-alert warning">
|
||||
<div>
|
||||
<header>
|
||||
Confirm Delete
|
||||
</header>
|
||||
<p>
|
||||
Are you sure you want to delete this intention?
|
||||
</p>
|
||||
</div>
|
||||
<ul>
|
||||
<li class="dangerous">
|
||||
<button tabindex="-1" type="button" class="type-delete" onclick={{queue (action change) (action writer.delete item)}}>Delete</button>
|
||||
</li>
|
||||
<li>
|
||||
<label for={{confirm}}>Cancel</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{{else}}
|
||||
<li role="none">
|
||||
<a role="menuitem" tabindex="-1" href={{href-to (or routeName 'dc.intentions.edit') item.ID}}>View</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
</BlockSlot>
|
||||
</PopoverMenu>
|
||||
</BlockSlot>
|
||||
</TabularCollection>
|
||||
|
||||
{{else}}
|
||||
{{yield}}
|
||||
{{/if}}
|
||||
</BlockSlot>
|
||||
</DataWriter>
|
|
@ -1,6 +0,0 @@
|
|||
import Component from '@ember/component';
|
||||
|
||||
export default Component.extend({
|
||||
tagName: '',
|
||||
ondelete: function() {},
|
||||
});
|
|
@ -1,19 +0,0 @@
|
|||
@import './skin';
|
||||
@import './layout';
|
||||
.consul-intention-list td.source,
|
||||
.consul-intention-list td.destination {
|
||||
@extend %tbody-th;
|
||||
}
|
||||
.consul-intention-list td strong {
|
||||
@extend %pill-700;
|
||||
}
|
||||
.consul-intention-list td.intent-allow strong {
|
||||
@extend %pill-allow;
|
||||
}
|
||||
.consul-intention-list td.intent-deny strong {
|
||||
@extend %pill-deny;
|
||||
}
|
||||
.consul-intention-list td.intent-l7-rules strong {
|
||||
@extend %pill-l7;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
{{#let
|
||||
(from-entries (array
|
||||
(array 'allow' 'Allowed')
|
||||
(array 'deny' 'Denied')
|
||||
(array '' 'L7 Rules')
|
||||
))
|
||||
as |titles|}}
|
||||
<div
|
||||
class={{concat 'consul-intention-list-check ' 'notice ' (or @item.Action 'permissions')}}
|
||||
...attributes
|
||||
>
|
||||
<h3>
|
||||
{{get titles (or @item.Action '')}}
|
||||
</h3>
|
||||
<p>
|
||||
{{#if (eq @item.Action 'allow')}}
|
||||
Yes, {{item.SourceName}} is allowed to connect to {{@item.DestinationName}} due to the highest precedence intention below:
|
||||
{{else if (eq @item.Action 'deny')}}
|
||||
No, {{@item.SourceName}} is not allowed to connect to {{@item.DestinationName}} due to the highest precedence intention below:
|
||||
{{else}}
|
||||
{{@item.SourceName}} may or may not be allowed to connect with {{@item.DestinationName}} through its L7 rules.
|
||||
{{/if}}
|
||||
</p>
|
||||
</div>
|
||||
{{/let}}
|
|
@ -0,0 +1,27 @@
|
|||
.consul-intention-list {
|
||||
td.source,
|
||||
td.destination {
|
||||
@extend %tbody-th;
|
||||
}
|
||||
td strong {
|
||||
@extend %pill-700;
|
||||
}
|
||||
td.intent-allow strong {
|
||||
@extend %pill-allow;
|
||||
}
|
||||
td.intent-deny strong {
|
||||
@extend %pill-deny;
|
||||
}
|
||||
td.intent-l7-rules strong {
|
||||
@extend %pill-l7;
|
||||
}
|
||||
.notice.allow {
|
||||
@extend %notice-success;
|
||||
}
|
||||
.notice.deny {
|
||||
@extend %notice-error;
|
||||
}
|
||||
.notice.permissions {
|
||||
@extend %notice-info;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
<div
|
||||
class="consul-intention-list"
|
||||
...attributes
|
||||
>
|
||||
<DataWriter
|
||||
@sink={{concat '/' @dc '/' @nspace '/intention/'}}
|
||||
@type="intention"
|
||||
@ondelete={{action @ondelete}}
|
||||
as |writer|>
|
||||
<BlockSlot @name="content">
|
||||
|
||||
{{#let (hash
|
||||
Check=(component 'consul/intention/list/check')
|
||||
Table=(component 'consul/intention/list/table' delete=writer.delete items=@items)
|
||||
) as |api|}}
|
||||
|
||||
{{#if (gt @items.length 0)}}
|
||||
{{yield api to="idle"}}
|
||||
{{else}}
|
||||
{{yield api to="empty"}}
|
||||
{{/if}}
|
||||
|
||||
{{/let}}
|
||||
|
||||
</BlockSlot>
|
||||
</DataWriter>
|
||||
</div>
|
|
@ -0,0 +1,4 @@
|
|||
@import './components';
|
||||
@import './skin';
|
||||
@import './layout';
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
<TabularCollection
|
||||
class="consul-intention-list-table"
|
||||
...attributes
|
||||
@items={{@items}}
|
||||
@rowHeight={{59}}
|
||||
as |item index|>
|
||||
<BlockSlot @name="header">
|
||||
<th class="source">Source</th>
|
||||
<th class="intent"> </th>
|
||||
<th class="destination">Destination</th>
|
||||
<th class="permissions">
|
||||
Permissions
|
||||
<span>
|
||||
<Tooltip>Permissions intercept an Intention's traffic using L7 criteria, such as path prefixes and http headers.</Tooltip>
|
||||
</span>
|
||||
</th>
|
||||
<th class="meta"> </th>
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="row">
|
||||
<td class="source" data-test-intention={{item.ID}}>
|
||||
<a href={{href-to (or @routeName 'dc.intentions.edit') item.ID}} data-test-intention-source={{item.SourceName}}>
|
||||
{{#if (eq item.SourceName '*') }}
|
||||
All Services (*)
|
||||
{{else}}
|
||||
{{item.SourceName}}
|
||||
{{/if}}
|
||||
{{! TODO: slugify }}
|
||||
<em class={{concat 'nspace-' (or item.SourceNS 'default')}}>{{or item.SourceNS 'default'}}</em>
|
||||
</a>
|
||||
</td>
|
||||
{{#let (or item.Action "L7 rules") as |intent|}}
|
||||
<td class="intent intent-{{slugify intent}}" data-test-intention-action={{intent}}>
|
||||
<strong>{{capitalize intent}}</strong>
|
||||
</td>
|
||||
{{/let}}
|
||||
<td class="destination" data-test-intention-destination={{item.DestinationName}}>
|
||||
<span>
|
||||
{{#if (eq item.DestinationName '*') }}
|
||||
All Services (*)
|
||||
{{else}}
|
||||
{{item.DestinationName}}
|
||||
{{/if}}
|
||||
{{! TODO: slugify }}
|
||||
<em class={{concat 'nspace-' (or item.DestinationNS 'default')}}>{{or item.DestinationNS 'default'}}</em>
|
||||
</span>
|
||||
</td>
|
||||
<td class="permissions">
|
||||
{{#if (gt item.Permissions.length 0)}}
|
||||
<span>{{pluralize item.Permissions.length 'Permission'}}</span>
|
||||
{{/if}}
|
||||
</td>
|
||||
<td class="meta">
|
||||
{{#if item.IsManagedByCRD}}
|
||||
<ConsulExternalSource @item={{item}} @label="Managed by CRD" />
|
||||
{{/if}}
|
||||
</td>
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="actions" as |index change checked|>
|
||||
<PopoverMenu @expanded={{if (eq checked index) true false}} @onchange={{action change index}} @keyboardAccess={{false}}>
|
||||
<BlockSlot @name="trigger">
|
||||
More
|
||||
</BlockSlot>
|
||||
<BlockSlot @name="menu" as |confirm send keypressClick change|>
|
||||
{{#if item.IsEditable}}
|
||||
<li role="none">
|
||||
<a role="menuitem" tabindex="-1" href={{href-to (or routeName 'dc.intentions.edit') item.ID}}>Edit</a>
|
||||
</li>
|
||||
<li role="none" class="dangerous">
|
||||
<label for={{confirm}} role="menuitem" tabindex="-1" onkeypress={{keypressClick}} data-test-delete>Delete</label>
|
||||
<div role="menu">
|
||||
<div class="confirmation-alert warning">
|
||||
<div>
|
||||
<header>
|
||||
Confirm Delete
|
||||
</header>
|
||||
<p>
|
||||
Are you sure you want to delete this intention?
|
||||
</p>
|
||||
</div>
|
||||
<ul>
|
||||
<li class="dangerous">
|
||||
<button tabindex="-1" type="button" class="type-delete" onclick={{queue (action change) (action @delete item)}}>Delete</button>
|
||||
</li>
|
||||
<li>
|
||||
<label for={{confirm}}>Cancel</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
{{else}}
|
||||
<li role="none">
|
||||
<a role="menuitem" tabindex="-1" href={{href-to (or @routeName 'dc.intentions.edit') item.ID}}>View</a>
|
||||
</li>
|
||||
{{/if}}
|
||||
</BlockSlot>
|
||||
</PopoverMenu>
|
||||
</BlockSlot>
|
||||
</TabularCollection>
|
|
@ -61,7 +61,7 @@
|
|||
* when convienient
|
||||
**/
|
||||
|
||||
@import 'consul-ui/components/consul-intention-list';
|
||||
@import 'consul-ui/components/consul/intention/list';
|
||||
@import 'consul-ui/components/consul-intention-form/fieldsets';
|
||||
@import 'consul-ui/components/consul-intention-permission-list';
|
||||
@import 'consul-ui/components/consul-intention-permission-form';
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
@extend %with-cancel-square-fill-color-icon;
|
||||
}
|
||||
/**/
|
||||
.notice.success {
|
||||
@extend %notice-success;
|
||||
}
|
||||
.notice.warning {
|
||||
@extend %notice-warning;
|
||||
}
|
||||
|
|
|
@ -42,10 +42,14 @@
|
|||
{{#let (sort-by (comparator 'intention' sort) filtered) as |sorted|}}
|
||||
<ChangeableSet @dispatcher={{searchable 'intention' sorted}} @terms={{search}}>
|
||||
<BlockSlot @name="content" as |searched|>
|
||||
<ConsulIntentionList
|
||||
<Consul::Intention::List
|
||||
@items={{searched}}
|
||||
@ondelete={{refresh-route}}
|
||||
>
|
||||
>
|
||||
<:idle as |list|>
|
||||
<list.Table />
|
||||
</:idle>
|
||||
<:empty as |list|>
|
||||
<EmptyState @allowLogin={{true}}>
|
||||
<BlockSlot @name="header">
|
||||
<h2>
|
||||
|
@ -74,7 +78,8 @@
|
|||
</li>
|
||||
</BlockSlot>
|
||||
</EmptyState>
|
||||
</ConsulIntentionList>
|
||||
</:empty>
|
||||
</Consul::Intention::List>
|
||||
</BlockSlot>
|
||||
</ChangeableSet>
|
||||
{{/let}}
|
||||
|
|
|
@ -31,19 +31,33 @@
|
|||
{{#let (sort-by (comparator 'intention' sort) filtered) as |sorted|}}
|
||||
<ChangeableSet @dispatcher={{searchable 'intention' sorted}} @terms={{search}}>
|
||||
<BlockSlot @name="content" as |searched|>
|
||||
<ConsulIntentionList
|
||||
|
||||
<Consul::Intention::List
|
||||
@items={{searched}}
|
||||
@ondelete={{refresh-route}}
|
||||
@routeName="dc.services.show.intentions.edit"
|
||||
>
|
||||
<EmptyState>
|
||||
<BlockSlot @name="body">
|
||||
<p>
|
||||
There are no intentions {{if (gt items.length 0) 'found '}} for this service.
|
||||
</p>
|
||||
</BlockSlot>
|
||||
</EmptyState>
|
||||
</ConsulIntentionList>
|
||||
>
|
||||
<:idle as |list|>
|
||||
{{#if (eq searched.length 1)}}
|
||||
{{#let searched.firstObject as |item|}}
|
||||
{{#if (eq search item.SourceName)}}
|
||||
<list.Check @item={{item}} />
|
||||
{{/if}}
|
||||
{{/let}}
|
||||
{{/if}}
|
||||
<list.Table />
|
||||
</:idle>
|
||||
<:empty as |list|>
|
||||
<EmptyState>
|
||||
<BlockSlot @name="body">
|
||||
<p>
|
||||
There are no intentions {{if (gt items.length 0) 'found '}} for this service.
|
||||
</p>
|
||||
</BlockSlot>
|
||||
</EmptyState>
|
||||
</:empty>
|
||||
</Consul::Intention::List>
|
||||
|
||||
</BlockSlot>
|
||||
</ChangeableSet>
|
||||
{{/let}}
|
||||
|
|
|
@ -100,6 +100,7 @@
|
|||
"ember-load-initializers": "^2.1.1",
|
||||
"ember-math-helpers": "^2.4.0",
|
||||
"ember-maybe-import-regenerator": "^0.1.6",
|
||||
"ember-named-blocks-polyfill": "^0.2.3",
|
||||
"ember-on-helper": "^0.1.0",
|
||||
"ember-page-title": "^5.2.3",
|
||||
"ember-power-select": "^4.0.3",
|
||||
|
|
|
@ -41,7 +41,7 @@ import tokenListFactory from 'consul-ui/components/token-list/pageobject';
|
|||
import consulTokenListFactory from 'consul-ui/components/consul-token-list/pageobject';
|
||||
import consulRoleListFactory from 'consul-ui/components/consul-role-list/pageobject';
|
||||
import consulPolicyListFactory from 'consul-ui/components/consul-policy-list/pageobject';
|
||||
import consulIntentionListFactory from 'consul-ui/components/consul-intention-list/pageobject';
|
||||
import consulIntentionListFactory from 'consul-ui/components/consul/intention/list/pageobject';
|
||||
import consulNspaceListFactory from 'consul-ui/components/consul-nspace-list/pageobject';
|
||||
import consulKvListFactory from 'consul-ui/components/consul-kv-list/pageobject';
|
||||
|
||||
|
|
|
@ -6115,6 +6115,15 @@ ember-modifier-manager-polyfill@^1.1.0:
|
|||
ember-cli-version-checker "^2.1.2"
|
||||
ember-compatibility-helpers "^1.2.0"
|
||||
|
||||
ember-named-blocks-polyfill@^0.2.3:
|
||||
version "0.2.3"
|
||||
resolved "https://registry.yarnpkg.com/ember-named-blocks-polyfill/-/ember-named-blocks-polyfill-0.2.3.tgz#05fb3b40cff98a0d30e8c3b1e3d2155951007d84"
|
||||
integrity sha512-RrhkgWmfte2lRuOmRWWa7sS2Eo6W3O0VybK0iPhhnLvk7VtUSOmFxuDlhAtEaJ0lBieISrNcmSIZRnmgca/HcA==
|
||||
dependencies:
|
||||
ember-cli-babel "^7.19.0"
|
||||
ember-cli-htmlbars "^4.3.1"
|
||||
ember-cli-version-checker "^5.1.1"
|
||||
|
||||
ember-native-dom-helpers@^0.6.3:
|
||||
version "0.6.3"
|
||||
resolved "https://registry.yarnpkg.com/ember-native-dom-helpers/-/ember-native-dom-helpers-0.6.3.tgz#31c88b6eb8e1bb99ee594d19de8f0270d1d5eb35"
|
||||
|
|
Loading…
Reference in New Issue