From 049ca102c41fbf646b07e34f5f69f652de9fbc6c Mon Sep 17 00:00:00 2001 From: Valeriia Ruban Date: Fri, 26 Jan 2024 09:57:18 -0800 Subject: [PATCH] Cc 7145 hcp link status api (#20330) * feat: add api call to hcp/link endpoint * updated * updated * update approach to get the linking status * updated application template * feat: add api call to hcp/link endpoint * updated * updated * update approach to get the linking status * updated application template * update purple banner links * Hook up the linked check to the purple banner * fixed lint issue * Updated tests for new link status API calls as args instead of from service --------- Co-authored-by: Chris Hut --- .../components/link-to-hcp-banner/index.hbs | 2 +- .../components/link-to-hcp-banner/index.js | 4 ++ .../consul-ui/app/services/hcp-link-status.js | 4 +- .../app/services/repository/hcp-link.js | 42 +++++++++++++++++++ .../consul-ui/app/templates/application.hbs | 36 ++++++++-------- .../app/templates/dc/services/index.hbs | 6 ++- .../consul-ui/mock-api/api/hcp/v2/link/global | 16 +++++++ .../components/link-to-hcp-banner-test.js | 39 +++++++++++++---- 8 files changed, 119 insertions(+), 30 deletions(-) create mode 100644 ui/packages/consul-ui/app/services/repository/hcp-link.js create mode 100644 ui/packages/consul-ui/mock-api/api/hcp/v2/link/global diff --git a/ui/packages/consul-ui/app/components/link-to-hcp-banner/index.hbs b/ui/packages/consul-ui/app/components/link-to-hcp-banner/index.hbs index 950c30c945..39dd933c91 100644 --- a/ui/packages/consul-ui/app/components/link-to-hcp-banner/index.hbs +++ b/ui/packages/consul-ui/app/components/link-to-hcp-banner/index.hbs @@ -2,7 +2,7 @@ Copyright (c) HashiCorp, Inc. SPDX-License-Identifier: BUSL-1.1 }} -{{#if this.hcpLinkStatus.shouldDisplayBanner}} +{{#if (and this.hcpLinkStatus.shouldDisplayBanner this.notLinked)}} {{t "components.link-to-hcp-banner.title"}} diff --git a/ui/packages/consul-ui/app/components/link-to-hcp-banner/index.js b/ui/packages/consul-ui/app/components/link-to-hcp-banner/index.js index 3d0c96f2fa..9416cfbafb 100644 --- a/ui/packages/consul-ui/app/components/link-to-hcp-banner/index.js +++ b/ui/packages/consul-ui/app/components/link-to-hcp-banner/index.js @@ -11,6 +11,10 @@ export default class LinkToHcpBannerComponent extends Component { @service('hcp-link-status') hcpLinkStatus; @service('env') env; + get notLinked() { + return this.args.linkData?.isLinked === false; + } + @action onDismiss() { this.hcpLinkStatus.dismissHcpLinkBanner(); diff --git a/ui/packages/consul-ui/app/services/hcp-link-status.js b/ui/packages/consul-ui/app/services/hcp-link-status.js index 4fec7f5bab..cf03d8fc98 100644 --- a/ui/packages/consul-ui/app/services/hcp-link-status.js +++ b/ui/packages/consul-ui/app/services/hcp-link-status.js @@ -9,13 +9,11 @@ import { tracked } from '@glimmer/tracking'; const LOCAL_STORAGE_KEY = 'consul:hideHcpLinkBanner'; export default class HcpLinkStatus extends Service { - @tracked - alreadyLinked = false; @tracked userDismissedBanner = false; get shouldDisplayBanner() { - return !this.alreadyLinked && !this.userDismissedBanner; + return !this.userDismissedBanner; } constructor() { diff --git a/ui/packages/consul-ui/app/services/repository/hcp-link.js b/ui/packages/consul-ui/app/services/repository/hcp-link.js new file mode 100644 index 0000000000..f82296cd09 --- /dev/null +++ b/ui/packages/consul-ui/app/services/repository/hcp-link.js @@ -0,0 +1,42 @@ +/** + * Copyright (c) HashiCorp, Inc. + * SPDX-License-Identifier: BUSL-1.1 + */ + +import RepositoryService from 'consul-ui/services/repository'; +import dataSource from 'consul-ui/decorators/data-source'; + +export default class HcpLinkService extends RepositoryService { + @dataSource('/:partition/:ns/:dc/hcp-link') + async fetch({ partition, ns, dc }, { uri }, request) { + let result; + try { + result = ( + await request` + GET /api/hcp/v2/link/global + ` + )((headers, body) => { + return { + meta: { + version: 2, + uri: uri, + }, + body: { + isLinked: (body.status['consul.io/hcp/link']['conditions'] || []).some( + (condition) => condition.type === 'linked' && condition.state === 'STATE_TRUE' + ), + }, + headers, + }; + }); + } catch (e) { + // set linked to false if the global link is not found + if (e.statusCode === 404) { + result = Promise.resolve({ isLinked: false }); + } else { + result = Promise.resolve(null); + } + } + return result; + } +} diff --git a/ui/packages/consul-ui/app/templates/application.hbs b/ui/packages/consul-ui/app/templates/application.hbs index 7be739bf64..bab98e7b1f 100644 --- a/ui/packages/consul-ui/app/templates/application.hbs +++ b/ui/packages/consul-ui/app/templates/application.hbs @@ -43,18 +43,18 @@ {{#if (not-eq route.currentName 'oauth-provider-debug')}} - {{! redirect if we aren't on a URL with dc information }} + {{! redirect if we aren't on a URL with dc information }} {{#if (eq route.currentName 'index')}} - {{! until we get to the dc route we don't know any permissions }} - {{! as we don't know the dc, any inital permission based }} - {{! redirects are in the dc.show route}} + {{! until we get to the dc route we don't know any permissions }} + {{! as we don't know the dc, any inital permission based }} + {{! redirects are in the dc.show route}} - {{! 2022-04-15: Temporarily reverting the services page to the default }} + {{! 2022-04-15: Temporarily reverting the services page to the default }} {{did-insert (route-action 'replaceWith' 'dc.services.index' (hash dc=(env 'CONSUL_DATACENTER_LOCAL'))) }} {{else}} - {{! If we are notfound, guess the params we need }} + {{! If we are notfound, guess the params we need }} {{#if (eq route.currentName 'notfound')}} {{! Once we have a list of DCs make sure the DC we are asking for exists }} {{! If not use the DC that the UI is running in }} @@ -85,20 +85,20 @@ (hash Name=(env 'CONSUL_DATACENTER_LOCAL')) ) dcs.data - as |dc dcs| + as |dc dcs| }} {{#if (and (gt dc.Name.length 0) dcs)}} - {{! figure out our current DC and convert it to a model }} + {{! figure out our current DC and convert it to a model }} {{#if dc.data}} - {{#if error}} - {{! If we got an error from anything, show an error page }} + {{! If we got an error from anything, show an error page }} {{else}} - {{! Otherwise show the rest of the app}} + {{! Otherwise show the rest of the app}} {{outlet}} diff --git a/ui/packages/consul-ui/app/templates/dc/services/index.hbs b/ui/packages/consul-ui/app/templates/dc/services/index.hbs index 7f33e16c6a..0a7e2b97b1 100644 --- a/ui/packages/consul-ui/app/templates/dc/services/index.hbs +++ b/ui/packages/consul-ui/app/templates/dc/services/index.hbs @@ -62,7 +62,11 @@ as |route|> (or route.params.nspace route.model.user.token.Namespace 'default') as |sort filters items partition nspace|}} - +{{#let route.params.dc as |dc|}} + + + +{{/let}}

diff --git a/ui/packages/consul-ui/mock-api/api/hcp/v2/link/global b/ui/packages/consul-ui/mock-api/api/hcp/v2/link/global new file mode 100644 index 0000000000..873f854c20 --- /dev/null +++ b/ui/packages/consul-ui/mock-api/api/hcp/v2/link/global @@ -0,0 +1,16 @@ +{ + "status": { + "consul.io/hcp/link": { + "conditions": [ + { + "message": "Successfully linked to cluster 'organization/f53e5646-6529-4698-ae29-d74f8bd22a01/project/6994bb7a-5561-4d5c-8bb0-cf40177e5b77/hashicorp.consul.global-network-manager.cluster/mkam-vm'", + "reason": "SUCCESS", + "state": "STATE_FALSE", + "type": "linked" + } + ], + "observedGeneration":"01HMA2VPHVKNF6QR8TD07KDN5K", + "updatedAt":"2024-01-16T21:29:25.923140Z" + } + } +} \ No newline at end of file diff --git a/ui/packages/consul-ui/tests/integration/components/link-to-hcp-banner-test.js b/ui/packages/consul-ui/tests/integration/components/link-to-hcp-banner-test.js index d20646bf34..54c7dd064e 100644 --- a/ui/packages/consul-ui/tests/integration/components/link-to-hcp-banner-test.js +++ b/ui/packages/consul-ui/tests/integration/components/link-to-hcp-banner-test.js @@ -11,7 +11,6 @@ import Service from '@ember/service'; import sinon from 'sinon'; const userDismissedBannerStub = sinon.stub(); -const userHasLinkedStub = sinon.stub(); const dismissHcpLinkBannerStub = sinon.stub(); const bannerSelector = '[data-test-link-to-hcp-banner]'; module('Integration | Component | link-to-hcp-banner', function (hooks) { @@ -22,7 +21,6 @@ module('Integration | Component | link-to-hcp-banner', function (hooks) { return true; } userDismissedBanner = userDismissedBannerStub; - userHasLinked = userHasLinkedStub; dismissHcpLinkBanner = dismissHcpLinkBannerStub; } @@ -39,7 +37,8 @@ module('Integration | Component | link-to-hcp-banner', function (hooks) { }); test('it renders banner when hcp-link-status says it should', async function (assert) { - await render(hbs``); + this.linkData = { isLinked: false }; + await render(hbs``); assert.dom(bannerSelector).exists({ count: 1 }); await click(`${bannerSelector} button[aria-label="Dismiss"]`); @@ -62,12 +61,37 @@ module('Integration | Component | link-to-hcp-banner', function (hooks) { get shouldDisplayBanner() { return false; } - userDismissedBanner = sinon.stub(); - userHasLinked = sinon.stub(); dismissHcpLinkBanner = sinon.stub(); } this.owner.register('service:hcp-link-status', HcpLinkStatusStub); - await render(hbs``); + this.linkData = { isLinked: false }; + await render(hbs``); + assert.dom(bannerSelector).doesNotExist(); + }); + + test('banner does not render when cluster is already linked', async function (assert) { + class HcpLinkStatusStub extends Service { + get shouldDisplayBanner() { + return true; + } + dismissHcpLinkBanner = sinon.stub(); + } + this.owner.register('service:hcp-link-status', HcpLinkStatusStub); + this.linkData = { isLinked: true }; + await render(hbs``); + assert.dom(bannerSelector).doesNotExist(); + }); + + test('banner does not render when we have no cluster link status info', async function (assert) { + class HcpLinkStatusStub extends Service { + get shouldDisplayBanner() { + return true; + } + dismissHcpLinkBanner = sinon.stub(); + } + this.owner.register('service:hcp-link-status', HcpLinkStatusStub); + this.linkData = undefined; + await render(hbs``); assert.dom(bannerSelector).doesNotExist(); }); @@ -79,7 +103,8 @@ module('Integration | Component | link-to-hcp-banner', function (hooks) { } } this.owner.register('service:env', EnvStub); - await render(hbs``); + this.linkData = { isLinked: false }; + await render(hbs``); assert .dom('[data-test-link-to-hcp-banner-description]') .hasText(