ui: Create Upstreams tab for Ingress Gateways (#7865)

pull/7870/head
Kenia 2020-05-13 11:28:11 -04:00 committed by kenia
parent 2adfb42bde
commit 6367160c93
15 changed files with 183 additions and 19 deletions

View File

@ -22,6 +22,9 @@ export const routes = {
services: { services: {
_options: { path: '/services' }, _options: { path: '/services' },
}, },
upstreams: {
_options: { path: '/upstreams' },
},
routing: { routing: {
_options: { path: '/routing' }, _options: { path: '/routing' },
}, },

View File

@ -0,0 +1,14 @@
import Route from '@ember/routing/route';
export default Route.extend({
model: function() {
const parent = this.routeName
.split('.')
.slice(0, -1)
.join('.');
return this.modelFor(parent);
},
setupController: function(controller, model) {
controller.setProperties(model);
},
});

View File

@ -33,3 +33,12 @@
%composite-row-detail .port button:hover { %composite-row-detail .port button:hover {
background-color: transparent !important; background-color: transparent !important;
} }
// Tooltip
%composite-row-detail .feedback-dialog-out {
left: -12px;
bottom: 12px;
}
%composite-row-detail .feedback-dialog-out::after {
left: 18px;
}

View File

@ -1,9 +1,9 @@
%composite-row { %composite-row {
list-style-type: none; list-style-type: none;
border-top-color: $gray-200; border-top-color: $transparent;
border-bottom-color: transparent; border-bottom-color: $gray-200;
border-right-color: transparent; border-right-color: $transparent;
border-left-color: transparent; border-left-color: $transparent;
} }
%composite-row-intent { %composite-row-intent {
border-color: $gray-200; border-color: $gray-200;
@ -16,9 +16,6 @@
%composite-row-detail { %composite-row-detail {
color: $gray-500; color: $gray-500;
} }
%composite-row:last-child {
border-bottom-color: $gray-200;
}
// Health Checks // Health Checks
%composite-row .passing::before { %composite-row .passing::before {

View File

@ -1,7 +1,19 @@
.list-collection { .list-collection {
@extend %list-collection;
height: 500px; height: 500px;
position: relative; position: relative;
} }
.list-collection > ul { %list-collection > ul {
border-top: 1px solid $gray-200;
overflow-x: hidden !important; overflow-x: hidden !important;
} }
%list-collection > ul > li:nth-child(2) .with-feedback p {
bottom: auto;
top: 24px;
}
%list-collection > ul > li:nth-child(2) p::after {
bottom: auto;
top: -10px !important;
border-bottom-width: 18px;
border-top-width: 0;
}

View File

@ -1,8 +1,9 @@
// Services - Linked Services tab // Services - Linked Services tab
.gateway-services-list > ul { // TODO - move this into composite-row
@extend %gateway-services-list; .consul-gateway-services-list > ul {
@extend %consul-gateway-services-list;
} }
%gateway-services-list > li:not(:first-child) { %consul-gateway-services-list > li:not(:first-child) {
@extend %gateway-service-row; @extend %gateway-service-row;
} }
%gateway-service-row { %gateway-service-row {
@ -12,6 +13,7 @@
// Service Detail - Proxy Info tab // Service Detail - Proxy Info tab
.proxy-upstreams > ul { .proxy-upstreams > ul {
@extend %proxy-upstreams-list; @extend %proxy-upstreams-list;
border-top: 1px solid $gray-200;
} }
%proxy-upstreams-list > li { %proxy-upstreams-list > li {
@extend %composite-row; @extend %composite-row;

View File

@ -17,7 +17,7 @@
<ConsulKind @item={{item.Service}} /> <ConsulKind @item={{item.Service}} />
</BlockSlot> </BlockSlot>
<BlockSlot @name="nav"> <BlockSlot @name="nav">
{{#if (or (not item.Service.Kind) (eq item.Service.Kind 'terminating-gateway'))}} {{#if (not-eq item.Service.Kind 'mesh-gateway')}}
<TabNav @items={{ <TabNav @items={{
compact compact
(array (array
@ -25,6 +25,9 @@
(if (eq item.Service.Kind 'terminating-gateway') (if (eq item.Service.Kind 'terminating-gateway')
(hash label="Linked Services" href=(href-to "dc.services.show.services") selected=(is-href "dc.services.show.services")) (hash label="Linked Services" href=(href-to "dc.services.show.services") selected=(is-href "dc.services.show.services"))
'') '')
(if (eq item.Service.Kind 'ingress-gateway')
(hash label="Upstreams" href=(href-to "dc.services.show.upstreams") selected=(is-href "dc.services.show.upstreams"))
'')
(if (not item.Service.Kind) (if (not item.Service.Kind)
(hash label="Intentions" href=(href-to "dc.services.show.intentions") selected=(is-href "dc.services.show.intentions")) (hash label="Intentions" href=(href-to "dc.services.show.intentions") selected=(is-href "dc.services.show.intentions"))
'') '')

View File

@ -4,10 +4,10 @@
<section> <section>
<p> <p>
The following services may receive traffic from external services through this gateway. Learn more about configuring gateways in our The following services may receive traffic from external services through this gateway. Learn more about configuring gateways in our
<a href={{env 'CONSUL_TERMINATING_GATEWAYS_URL'}} target="_blank">step-by-step guide.</a> <a href="{{env 'CONSUL_DOCS_URL'}}/connect/terminating_gateway.html" target="_blank" rel="noopener noreferrer">step-by-step guide.</a>
</p> </p>
<ListCollection @cellHeight={{73}} @items={{gateway.Services}} class="gateway-services-list" as |item index|> <ListCollection @cellHeight={{73}} @items={{gateway.Services}} class="consul-gateway-services-list" as |item index|>
<a data-test-service-name href={{href-to 'dc.services.show' item.Name}} class={{service/health-checks item}}> <a data-test-service-name href={{href-to 'dc.services.show' item.Name}} class={{service/health-checks item}}>
{{item.Name}} {{item.Name}}
</a> </a>

View File

@ -0,0 +1,32 @@
<div id="upstreams" class="tab-section">
<div role="tabpanel">
{{#if (gt gateway.Services.length 0)}}
<section>
<p>
Upstreams are services that may receive traffic from this gateway. Learn more about configuring gateways in our
<a href="{{env 'CONSUL_DOCS_URL'}}/connect/ingress_gateway.html" target="_blank" rel="noopener noreferrer">documentation.</a>
</p>
<ListCollection @cellHeight={{73}} @items={{gateway.Services}} class="consul-gateway-services-list" as |item index|>
<a data-test-service-name href={{href-to 'dc.services.show' item.Name}}>
{{item.Name}}
</a>
<ul>
{{#if (not-eq item.GatewayConfig.ListenerPort 0)}}
<li class="port">
<CopyButton
@value={{item.GatewayConfig.ListenerPort}}
@name="Port"
/>
<span>:{{item.GatewayConfig.ListenerPort}}</span>
</li>
{{/if}}
</ul>
</ListCollection>
</section>
{{else}}
<p>
There are no upstreams.
</p>
{{/if}}
</div>
</div>

View File

@ -81,8 +81,6 @@ module.exports = function(environment, $ = process.env) {
CONSUL_DOCS_LEARN_URL: 'https://learn.hashicorp.com', CONSUL_DOCS_LEARN_URL: 'https://learn.hashicorp.com',
CONSUL_DOCS_API_URL: 'https://www.consul.io/api', CONSUL_DOCS_API_URL: 'https://www.consul.io/api',
CONSUL_COPYRIGHT_URL: 'https://www.hashicorp.com', CONSUL_COPYRIGHT_URL: 'https://www.hashicorp.com',
CONSUL_TERMINATING_GATEWAYS_URL: 'https://www.consul.io/docs/connect/terminating_gateway',
CONSUL_INGRESS_GATEWAYS_URL: 'https://www.consul.io/docs/connect/ingress_gateway',
}); });
const isTestLike = ['staging', 'test'].indexOf(environment) > -1; const isTestLike = ['staging', 'test'].indexOf(environment) > -1;
const isDevLike = ['development', 'staging', 'test'].indexOf(environment) > -1; const isDevLike = ['development', 'staging', 'test'].indexOf(environment) > -1;

View File

@ -1,5 +1,5 @@
@setupApplicationTest @setupApplicationTest
Feature: dc / services / gateway Feature: dc / services / show / services
Background: Background:
Given 1 datacenter model with the value "dc1" Given 1 datacenter model with the value "dc1"
And 1 node models And 1 node models
@ -29,6 +29,29 @@ Feature: dc / services / gateway
And the title should be "terminating-gateway-1 - Consul" And the title should be "terminating-gateway-1 - Consul"
When I click linkedServices on the tabs When I click linkedServices on the tabs
Then I see 3 service models Then I see 3 service models
Scenario: Don't see the Linked Services tab
Given 1 datacenter model with the value "dc1"
And 1 node models
And 1 service model from yaml
---
- Service:
Name: [Name]
Kind: [Kind]
---
When I visit the service page for yaml
---
dc: dc1
service: [Name]
---
And the title should be "[Name] - Consul"
And I don't see linkedServices on the tabs
Where:
---------------------------------------------
| Name | Kind |
| service | ~ |
| ingress-gateway | ingress-gateway |
| mesh-gateway | mesh-gateway |
---------------------------------------------

View File

@ -0,0 +1,54 @@
@setupApplicationTest
Feature: dc / services / show / upstreams
Background:
Given 1 datacenter model with the value "dc1"
And 1 node models
And 1 service model from yaml
---
- Service:
Name: ingress-gateway-1
Kind: ingress-gateway
---
Scenario: Seeing the Upstreams tab
When I visit the service page for yaml
---
dc: dc1
service: ingress-gateway-1
---
And the title should be "ingress-gateway-1 - Consul"
And I see upstreams on the tabs
When I click upstreams on the tabs
And I see upstreamsIsSelected on the tabs
Scenario: Seeing the list of Upstreams
Given 3 service models from yaml
When I visit the service page for yaml
---
dc: dc1
service: ingress-gateway-1
---
And the title should be "ingress-gateway-1 - Consul"
When I click upstreams on the tabs
Then I see 3 service models
Scenario: Don't see the Upstreams tab
Given 1 datacenter model with the value "dc1"
And 1 node models
And 1 service model from yaml
---
- Service:
Name: [Name]
Kind: [Kind]
---
When I visit the service page for yaml
---
dc: dc1
service: [Name]
---
And the title should be "[Name] - Consul"
And I don't see upstreams on the tabs
Where:
---------------------------------------------
| Name | Kind |
| service | ~ |
| terminating-gateway | terminating-gateway |
| mesh-gateway | mesh-gateway |
---------------------------------------------

View File

@ -0,0 +1,10 @@
import steps from '../../../steps';
// step definitions that are shared between features should be moved to the
// tests/acceptance/steps/steps.js file
export default function(assert) {
return steps(assert).then('I should find a file', function() {
assert.ok(true, this.step);
});
}

View File

@ -7,7 +7,14 @@ export default function(visitable, attribute, collection, text, intentions, filt
dashboardAnchor: { dashboardAnchor: {
href: attribute('href', '[data-test-dashboard-anchor]'), href: attribute('href', '[data-test-dashboard-anchor]'),
}, },
tabs: tabs('tab', ['instances', 'linked-services', 'intentions', 'routing', 'tags']), tabs: tabs('tab', [
'instances',
'linked-services',
'upstreams',
'intentions',
'routing',
'tags',
]),
filter: filter, filter: filter,
// TODO: These need to somehow move to subpages // TODO: These need to somehow move to subpages
@ -15,7 +22,7 @@ export default function(visitable, attribute, collection, text, intentions, filt
address: text('[data-test-address]'), address: text('[data-test-address]'),
}), }),
intentions: intentions(), intentions: intentions(),
services: collection('.gateway-services-list> ul > li:not(:first-child)', { services: collection('.consul-gateway-services-list> ul > li:not(:first-child)', {
name: text('[data-test-service-name]'), name: text('[data-test-service-name]'),
}), }),
}; };