mirror of https://github.com/hashicorp/consul
ui: Topology - Fix up Default Allow and Permissive Intentions notices (#11216)
* ui: Default allow notices test (#11240)pull/11284/head
parent
be667e280f
commit
daec73e76c
|
@ -0,0 +1,3 @@
|
||||||
|
```release-note:bug
|
||||||
|
ui: Topology - Fix up Default Allow and Permissive Intentions notices
|
||||||
|
```
|
|
@ -1,10 +1,14 @@
|
||||||
<div class="collapsible-notices {{if this.collapsed 'collapsed'}}">
|
{{#if @collapsible}}
|
||||||
<div class="notices">
|
<div class="collapsible-notices {{if this.collapsed 'collapsed'}}">
|
||||||
{{yield}}
|
<div class="notices">
|
||||||
|
{{yield}}
|
||||||
|
</div>
|
||||||
|
{{#if this.collapsed}}
|
||||||
|
<button type="button" class="expand" {{on 'click' (set this 'collapsed' false)}}>{{t "components.app.collapsible-notices.expand"}}</button>
|
||||||
|
{{else}}
|
||||||
|
<button type="button" class="collapse" {{on 'click' (set this 'collapsed' true)}}>{{t "components.app.collapsible-notices.collapse"}}</button>
|
||||||
|
{{/if}}
|
||||||
</div>
|
</div>
|
||||||
{{#if this.collapsed}}
|
|
||||||
<button type="button" class="expand" {{on 'click' (set this 'collapsed' false)}}>{{t "components.app.collapsible-notices.expand"}}</button>
|
|
||||||
{{else}}
|
{{else}}
|
||||||
<button type="button" class="collapse" {{on 'click' (set this 'collapsed' true)}}>{{t "components.app.collapsible-notices.collapse"}}</button>
|
{{yield}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
{{did-update this.setHeight 'downstream-lines' @topology.Downstreams}}
|
{{did-update this.setHeight 'downstream-lines' @topology.Downstreams}}
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<p>{{@dc}}</p>
|
<p>{{@dc.Name}}</p>
|
||||||
<span>
|
<span>
|
||||||
<Tooltip>
|
<Tooltip>
|
||||||
Only showing downstreams within the current datacenter for {{@service.Service.Service}}.
|
Only showing downstreams within the current datacenter for {{@service.Service.Service}}.
|
||||||
|
@ -19,7 +19,7 @@
|
||||||
{{#each @topology.Downstreams as |item|}}
|
{{#each @topology.Downstreams as |item|}}
|
||||||
<TopologyMetrics::Card
|
<TopologyMetrics::Card
|
||||||
@nspace={{@nspace}}
|
@nspace={{@nspace}}
|
||||||
@dc={{@dc}}
|
@dc={{@dc.Name}}
|
||||||
@service={{@service.Service}}
|
@service={{@service.Service}}
|
||||||
@item={{item}}
|
@item={{item}}
|
||||||
@hasMetricsProvider={{@hasMetricsProvider}}
|
@hasMetricsProvider={{@hasMetricsProvider}}
|
||||||
|
@ -50,7 +50,7 @@
|
||||||
<TopologyMetrics::Series
|
<TopologyMetrics::Series
|
||||||
@nspace={{or @service.Service.Namespace 'default'}}
|
@nspace={{or @service.Service.Namespace 'default'}}
|
||||||
@partition={{or service.Service.Partition 'default'}}
|
@partition={{or service.Service.Partition 'default'}}
|
||||||
@dc={{@dc}}
|
@dc={{@dc.Name}}
|
||||||
@service={{@service.Service.Service}}
|
@service={{@service.Service.Service}}
|
||||||
@protocol={{@topology.Protocol}}
|
@protocol={{@topology.Protocol}}
|
||||||
@noMetricsReason={{this.noMetricsReason}}
|
@noMetricsReason={{this.noMetricsReason}}
|
||||||
|
@ -59,7 +59,7 @@
|
||||||
<TopologyMetrics::Stats
|
<TopologyMetrics::Stats
|
||||||
@nspace={{or @service.Service.Namespace 'default'}}
|
@nspace={{or @service.Service.Namespace 'default'}}
|
||||||
@partition={{or service.Service.Partition 'default'}}
|
@partition={{or service.Service.Partition 'default'}}
|
||||||
@dc={{@dc}}
|
@dc={{@dc.Name}}
|
||||||
@endpoint='summary-for-service'
|
@endpoint='summary-for-service'
|
||||||
@service={{@service.Service.Service}}
|
@service={{@service.Service.Service}}
|
||||||
@protocol={{@topology.Protocol}}
|
@protocol={{@topology.Protocol}}
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#each upstreams as |item|}}
|
{{#each upstreams as |item|}}
|
||||||
<TopologyMetrics::Card
|
<TopologyMetrics::Card
|
||||||
@dc={{@dc}}
|
@dc={{@dc.Name}}
|
||||||
@item={{item}}
|
@item={{item}}
|
||||||
@service={{@service.Service}}
|
@service={{@service.Service}}
|
||||||
>
|
>
|
||||||
|
|
|
@ -69,9 +69,9 @@ export default class TopologyMetrics extends Component {
|
||||||
get upstreams() {
|
get upstreams() {
|
||||||
const upstreams = get(this.args.topology, 'Upstreams') || [];
|
const upstreams = get(this.args.topology, 'Upstreams') || [];
|
||||||
const items = [...upstreams];
|
const items = [...upstreams];
|
||||||
const defaultAllow = get(this.args.topology, 'DefaultAllow');
|
const defaultACLPolicy = get(this.args.dc, 'DefaultACLPolicy');
|
||||||
const wildcardIntention = get(this.args.topology, 'WildcardIntention');
|
const wildcardIntention = get(this.args.topology, 'wildcardIntention');
|
||||||
if (defaultAllow || wildcardIntention) {
|
if (defaultACLPolicy === 'allow' || wildcardIntention) {
|
||||||
items.push({
|
items.push({
|
||||||
Name: '* (All Services)',
|
Name: '* (All Services)',
|
||||||
Datacenter: '',
|
Datacenter: '',
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { helper } from '@ember/component/helper';
|
||||||
|
|
||||||
|
export function collapsibleNotices(params, hash) {
|
||||||
|
// This filter will only return truthy items
|
||||||
|
const noticesCount = params.filter(Boolean).length;
|
||||||
|
return noticesCount > 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default helper(collapsibleNotices);
|
|
@ -14,8 +14,6 @@ export default class Topology extends Model {
|
||||||
@attr('string') Protocol;
|
@attr('string') Protocol;
|
||||||
@attr('boolean') FilteredByACLs;
|
@attr('boolean') FilteredByACLs;
|
||||||
@attr('boolean') TransparentProxy;
|
@attr('boolean') TransparentProxy;
|
||||||
@attr('boolean') DefaultAllow;
|
|
||||||
@attr('boolean') WildcardIntention;
|
|
||||||
@attr() Upstreams; // Service[]
|
@attr() Upstreams; // Service[]
|
||||||
@attr() Downstreams; // Service[],
|
@attr() Downstreams; // Service[],
|
||||||
@attr() meta; // {}
|
@attr() meta; // {}
|
||||||
|
@ -33,14 +31,19 @@ export default class Topology extends Model {
|
||||||
return undefinedDownstream;
|
return undefinedDownstream;
|
||||||
}
|
}
|
||||||
|
|
||||||
@computed('FilteredByACL', 'DefaultAllow', 'WildcardIntention', 'notDefinedIntention')
|
@computed('Downstreams', 'Upstreams')
|
||||||
get collapsible() {
|
// A service has a wildcard intention if `Allowed == true` and `HasExact = false`
|
||||||
if (this.DefaultAllow && this.FilteredByACLs && this.notDefinedIntention) {
|
// The Permissive Intention notice appears if at least one upstream or downstream has
|
||||||
return true;
|
// a wildcard intention
|
||||||
} else if (this.WildcardIntention && this.FilteredByACLs && this.notDefinedIntention) {
|
get wildcardIntention() {
|
||||||
return true;
|
const downstreamWildcard =
|
||||||
}
|
this.Downstreams.filter(item => !item.Intention.HasExact && item.Intention.Allowed).length !==
|
||||||
|
0;
|
||||||
|
|
||||||
return false;
|
const upstreamWildcard =
|
||||||
|
this.Upstreams.filter(item => !item.Intention.HasExact && item.Intention.Allowed).length !==
|
||||||
|
0;
|
||||||
|
|
||||||
|
return downstreamWildcard || upstreamWildcard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ as |route|>
|
||||||
loader.data
|
loader.data
|
||||||
as |nspace dc items topology|}}
|
as |nspace dc items topology|}}
|
||||||
<div class="tab-section">
|
<div class="tab-section">
|
||||||
{{#if (and (eq topology.Upstreams.length 0) (eq topology.Downstreams.length 0) (not topology.DefaultAllow) (not topology.WildcardIntention))}}
|
{{#if (and (eq topology.Upstreams.length 0) (eq topology.Downstreams.length 0) (not-eq dc.DefaultACLPolicy 'allow') (not topology.wildcardIntention))}}
|
||||||
<EmptyState>
|
<EmptyState>
|
||||||
<BlockSlot @name="header">
|
<BlockSlot @name="header">
|
||||||
<h2>
|
<h2>
|
||||||
|
@ -46,84 +46,47 @@ as |nspace dc items topology|}}
|
||||||
</BlockSlot>
|
</BlockSlot>
|
||||||
</EmptyState>
|
</EmptyState>
|
||||||
{{else}}
|
{{else}}
|
||||||
{{#if topology.collapsible}}
|
|
||||||
<CollapsibleNotices>
|
|
||||||
{{#if topology.FilteredByACLs}}
|
|
||||||
<TopologyMetrics::Notice
|
|
||||||
data-test-notice='filtered-by-acls'
|
|
||||||
@type="info"
|
|
||||||
@for="limited-access"
|
|
||||||
@action={{false}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
{{#if topology.DefaultAllow}}
|
|
||||||
<TopologyMetrics::Notice
|
|
||||||
data-test-notice='default-allow'
|
|
||||||
@type="warning"
|
|
||||||
@for="default-allow"
|
|
||||||
@internal={{true}}
|
|
||||||
@action={{true}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
{{#if topology.WildcardIntention}}
|
|
||||||
<TopologyMetrics::Notice
|
|
||||||
data-test-notice='wildcard-intention'
|
|
||||||
@type="warning"
|
|
||||||
@for="wildcard-intention"
|
|
||||||
@internal={{true}}
|
|
||||||
@action={{true}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
{{#if topology.notDefinedIntention}}
|
|
||||||
<TopologyMetrics::Notice
|
|
||||||
data-test-notice='not-defined-intention'
|
|
||||||
@type="warning"
|
|
||||||
@for="not-defined-intention"
|
|
||||||
@link="{{env 'CONSUL_DOCS_URL'}}/connect/registration/service-registration#upstreams"
|
|
||||||
@internal={{false}}
|
|
||||||
@action={{true}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
</CollapsibleNotices>
|
|
||||||
{{else}}
|
|
||||||
{{#if topology.FilteredByACLs}}
|
|
||||||
<TopologyMetrics::Notice
|
|
||||||
data-test-notice='filtered-by-acls'
|
|
||||||
@type="info"
|
|
||||||
@for="limited-access"
|
|
||||||
@action={{false}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
{{#if topology.DefaultAllow}}
|
|
||||||
<TopologyMetrics::Notice
|
|
||||||
data-test-notice='default-allow'
|
|
||||||
@type="warning"
|
|
||||||
@for="default-allow"
|
|
||||||
@internal={{true}}
|
|
||||||
@action={{true}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
{{#if topology.WildcardIntention}}
|
|
||||||
<TopologyMetrics::Notice
|
|
||||||
data-test-notice='wildcard-intention'
|
|
||||||
@type="warning"
|
|
||||||
@for="wildcard-intention"
|
|
||||||
@internal={{true}}
|
|
||||||
@action={{true}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
{{#if topology.notDefinedIntention}}
|
|
||||||
<TopologyMetrics::Notice
|
|
||||||
data-test-notice='not-defined-intention'
|
|
||||||
@type="warning"
|
|
||||||
@for="not-defined-intention"
|
|
||||||
@link="{{env 'CONSUL_DOCS_URL'}}/connect/registration/service-registration#upstreams"
|
|
||||||
@internal={{false}}
|
|
||||||
@action={{true}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
|
{{#let (collapsible-notices topology.FilteredByACLs (eq dc.DefaultACLPolicy 'allow') topology.wildcardIntention topology.notDefinedIntention) as |collapsible| }}
|
||||||
|
<CollapsibleNotices @collapsible={{collapsible}}>
|
||||||
|
{{#if topology.FilteredByACLs}}
|
||||||
|
<TopologyMetrics::Notice
|
||||||
|
data-test-notice='filtered-by-acls'
|
||||||
|
@type="info"
|
||||||
|
@for="limited-access"
|
||||||
|
@action={{false}}
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
{{#if (eq dc.DefaultACLPolicy 'allow')}}
|
||||||
|
<TopologyMetrics::Notice
|
||||||
|
data-test-notice='default-allow'
|
||||||
|
@type="warning"
|
||||||
|
@for="default-allow"
|
||||||
|
@internal={{true}}
|
||||||
|
@action={{true}}
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
{{#if topology.wildcardIntention}}
|
||||||
|
<TopologyMetrics::Notice
|
||||||
|
data-test-notice='wildcard-intention'
|
||||||
|
@type="warning"
|
||||||
|
@for="wildcard-intention"
|
||||||
|
@internal={{true}}
|
||||||
|
@action={{true}}
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
{{#if topology.notDefinedIntention}}
|
||||||
|
<TopologyMetrics::Notice
|
||||||
|
data-test-notice='not-defined-intention'
|
||||||
|
@type="warning"
|
||||||
|
@for="not-defined-intention"
|
||||||
|
@link="{{env 'CONSUL_DOCS_URL'}}/connect/registration/service-registration#upstreams"
|
||||||
|
@internal={{false}}
|
||||||
|
@action={{true}}
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
</CollapsibleNotices>
|
||||||
|
{{/let}}
|
||||||
<DataSource
|
<DataSource
|
||||||
@src={{uri '/${partition}/${nspace}/${dc}/ui-config'
|
@src={{uri '/${partition}/${nspace}/${dc}/ui-config'
|
||||||
(hash
|
(hash
|
||||||
|
@ -136,7 +99,7 @@ as |nspace dc items topology|}}
|
||||||
{{#if config.data}}
|
{{#if config.data}}
|
||||||
<TopologyMetrics
|
<TopologyMetrics
|
||||||
@nspace={{nspace}}
|
@nspace={{nspace}}
|
||||||
@dc={{dc.Name}}
|
@dc={{dc}}
|
||||||
@service={{items.firstObject}}
|
@service={{items.firstObject}}
|
||||||
@topology={{topology}}
|
@topology={{topology}}
|
||||||
|
|
||||||
|
|
|
@ -4,4 +4,4 @@
|
||||||
"*":
|
"*":
|
||||||
headers:
|
headers:
|
||||||
response:
|
response:
|
||||||
X-Consul-Default-Acl-Policy: ${fake.helpers.randomize(['allow', 'deny'])}
|
x-consul-default-acl-policy: ${env('CONSUL_ACL_POLICY', fake.helpers.randomize(['allow', 'deny']))}
|
||||||
|
|
|
@ -53,17 +53,11 @@ ${
|
||||||
fake.seed(index);
|
fake.seed(index);
|
||||||
|
|
||||||
|
|
||||||
// Randomly make permissive intentions
|
|
||||||
const defaultAllow = fake.random.boolean();
|
|
||||||
const wildcardIntention = defaultAllow ? false : fake.random.boolean();
|
|
||||||
|
|
||||||
return `
|
return `
|
||||||
{
|
{
|
||||||
"Protocol": "${serviceProto}",
|
"Protocol": "${serviceProto}",
|
||||||
"FilteredByACLs": ${fake.random.boolean()},
|
"FilteredByACLs": ${fake.random.boolean()},
|
||||||
"TransparentProxy": ${fake.random.boolean()},
|
"TransparentProxy": ${fake.random.boolean()},
|
||||||
"DefaultAllow": ${defaultAllow},
|
|
||||||
"WildcardIntention": ${wildcardIntention},
|
|
||||||
"Upstreams": [
|
"Upstreams": [
|
||||||
${
|
${
|
||||||
upstreams.map((item, i) => {
|
upstreams.map((item, i) => {
|
||||||
|
|
|
@ -18,14 +18,25 @@ Feature: dc / services / show / topology / tproxy
|
||||||
Name: web
|
Name: web
|
||||||
Kind: ~
|
Kind: ~
|
||||||
---
|
---
|
||||||
Scenario: Deafult allow is set to true
|
Scenario: Default allow is set to true
|
||||||
Given 1 topology model from yaml
|
Given 1 topology model from yaml
|
||||||
---
|
---
|
||||||
FilteredByACLs: false
|
FilteredByACLs: false
|
||||||
TransparentProxy: false
|
TransparentProxy: false
|
||||||
DefaultAllow: true
|
Downstreams:
|
||||||
WildcardIntention: false
|
- Name: db-1
|
||||||
|
Namespace: default
|
||||||
|
Datacenter: datacenter
|
||||||
|
Intention:
|
||||||
|
Allowed: false
|
||||||
|
Upstreams:
|
||||||
|
- Name: db-2
|
||||||
|
Namespace: default
|
||||||
|
Datacenter: datacenter
|
||||||
|
Intention:
|
||||||
|
Allowed: false
|
||||||
---
|
---
|
||||||
|
And the default ACL policy is "allow"
|
||||||
When I visit the service page for yaml
|
When I visit the service page for yaml
|
||||||
---
|
---
|
||||||
dc: datacenter
|
dc: datacenter
|
||||||
|
@ -33,13 +44,24 @@ Feature: dc / services / show / topology / tproxy
|
||||||
---
|
---
|
||||||
Then the url should be /datacenter/services/web/topology
|
Then the url should be /datacenter/services/web/topology
|
||||||
And I see the tabs.topologyTab.defaultAllowNotice object
|
And I see the tabs.topologyTab.defaultAllowNotice object
|
||||||
Scenario: WildcardIntetions and FilteredByACLs are set to true
|
Scenario: A Downstream service has a wildcard intention
|
||||||
Given 1 topology model from yaml
|
Given 1 topology model from yaml
|
||||||
---
|
---
|
||||||
FilteredByACLs: true
|
FilteredByACLs: true
|
||||||
TransparentProxy: false
|
TransparentProxy: false
|
||||||
DefaultAllow: false
|
Downstreams:
|
||||||
WildcardIntention: true
|
- Name: db-1
|
||||||
|
Namespace: default
|
||||||
|
Datacenter: datacenter
|
||||||
|
Intention:
|
||||||
|
Allowed: true
|
||||||
|
HasExact: false
|
||||||
|
Upstreams:
|
||||||
|
- Name: db-2
|
||||||
|
Namespace: default
|
||||||
|
Datacenter: datacenter
|
||||||
|
Intention:
|
||||||
|
Allowed: false
|
||||||
---
|
---
|
||||||
When I visit the service page for yaml
|
When I visit the service page for yaml
|
||||||
---
|
---
|
||||||
|
|
|
@ -38,6 +38,9 @@ export default function(scenario, create, set, win = window, doc = document) {
|
||||||
.given(['ACLs are disabled'], function() {
|
.given(['ACLs are disabled'], function() {
|
||||||
doc.cookie = `CONSUL_ACLS_ENABLE=0`;
|
doc.cookie = `CONSUL_ACLS_ENABLE=0`;
|
||||||
})
|
})
|
||||||
|
.given(['the default ACL policy is "$policy"'], function(policy) {
|
||||||
|
set('CONSUL_ACL_POLICY', policy);
|
||||||
|
})
|
||||||
.given(['a "$value" metrics provider'], function(value) {
|
.given(['a "$value" metrics provider'], function(value) {
|
||||||
doc.cookie = `CONSUL_METRICS_PROXY_ENABLE=1`;
|
doc.cookie = `CONSUL_METRICS_PROXY_ENABLE=1`;
|
||||||
doc.cookie = `CONSUL_METRICS_PROVIDER=${value}`;
|
doc.cookie = `CONSUL_METRICS_PROVIDER=${value}`;
|
||||||
|
|
Loading…
Reference in New Issue