NET-5414: sameness group service show (#19586)

Fix viewing peered services on different namespaces
This commit is contained in:
Tyler Wendlandt 2023-11-09 15:25:01 -07:00 committed by GitHub
parent cb86b29e89
commit 7699fb12eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 146 additions and 113 deletions

3
.changelog/19586.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:bug
ui: fix being able to view peered services from non-default namnespaces
```

View File

@ -4,7 +4,6 @@
}} }}
{{#let @list (env "CONSUL_HCP_URL") as |SNL hcpUrl|}} {{#let @list (env "CONSUL_HCP_URL") as |SNL hcpUrl|}}
{{log hcpUrl}}
{{#if (and SNL hcpUrl)}} {{#if (and SNL hcpUrl)}}
<SNL.BackLink <SNL.BackLink
@text={{t "components.hashicorp-consul.side-nav.hcp"}} @text={{t "components.hashicorp-consul.side-nav.hcp"}}

View File

@ -17,37 +17,34 @@
(is-href "dc.nspaces" @dc.Name) (is-href "dc.nspaces" @dc.Name)
as |SNL nspace isManaging| as |SNL nspace isManaging|
}} }}
<SNL.Title class="consul-side-nav__selector-title">{{t "components.hashicorp-consul.side-nav.nspaces.title"}}</SNL.Title> <SNL.Title class="consul-side-nav__selector-title">{{t
"components.hashicorp-consul.side-nav.nspaces.title"
}}</SNL.Title>
<NavSelector <NavSelector
@list={{@list}} @list={{@list}}
@items={{sort-by "Name:asc" (reject-by "DeletedAt" @nspaces)}} @items={{sort-by "Name:asc" (reject-by "DeletedAt" @nspaces)}}
@item={{nspace}} @item={{nspace}}
@key="Name" @key="Name"
@icon="folder" @icon="folder"
@placeholder={{t "components.hashicorp-consul.side-nav.nspaces.placeholder"}} @placeholder={{t
"components.hashicorp-consul.side-nav.nspaces.placeholder"
}}
@footerLink={{href-to "dc.nspaces" @dc.Name}} @footerLink={{href-to "dc.nspaces" @dc.Name}}
@footerLinkText={{t "components.hashicorp-consul.side-nav.nspaces.footer"}} @footerLinkText={{t
"components.hashicorp-consul.side-nav.nspaces.footer"
}}
data-test-nspace-menu data-test-nspace-menu
as |Dropdown item| as |Dropdown item|
> >
<Dropdown.Checkmark <Dropdown.Checkmark
@selected={{eq nspace.Name item.Name}} @selected={{eq nspace.Name item.Name}}
@href={{if @href={{href-to
isManaging "dc.services.index"
(href-to params=(hash
"dc.services.index" partition=(if (gt @partition.length 0) @partition undefined)
params=(hash nspace=item.Name
partition=(if (gt @partition.length 0) @partition undefined) peer=undefined
nspace=item.Name dc=@dc.Name
dc=@dc.Name
)
)
(href-to
"."
params=(hash
partition=(if (gt @partition.length 0) @partition undefined)
nspace=item.Name
)
) )
}} }}
@isHrefExternal={{false}} @isHrefExternal={{false}}

View File

@ -14,16 +14,22 @@
@src={{uri "/*/*/${dc}/partitions" (hash dc=@dc.Name)}} @src={{uri "/*/*/${dc}/partitions" (hash dc=@dc.Name)}}
@onchange={{fn (optional @onchange)}} @onchange={{fn (optional @onchange)}}
/> />
<SNL.Title class="consul-side-nav__selector-title">{{t "components.hashicorp-consul.side-nav.partitions.title"}}</SNL.Title> <SNL.Title class="consul-side-nav__selector-title">{{t
"components.hashicorp-consul.side-nav.partitions.title"
}}</SNL.Title>
<NavSelector <NavSelector
@list={{@list}} @list={{@list}}
@items={{sort-by "Name:asc" (reject-by "DeletedAt" @partitions)}} @items={{sort-by "Name:asc" (reject-by "DeletedAt" @partitions)}}
@item={{partition}} @item={{partition}}
@key="Name" @key="Name"
@icon="users" @icon="users"
@placeholder={{t "components.hashicorp-consul.side-nav.partitions.placeholder"}} @placeholder={{t
"components.hashicorp-consul.side-nav.partitions.placeholder"
}}
@footerLink={{href-to "dc.partitions" @dc.Name}} @footerLink={{href-to "dc.partitions" @dc.Name}}
@footerLinkText={{t "components.hashicorp-consul.side-nav.partitions.footer"}} @footerLinkText={{t
"components.hashicorp-consul.side-nav.partitions.footer"
}}
@disabled={{not canChoose}} @disabled={{not canChoose}}
data-test-datacenter-disclosure-menu data-test-datacenter-disclosure-menu
as |Dropdown item| as |Dropdown item|
@ -34,13 +40,9 @@
@href={{if @href={{if
item.href item.href
item.href item.href
(if (href-to
isManaging "dc.services.index"
(href-to params=(hash partition=item.Name nspace=undefined peer=undefined dc=@dc.Name)
"dc.services.index"
params=(hash partition=item.Name nspace=undefined dc=@dc.Name)
)
(href-to "." params=(hash partition=item.Name nspace=undefined))
) )
}} }}
@isHrefExternal={{false}} @isHrefExternal={{false}}
@ -50,4 +52,4 @@
</Dropdown.Checkmark> </Dropdown.Checkmark>
{{/if}} {{/if}}
</NavSelector> </NavSelector>
{{/let}} {{/let}}

View File

@ -83,6 +83,7 @@
<Consul::Service::List <Consul::Service::List
@items={{collection.items}} @items={{collection.items}}
@partition={{partition}} @partition={{partition}}
@nspace={{nspace}}
@isPeerDetail={{true}} @isPeerDetail={{true}}
/> />
</collection.Collection> </collection.Collection>

View File

@ -10,85 +10,5 @@
@linkable='linkable service' @linkable='linkable service'
as |item index| as |item index|
> >
<BlockSlot @name='header'> <Consul::Service::List::Item @item={{item}} @partition={{@partition}} @nspace={{@nspace}} />
<dl class={{item.MeshStatus}}>
<dt>
Health
</dt>
<dd {{tooltip item.healthTooltipText}}></dd>
</dl>
{{#if (gt item.InstanceCount 0)}}
<a
data-test-service-name
href={{href-to
'dc.services.show.index'
item.Name
params=(if
(not-eq item.Partition @partition)
(hash partition=item.Partition nspace=item.Namespace peer=item.PeerName)
(hash peer=item.PeerName)
)
}}
>
{{item.Name}}
</a>
{{else}}
<p data-test-service-name>
{{item.Name}}
</p>
{{/if}}
</BlockSlot>
<BlockSlot @name='details'>
<Consul::Kind @item={{item}} />
<Consul::ExternalSource @item={{item}} />
{{#if
(and
(not-eq item.InstanceCount 0)
(and (not-eq item.Kind 'terminating-gateway') (not-eq item.Kind 'ingress-gateway'))
)
}}
<span>
{{format-number item.InstanceCount}}
{{pluralize item.InstanceCount 'instance' without-count=true}}
</span>
{{/if}}
{{! we are displaying imported-services - don't show bucket-list }}
{{#unless @isPeerDetail}}
<Consul::Bucket::List @item={{item}} @nspace={{@nspace}} @partition={{@partition}} />
{{/unless}}
{{#if (eq item.Kind 'terminating-gateway')}}
<span data-test-associated-service-count>
{{format-number item.GatewayConfig.AssociatedServiceCount}}
{{pluralize item.GatewayConfig.AssociatedServiceCount 'linked service' without-count=true}}
</span>
{{else if (eq item.Kind 'ingress-gateway')}}
<span data-test-associated-service-count>
{{format-number item.GatewayConfig.AssociatedServiceCount}}
{{pluralize item.GatewayConfig.AssociatedServiceCount 'upstream' without-count=true}}
</span>
{{/if}}
{{#if (or item.ConnectedWithGateway item.ConnectedWithProxy)}}
<dl class='mesh'>
<dt>
<Tooltip>
This service uses a proxy for the Consul service mesh
</Tooltip>
</dt>
{{#if (and item.ConnectedWithGateway item.ConnectedWithProxy)}}
<dd data-test-mesh>
in service mesh with proxy and gateway
</dd>
{{else if item.ConnectedWithProxy}}
<dd data-test-mesh>
in service mesh with proxy
</dd>
{{else if item.ConnectedWithGateway}}
<dd data-test-mesh>
in service mesh with gateway
</dd>
{{/if}}
</dl>
{{/if}}
<TagList @item={{item}} />
</BlockSlot>
</ListCollection> </ListCollection>

View File

@ -0,0 +1,82 @@
{{!
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: BUSL-1.1
}}
<BlockSlot @name='header'>
<dl class={{@item.MeshStatus}}>
<dt>
Health
</dt>
<dd {{tooltip @item.healthTooltipText}}></dd>
</dl>
{{#if (gt @item.InstanceCount 0)}}
<a
data-test-service-name
href={{href-to
'dc.services.show.index'
@item.Name
params=this.linkParams
}}
>
{{@item.Name}}
</a>
{{else}}
<p data-test-service-name>
{{@item.Name}}
</p>
{{/if}}
</BlockSlot>
<BlockSlot @name='details'>
<Consul::Kind @item={{@item}} />
<Consul::ExternalSource @item={{@item}} />
{{#if
(and
(not-eq @item.InstanceCount 0)
(and (not-eq @item.Kind 'terminating-gateway') (not-eq @item.Kind 'ingress-gateway'))
)
}}
<span>
{{format-number @item.InstanceCount}}
{{pluralize @item.InstanceCount 'instance' without-count=true}}
</span>
{{/if}}
{{! we are displaying imported-services - don't show bucket-list }}
{{#unless @isPeerDetail}}
<Consul::Bucket::List @item={{@item}} @nspace={{@nspace}} @partition={{@partition}} />
{{/unless}}
{{#if (eq @item.Kind 'terminating-gateway')}}
<span data-test-associated-service-count>
{{format-number @item.GatewayConfig.AssociatedServiceCount}}
{{pluralize @item.GatewayConfig.AssociatedServiceCount 'linked service' without-count=true}}
</span>
{{else if (eq @item.Kind 'ingress-gateway')}}
<span data-test-associated-service-count>
{{format-number @item.GatewayConfig.AssociatedServiceCount}}
{{pluralize @item.GatewayConfig.AssociatedServiceCount 'upstream' without-count=true}}
</span>
{{/if}}
{{#if (or @item.ConnectedWithGateway @item.ConnectedWithProxy)}}
<dl class='mesh'>
<dt>
<Tooltip>
This service uses a proxy for the Consul service mesh
</Tooltip>
</dt>
{{#if (and @item.ConnectedWithGateway @item.ConnectedWithProxy)}}
<dd data-test-mesh>
in service mesh with proxy and gateway
</dd>
{{else if @item.ConnectedWithProxy}}
<dd data-test-mesh>
in service mesh with proxy
</dd>
{{else if @item.ConnectedWithGateway}}
<dd data-test-mesh>
in service mesh with gateway
</dd>
{{/if}}
</dl>
{{/if}}
<TagList @item={{@item}} />
</BlockSlot>

View File

@ -0,0 +1,25 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: BUSL-1.1
*/
import Component from '@glimmer/component';
export default class ConsulServiceListItem extends Component {
get linkParams() {
const hash = {};
if (this.args.item.Partition && this.args.partition !== this.args.item.Partition) {
hash.partition = this.args.item.Partition;
hash.nspace = this.args.Namespace;
} else if (this.args.item.Namespace && this.args.nspace !== this.args.item.Namespace) {
hash.nspace = this.args.item.Namespace;
}
if (this.args.item.PeerName) {
hash.peer = this.args.item.PeerName;
}
return hash;
}
}

View File

@ -149,7 +149,10 @@ export default class FSMWithOptionalLocation {
url = this.getURLFrom(url) url = this.getURLFrom(url)
.split('/') .split('/')
.filter((item, i) => { .filter((item, i) => {
if (i < 3) { // the max optional parameters we have is 3 (partition, namespace, peer). When we split the path
// by '/' it has a prefixed empty '' in the array. So we know we only have to check up to the 4th
// index for optional parameters.
if (i < 4) {
let found = false; let found = false;
Object.entries(OPTIONAL).reduce((prev, [key, re]) => { Object.entries(OPTIONAL).reduce((prev, [key, re]) => {
const res = re.exec(item); const res = re.exec(item);

View File

@ -101,6 +101,7 @@ as |sort filters items partition nspace|}}
<Consul::Service::List <Consul::Service::List
@items={{collection.items}} @items={{collection.items}}
@partition={{partition}} @partition={{partition}}
@nspace={{nspace}}
> >
</Consul::Service::List> </Consul::Service::List>
</collection.Collection> </collection.Collection>