ui: [BUGFIX] Request intention listing with ns parameter (#9432)
This PR adds the ns=* query parameter when namespaces are enabled to keep backwards compatibility with how the UI used to work (Intentions page always lists all intention across all namespace you have access to) I found a tiny dev bug for printing out the current URL during acceptance testing and fixed that up while I was there.
This commit is contained in:
parent
1dcf7fe0f8
commit
7a21bd7720
|
@ -0,0 +1,4 @@
|
|||
```release-note:bug
|
||||
ui: request intention listing with ns=* parameter to retrieve all intentions
|
||||
across namespaces
|
||||
```
|
|
@ -2,12 +2,16 @@ import Adapter, { DATACENTER_QUERY_PARAM as API_DATACENTER_KEY } from './applica
|
|||
import { get } from '@ember/object';
|
||||
import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc';
|
||||
|
||||
// Intentions use SourceNS and DestinationNS properties for namespacing so we
|
||||
// don't need to add the `?ns=` anywhere here
|
||||
// Intentions have different namespacing to the rest of the UI in that the don't
|
||||
// have a Namespace property, the DestinationNS is essentially its namespace.
|
||||
// Listing of intentions still requires the `ns` query string parameter which
|
||||
// will give us all the intentions that have the `ns` as either the SourceNS or
|
||||
// the DestinationNS.
|
||||
// We currently list intentions by the * wildcard namespace for back compat reasons
|
||||
|
||||
// TODO: Update to use this.formatDatacenter()
|
||||
export default class IntentionAdapter extends Adapter {
|
||||
requestForQuery(request, { dc, filter, index, uri }) {
|
||||
requestForQuery(request, { dc, ns, filter, index, uri }) {
|
||||
return request`
|
||||
GET /v1/connect/intentions?${{ dc }}
|
||||
X-Request-ID: ${uri}${
|
||||
|
@ -18,6 +22,7 @@ export default class IntentionAdapter extends Adapter {
|
|||
}
|
||||
|
||||
${{
|
||||
...this.formatNspace('*'),
|
||||
index,
|
||||
filter,
|
||||
}}
|
||||
|
|
|
@ -72,7 +72,7 @@ as |api|>
|
|||
{{/if}}
|
||||
|
||||
<DataSource
|
||||
@src={{concat '/' @nspace '/' @dc '/services'}}
|
||||
@src={{concat '/*/' @dc '/services'}}
|
||||
@onchange={{action this.createServices item}}
|
||||
/>
|
||||
{{#if (env 'CONSUL_NSPACES_ENABLED')}}
|
||||
|
|
|
@ -1,24 +1,30 @@
|
|||
import { inject as service } from '@ember/service';
|
||||
import Route from 'consul-ui/routing/route';
|
||||
import { hash } from 'rsvp';
|
||||
|
||||
export default class EditRoute extends Route {
|
||||
@service('repository/intention')
|
||||
repo;
|
||||
@service('repository/intention') repo;
|
||||
@service('env') env;
|
||||
|
||||
model({ intention_id }, transition) {
|
||||
async model({ intention_id }, transition) {
|
||||
const dc = this.modelFor('dc').dc.Name;
|
||||
const nspace = '*';
|
||||
return hash({
|
||||
dc: dc,
|
||||
nspace: nspace,
|
||||
item:
|
||||
typeof intention_id !== 'undefined'
|
||||
? this.repo.findBySlug(intention_id, dc, nspace)
|
||||
: this.repo.create({
|
||||
Datacenter: dc,
|
||||
}),
|
||||
});
|
||||
const nspace = this.modelFor('nspace').nspace.substr(1);
|
||||
|
||||
let item;
|
||||
if (typeof intention_id !== 'undefined') {
|
||||
item = await this.repo.findBySlug(intention_id, dc, nspace);
|
||||
} else {
|
||||
const defaultNspace = this.env.var('CONSUL_NSPACES_ENABLED') ? '*' : 'default';
|
||||
item = await this.repo.create({
|
||||
SourceNS: nspace || defaultNspace,
|
||||
DestinationNS: nspace || defaultNspace,
|
||||
Datacenter: dc,
|
||||
});
|
||||
}
|
||||
return {
|
||||
dc,
|
||||
nspace,
|
||||
item,
|
||||
};
|
||||
}
|
||||
|
||||
setupController(controller, model) {
|
||||
|
|
|
@ -17,7 +17,7 @@ export default class IndexRoute extends Route {
|
|||
model(params) {
|
||||
return {
|
||||
dc: this.modelFor('dc').dc.Name,
|
||||
nspace: this.modelFor('nspace').nspace.substr(1) || 'default',
|
||||
nspace: this.modelFor('nspace').nspace.substr(1),
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ export default class RepositoryService extends Service {
|
|||
if (dc === meta.dc) {
|
||||
if (checkNspace) {
|
||||
const nspace = get(item, 'Namespace');
|
||||
if (nspace !== meta.namespace) {
|
||||
if (typeof nspace !== 'undefined' && nspace !== meta.nspace) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,51 @@ Feature: dc / intentions / create: Intention Create
|
|||
In order to define intentions
|
||||
As a user
|
||||
I want to visit the intention create page, fill in the form and hit the create button and see a success notification
|
||||
Scenario:
|
||||
@onlyNamespaceable
|
||||
Scenario: with namespaces enabled
|
||||
Given 1 datacenter model with the value "datacenter"
|
||||
And 3 service models from yaml
|
||||
---
|
||||
- Name: web
|
||||
Kind: ~
|
||||
- Name: db
|
||||
Kind: ~
|
||||
- Name: cache
|
||||
Kind: ~
|
||||
---
|
||||
When I visit the intention page for yaml
|
||||
---
|
||||
dc: datacenter
|
||||
---
|
||||
Then the url should be /datacenter/intentions/create
|
||||
And the title should be "New Intention - Consul"
|
||||
# Set source
|
||||
And I click "[data-test-source-element] .ember-power-select-trigger"
|
||||
And I type "web" into ".ember-power-select-search-input"
|
||||
And I click ".ember-power-select-option:first-child"
|
||||
Then I see the text "web" in "[data-test-source-element] .ember-power-select-selected-item"
|
||||
# Set destination
|
||||
And I click "[data-test-destination-element] .ember-power-select-trigger"
|
||||
And I type "db" into ".ember-power-select-search-input"
|
||||
And I click ".ember-power-select-option:first-child"
|
||||
Then I see the text "db" in "[data-test-destination-element] .ember-power-select-selected-item"
|
||||
# Specifically set deny
|
||||
And I click "[value=deny]"
|
||||
And I submit
|
||||
# TODO: When namespace is empty we expect *
|
||||
# Then a PUT request was made to "/v1/connect/intentions/exact?source=@namespace%2Fweb&destination=@namespace%2Fdb&dc=datacenter" from yaml
|
||||
# ---
|
||||
# body:
|
||||
# SourceName: web
|
||||
# DestinationName: db
|
||||
# Action: deny
|
||||
# ---
|
||||
Then the url should be /datacenter/intentions
|
||||
And the title should be "Intentions - Consul"
|
||||
And "[data-notification]" has the "notification-update" class
|
||||
And "[data-notification]" has the "success" class
|
||||
@notNamespaceable
|
||||
Scenario: with namespaces disabled
|
||||
Given 1 datacenter model with the value "datacenter"
|
||||
And 3 service models from yaml
|
||||
---
|
||||
|
|
|
@ -1,17 +1,35 @@
|
|||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import getNspaceRunner from 'consul-ui/tests/helpers/get-nspace-runner';
|
||||
|
||||
const nspaceRunner = getNspaceRunner('intention');
|
||||
|
||||
module('Integration | Adapter | intention', function(hooks) {
|
||||
setupTest(hooks);
|
||||
const dc = 'dc-1';
|
||||
const id = 'SourceNS:SourceName:DestinationNS:DestinationName';
|
||||
test('requestForQuery returns the correct url', function(assert) {
|
||||
const adapter = this.owner.lookup('adapter:intention');
|
||||
const client = this.owner.lookup('service:client/http');
|
||||
const expected = `GET /v1/connect/intentions?dc=${dc}`;
|
||||
const actual = adapter.requestForQuery(client.requestParams.bind(client), {
|
||||
dc: dc,
|
||||
});
|
||||
assert.equal(`${actual.method} ${actual.url}`, expected);
|
||||
return nspaceRunner(
|
||||
(adapter, serializer, client) => {
|
||||
return adapter.requestForQuery(client.body, {
|
||||
dc: dc,
|
||||
ns: 'team-1',
|
||||
filter: '*',
|
||||
index: 1,
|
||||
});
|
||||
},
|
||||
{
|
||||
filter: '*',
|
||||
index: 1,
|
||||
ns: '*',
|
||||
},
|
||||
{
|
||||
filter: '*',
|
||||
index: 1,
|
||||
},
|
||||
this,
|
||||
assert
|
||||
);
|
||||
});
|
||||
test('requestForQueryRecord returns the correct url', function(assert) {
|
||||
const adapter = this.owner.lookup('adapter:intention');
|
||||
|
|
|
@ -102,7 +102,7 @@ export default function({
|
|||
visit(library, pages, utils.setCurrentPage, reset);
|
||||
click(library, utils.find, helpers.click);
|
||||
form(library, utils.find, helpers.fillIn, helpers.triggerKeyEvent, utils.getCurrentPage);
|
||||
debug(library, assert, utils.currentURL);
|
||||
debug(library, assert, helpers.currentURL);
|
||||
assertHttp(library, assert, lastNthRequest);
|
||||
assertModel(library, assert, utils.find, utils.getCurrentPage, pauseUntil, pluralize);
|
||||
assertPage(library, assert, utils.find, utils.getCurrentPage, $);
|
||||
|
|
Loading…
Reference in New Issue