ui: Move ember-data classes to use native JS classes/decorators (#9136)

* ui: Upgrade ember-data models to use native classes/decorators

* ui: Update remaining ember-data imports

* ui: Move ember-data Adapters to use native classes

* ui: Upgrade serializers to native classes/decorators

* ui: remove meta from roles, they never had it to start with
This commit is contained in:
John Cowen 2020-11-09 17:29:12 +00:00 committed by GitHub
parent e79c586fc4
commit 5c18dc099f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
59 changed files with 1008 additions and 939 deletions

View File

@ -4,16 +4,17 @@ import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc';
// The old ACL system doesn't support the `ns=` query param
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
requestForQuery: function(request, { dc, index }) {
export default class AclAdapter extends Adapter {
requestForQuery(request, { dc, index }) {
// https://www.consul.io/api/acl.html#list-acls
return request`
GET /v1/acl/list?${{ dc }}
${{ index }}
`;
},
requestForQueryRecord: function(request, { dc, index, id }) {
}
requestForQueryRecord(request, { dc, index, id }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -23,16 +24,18 @@ export default Adapter.extend({
${{ index }}
`;
},
requestForCreateRecord: function(request, serialized, data) {
}
requestForCreateRecord(request, serialized, data) {
// https://www.consul.io/api/acl.html#create-acl-token
return request`
PUT /v1/acl/create?${{ [API_DATACENTER_KEY]: data[DATACENTER_KEY] }}
${serialized}
`;
},
requestForUpdateRecord: function(request, serialized, data) {
}
requestForUpdateRecord(request, serialized, data) {
// the id is in the data, don't add it into the URL
// https://www.consul.io/api/acl.html#update-acl-token
return request`
@ -40,20 +43,23 @@ export default Adapter.extend({
${serialized}
`;
},
requestForDeleteRecord: function(request, serialized, data) {
}
requestForDeleteRecord(request, serialized, data) {
// https://www.consul.io/api/acl.html#delete-acl-token
return request`
PUT /v1/acl/destroy/${data[SLUG_KEY]}?${{ [API_DATACENTER_KEY]: data[DATACENTER_KEY] }}
`;
},
requestForCloneRecord: function(request, serialized, data) {
}
requestForCloneRecord(request, serialized, data) {
// https://www.consul.io/api/acl.html#clone-acl-token
return request`
PUT /v1/acl/clone/${data[SLUG_KEY]}?${{ [API_DATACENTER_KEY]: data[DATACENTER_KEY] }}
`;
},
clone: function(store, type, id, snapshot) {
}
clone(store, type, id, snapshot) {
return this.rpc(
function(adapter, request, serialized, unserialized) {
return adapter.requestForCloneRecord(request, serialized, unserialized);
@ -64,5 +70,5 @@ export default Adapter.extend({
snapshot,
type.modelName
);
},
});
}
}

View File

@ -3,17 +3,20 @@ import { inject as service } from '@ember/service';
export const DATACENTER_QUERY_PARAM = 'dc';
export const NSPACE_QUERY_PARAM = 'ns';
export default Adapter.extend({
client: service('client/http'),
env: service('env'),
formatNspace: function(nspace) {
export default class ApplicationAdapter extends Adapter {
@service('client/http') client;
@service('env') env;
formatNspace(nspace) {
if (this.env.env('CONSUL_NSPACES_ENABLED')) {
return nspace !== '' ? { [NSPACE_QUERY_PARAM]: nspace } : undefined;
}
},
formatDatacenter: function(dc) {
}
formatDatacenter(dc) {
return {
[DATACENTER_QUERY_PARAM]: dc,
};
},
});
}
}

View File

@ -1,12 +1,12 @@
import Adapter from './application';
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
requestForQuery: function(request, { dc, index, uri }) {
export default class CoordinateAdapter extends Adapter {
requestForQuery(request, { dc, index, uri }) {
return request`
GET /v1/coordinate/nodes?${{ dc }}
X-Request-ID: ${uri}
${{ index }}
`;
},
});
}
}

View File

@ -1,9 +1,9 @@
import Adapter from './application';
export default Adapter.extend({
requestForQuery: function(request) {
export default class DcAdapter extends Adapter {
requestForQuery(request) {
return request`
GET /v1/catalog/datacenters
`;
},
});
}
}

View File

@ -1,8 +1,8 @@
import Adapter from './application';
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
requestForQueryRecord: function(request, { dc, ns, index, id, uri }) {
export default class DiscoveryChainAdapter extends Adapter {
requestForQueryRecord(request, { dc, ns, index, id, uri }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -15,5 +15,5 @@ export default Adapter.extend({
index,
}}
`;
},
});
}
}

View File

@ -1,7 +1,7 @@
import { inject as service } from '@ember/service';
import Adapter from 'ember-data/adapter';
import AdapterError from '@ember-data/adapter/error';
import Adapter from '@ember-data/adapter';
import {
AdapterError,
AbortError,
TimeoutError,
ServerError,
@ -10,7 +10,7 @@ import {
NotFoundError,
ConflictError,
InvalidError,
} from 'ember-data/adapters/errors';
} from '@ember-data/adapter/error';
// TODO These are now exactly the same, apart from the fact that one uses
// `serialized, unserialized` and the other just `query`
@ -40,9 +40,10 @@ const write = function(adapter, modelName, type, snapshot) {
modelName
);
};
export default Adapter.extend({
client: service('client/http'),
rpc: function(req, resp, obj, modelName) {
export default class HttpAdapter extends Adapter {
@service('client/http') client;
rpc(req, resp, obj, modelName) {
const client = this.client;
const store = this.store;
const adapter = this;
@ -79,8 +80,9 @@ export default Adapter.extend({
// .catch(function(e) {
// return Promise.reject(e);
// });
},
error: function(err) {
}
error(err) {
if (err instanceof TypeError) {
throw err;
}
@ -132,23 +134,29 @@ export default Adapter.extend({
// Consider changing this to return the error and then
// throw from the call site instead
throw error;
},
query: function(store, type, query) {
}
query(store, type, query) {
return read(this, type.modelName, 'Query', query);
},
queryRecord: function(store, type, query) {
}
queryRecord(store, type, query) {
return read(this, type.modelName, 'QueryRecord', query);
},
findAll: function(store, type) {
}
findAll(store, type) {
return read(this, type.modelName, 'FindAll');
},
createRecord: function(store, type, snapshot) {
}
createRecord(store, type, snapshot) {
return write(this, type.modelName, 'CreateRecord', snapshot);
},
updateRecord: function(store, type, snapshot) {
}
updateRecord(store, type, snapshot) {
return write(this, type.modelName, 'UpdateRecord', snapshot);
},
deleteRecord: function(store, type, snapshot) {
}
deleteRecord(store, type, snapshot) {
return write(this, type.modelName, 'DeleteRecord', snapshot);
},
});
}
}

View File

@ -1,12 +1,13 @@
import Adapter, { DATACENTER_QUERY_PARAM as API_DATACENTER_KEY } from './application';
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 use SourceNS and DestinationNS properties for namespacing so we
// don't need to add the `?ns=` anywhere here
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
requestForQuery: function(request, { dc, filter, index, uri }) {
export default class IntentionAdapter extends Adapter {
requestForQuery(request, { dc, filter, index, uri }) {
return request`
GET /v1/connect/intentions?${{ dc }}
X-Request-ID: ${uri}${
@ -21,13 +22,15 @@ export default Adapter.extend({
filter,
}}
`;
},
requestForQueryRecord: function(request, { dc, index, id }) {
}
requestForQueryRecord(request, { dc, index, id }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
// get the information we need from the id, which has been previously encoded
// get the information we need from the id, which has been previously
// encoded
const [SourceNS, SourceName, DestinationNS, DestinationName] = id
.split(':')
.map(decodeURIComponent);
@ -42,8 +45,9 @@ export default Adapter.extend({
${{ index }}
`;
},
requestForCreateRecord: function(request, serialized, data) {
}
requestForCreateRecord(request, serialized, data) {
const body = {
SourceNS: serialized.SourceNS,
DestinationNS: serialized.DestinationNS,
@ -72,14 +76,16 @@ export default Adapter.extend({
${body}
`;
},
requestForUpdateRecord: function(request, serialized, data) {
}
requestForUpdateRecord(request, serialized, data) {
// you can no longer save Destinations
delete serialized.DestinationNS;
delete serialized.DestinationName;
return this.requestForCreateRecord(...arguments);
},
requestForDeleteRecord: function(request, serialized, data) {
}
requestForDeleteRecord(request, serialized, data) {
return request`
DELETE /v1/connect/intentions/exact?${{
source: `${data.SourceNS}/${data.SourceName}`,
@ -87,5 +93,5 @@ export default Adapter.extend({
[API_DATACENTER_KEY]: data[DATACENTER_KEY],
}}
`;
},
});
}
}

View File

@ -1,16 +1,15 @@
import Adapter from './application';
import isFolder from 'consul-ui/utils/isFolder';
import keyToArray from 'consul-ui/utils/keyToArray';
import { SLUG_KEY } from 'consul-ui/models/kv';
import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc';
import { NSPACE_KEY } from 'consul-ui/models/nspace';
// TODO: Update to use this.formatDatacenter()
const API_KEYS_KEY = 'keys';
export default Adapter.extend({
requestForQuery: function(request, { dc, ns, index, id, separator }) {
export default class KvAdapter extends Adapter {
requestForQuery(request, { dc, ns, index, id, separator }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -22,8 +21,9 @@ export default Adapter.extend({
index,
}}
`;
},
requestForQueryRecord: function(request, { dc, ns, index, id }) {
}
requestForQueryRecord(request, { dc, ns, index, id }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -35,10 +35,11 @@ export default Adapter.extend({
index,
}}
`;
},
// TODO: Should we replace text/plain here with x-www-form-encoded?
// See https://github.com/hashicorp/consul/issues/3804
requestForCreateRecord: function(request, serialized, data) {
}
// TODO: Should we replace text/plain here with x-www-form-encoded? See
// https://github.com/hashicorp/consul/issues/3804
requestForCreateRecord(request, serialized, data) {
const params = {
...this.formatDatacenter(data[DATACENTER_KEY]),
...this.formatNspace(data[NSPACE_KEY]),
@ -49,8 +50,9 @@ export default Adapter.extend({
${serialized}
`;
},
requestForUpdateRecord: function(request, serialized, data) {
}
requestForUpdateRecord(request, serialized, data) {
const params = {
...this.formatDatacenter(data[DATACENTER_KEY]),
flags: data.Flags,
@ -62,8 +64,9 @@ export default Adapter.extend({
${serialized}
`;
},
requestForDeleteRecord: function(request, serialized, data) {
}
requestForDeleteRecord(request, serialized, data) {
let recurse;
if (isFolder(data[SLUG_KEY])) {
recurse = null;
@ -76,5 +79,5 @@ export default Adapter.extend({
return request`
DELETE /v1/kv/${keyToArray(data[SLUG_KEY])}?${params}
`;
},
});
}
}

View File

@ -1,15 +1,18 @@
import Adapter from './application';
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
requestForQuery: function(request, { dc, index, id, uri }) {
export default class NodeAdapter extends Adapter {
requestForQuery(request, { dc, index, id, uri }) {
return request`
GET /v1/internal/ui/nodes?${{ dc }}
X-Request-ID: ${uri}
${{ index }}
`;
},
requestForQueryRecord: function(request, { dc, index, id, uri }) {
}
requestForQueryRecord(request, { dc, index, id, uri }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -19,15 +22,17 @@ export default Adapter.extend({
${{ index }}
`;
},
requestForQueryLeader: function(request, { dc, uri }) {
}
requestForQueryLeader(request, { dc, uri }) {
return request`
GET /v1/status/leader?${{ dc }}
X-Request-ID: ${uri}
Refresh: 30
`;
},
queryLeader: function(store, type, id, snapshot) {
}
queryLeader(store, type, id, snapshot) {
return this.rpc(
function(adapter, request, serialized, unserialized) {
return adapter.requestForQueryLeader(request, serialized, unserialized);
@ -38,5 +43,5 @@ export default Adapter.extend({
snapshot,
type.modelName
);
},
});
}
}

View File

@ -2,16 +2,17 @@ import Adapter from './application';
import { SLUG_KEY } from 'consul-ui/models/nspace';
// namespaces aren't categorized by datacenter, therefore no dc
export default Adapter.extend({
requestForQuery: function(request, { index, uri }) {
export default class NspaceAdapter extends Adapter {
requestForQuery(request, { index, uri }) {
return request`
GET /v1/namespaces
X-Request-ID: ${uri}
${{ index }}
`;
},
requestForQueryRecord: function(request, { index, id }) {
}
requestForQueryRecord(request, { index, id }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an name');
}
@ -20,8 +21,9 @@ export default Adapter.extend({
${{ index }}
`;
},
requestForCreateRecord: function(request, serialized, data) {
}
requestForCreateRecord(request, serialized, data) {
return request`
PUT /v1/namespace/${data[SLUG_KEY]}
@ -34,8 +36,9 @@ export default Adapter.extend({
},
}}
`;
},
requestForUpdateRecord: function(request, serialized, data) {
}
requestForUpdateRecord(request, serialized, data) {
return request`
PUT /v1/namespace/${data[SLUG_KEY]}
@ -47,13 +50,15 @@ export default Adapter.extend({
},
}}
`;
},
requestForDeleteRecord: function(request, serialized, data) {
}
requestForDeleteRecord(request, serialized, data) {
return request`
DELETE /v1/namespace/${data[SLUG_KEY]}
`;
},
requestForAuthorize: function(request, { dc, ns, index }) {
}
requestForAuthorize(request, { dc, ns, index }) {
return request`
POST /v1/internal/acl/authorize?${{ dc, ns, index }}
@ -64,8 +69,9 @@ export default Adapter.extend({
},
]}
`;
},
authorize: function(store, type, id, snapshot) {
}
authorize(store, type, id, snapshot) {
return this.rpc(
function(adapter, request, serialized, unserialized) {
return adapter.requestForAuthorize(request, serialized, unserialized);
@ -79,5 +85,5 @@ export default Adapter.extend({
snapshot,
type.modelName
);
},
});
}
}

View File

@ -1,6 +1,5 @@
import Adapter from './application';
import { inject as service } from '@ember/service';
import { env } from 'consul-ui/env';
import nonEmptySet from 'consul-ui/utils/non-empty-set';
@ -10,9 +9,11 @@ if (env('CONSUL_NSPACES_ENABLED')) {
} else {
Namespace = () => ({});
}
export default Adapter.extend({
env: service('env'),
requestForQuery: function(request, { dc, ns, index, uri }) {
export default class OidcProviderAdapter extends Adapter {
@service('env') env;
requestForQuery(request, { dc, ns, index, uri }) {
return request`
GET /v1/internal/ui/oidc-auth-methods?${{ dc }}
X-Request-ID: ${uri}
@ -22,8 +23,9 @@ export default Adapter.extend({
...this.formatNspace(ns),
}}
`;
},
requestForQueryRecord: function(request, { dc, ns, id }) {
}
requestForQueryRecord(request, { dc, ns, id }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -37,8 +39,9 @@ export default Adapter.extend({
RedirectURI: `${this.env.var('CONSUL_BASE_UI_URL')}/oidc/callback`,
}}
`;
},
requestForAuthorize: function(request, { dc, ns, id, code, state }) {
}
requestForAuthorize(request, { dc, ns, id, code, state }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -59,8 +62,9 @@ export default Adapter.extend({
State: state,
}}
`;
},
requestForLogout: function(request, { id }) {
}
requestForLogout(request, { id }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -69,8 +73,9 @@ export default Adapter.extend({
Cache-Control: no-store
X-Consul-Token: ${id}
`;
},
authorize: function(store, type, id, snapshot) {
}
authorize(store, type, id, snapshot) {
return this.rpc(
function(adapter, request, serialized, unserialized) {
return adapter.requestForAuthorize(request, serialized, unserialized);
@ -81,8 +86,9 @@ export default Adapter.extend({
snapshot,
type.modelName
);
},
logout: function(store, type, id, snapshot) {
}
logout(store, type, id, snapshot) {
return this.rpc(
function(adapter, request, serialized, unserialized) {
return adapter.requestForLogout(request, serialized, unserialized);
@ -94,5 +100,5 @@ export default Adapter.extend({
snapshot,
type.modelName
);
},
});
}
}

View File

@ -1,9 +1,7 @@
import Adapter from './application';
import { SLUG_KEY } from 'consul-ui/models/policy';
import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc';
import { NSPACE_KEY } from 'consul-ui/models/nspace';
import { env } from 'consul-ui/env';
import nonEmptySet from 'consul-ui/utils/non-empty-set';
@ -15,8 +13,8 @@ if (env('CONSUL_NSPACES_ENABLED')) {
}
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
requestForQuery: function(request, { dc, ns, index, id }) {
export default class PolicyAdapter extends Adapter {
requestForQuery(request, { dc, ns, index, id }) {
return request`
GET /v1/acl/policies?${{ dc }}
@ -25,8 +23,9 @@ export default Adapter.extend({
index,
}}
`;
},
requestForQueryRecord: function(request, { dc, ns, index, id }) {
}
requestForQueryRecord(request, { dc, ns, index, id }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -38,8 +37,9 @@ export default Adapter.extend({
index,
}}
`;
},
requestForCreateRecord: function(request, serialized, data) {
}
requestForCreateRecord(request, serialized, data) {
const params = {
...this.formatDatacenter(data[DATACENTER_KEY]),
};
@ -54,8 +54,9 @@ export default Adapter.extend({
...Namespace(serialized.Namespace),
}}
`;
},
requestForUpdateRecord: function(request, serialized, data) {
}
requestForUpdateRecord(request, serialized, data) {
const params = {
...this.formatDatacenter(data[DATACENTER_KEY]),
};
@ -70,8 +71,9 @@ export default Adapter.extend({
...Namespace(serialized.Namespace),
}}
`;
},
requestForDeleteRecord: function(request, serialized, data) {
}
requestForDeleteRecord(request, serialized, data) {
const params = {
...this.formatDatacenter(data[DATACENTER_KEY]),
...this.formatNspace(data[NSPACE_KEY]),
@ -79,5 +81,5 @@ export default Adapter.extend({
return request`
DELETE /v1/acl/policy/${data[SLUG_KEY]}?${params}
`;
},
});
}
}

View File

@ -1,7 +1,7 @@
import Adapter from './application';
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
requestForQuery: function(request, { dc, ns, index, id, uri }) {
export default class ProxyAdapter extends Adapter {
requestForQuery(request, { dc, ns, index, id, uri }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -15,5 +15,5 @@ export default Adapter.extend({
index,
}}
`;
},
});
}
}

View File

@ -1,9 +1,7 @@
import Adapter from './application';
import { SLUG_KEY } from 'consul-ui/models/role';
import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc';
import { NSPACE_KEY } from 'consul-ui/models/nspace';
import { env } from 'consul-ui/env';
import nonEmptySet from 'consul-ui/utils/non-empty-set';
@ -13,9 +11,10 @@ if (env('CONSUL_NSPACES_ENABLED')) {
} else {
Namespace = () => ({});
}
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
requestForQuery: function(request, { dc, ns, index, id }) {
export default class RoleAdapter extends Adapter {
requestForQuery(request, { dc, ns, index, id }) {
return request`
GET /v1/acl/roles?${{ dc }}
@ -24,8 +23,9 @@ export default Adapter.extend({
index,
}}
`;
},
requestForQueryRecord: function(request, { dc, ns, index, id }) {
}
requestForQueryRecord(request, { dc, ns, index, id }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -37,8 +37,9 @@ export default Adapter.extend({
index,
}}
`;
},
requestForCreateRecord: function(request, serialized, data) {
}
requestForCreateRecord(request, serialized, data) {
const params = {
...this.formatDatacenter(data[DATACENTER_KEY]),
};
@ -54,8 +55,9 @@ export default Adapter.extend({
...Namespace(serialized.Namespace),
}}
`;
},
requestForUpdateRecord: function(request, serialized, data) {
}
requestForUpdateRecord(request, serialized, data) {
const params = {
...this.formatDatacenter(data[DATACENTER_KEY]),
};
@ -71,8 +73,9 @@ export default Adapter.extend({
...Namespace(serialized.Namespace),
}}
`;
},
requestForDeleteRecord: function(request, serialized, data) {
}
requestForDeleteRecord(request, serialized, data) {
const params = {
...this.formatDatacenter(data[DATACENTER_KEY]),
...this.formatNspace(data[NSPACE_KEY]),
@ -80,5 +83,5 @@ export default Adapter.extend({
return request`
DELETE /v1/acl/role/${data[SLUG_KEY]}?${params}
`;
},
});
}
}

View File

@ -1,7 +1,8 @@
import Adapter from './application';
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
requestForQuery: function(request, { dc, ns, index, id, uri }) {
export default class ServiceInstanceAdapter extends Adapter {
requestForQuery(request, { dc, ns, index, id, uri }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -15,10 +16,11 @@ export default Adapter.extend({
index,
}}
`;
},
requestForQueryRecord: function(request, { dc, ns, index, id, uri }) {
}
requestForQueryRecord(request, { dc, ns, index, id, uri }) {
// query and queryRecord both use the same endpoint
// they are just serialized differently
return this.requestForQuery(...arguments);
},
});
}
}

View File

@ -1,7 +1,8 @@
import Adapter from './application';
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
requestForQuery: function(request, { dc, ns, index, gateway, uri }) {
export default class ServiceAdapter extends Adapter {
requestForQuery(request, { dc, ns, index, gateway, uri }) {
if (typeof gateway !== 'undefined') {
return request`
GET /v1/internal/ui/gateway-services-nodes/${gateway}?${{ dc }}
@ -24,8 +25,9 @@ export default Adapter.extend({
}}
`;
}
},
requestForQueryRecord: function(request, { dc, ns, index, id, uri }) {
}
requestForQueryRecord(request, { dc, ns, index, id, uri }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -38,5 +40,5 @@ export default Adapter.extend({
index,
}}
`;
},
});
}
}

View File

@ -5,8 +5,8 @@ import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc';
import { NSPACE_KEY } from 'consul-ui/models/nspace';
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
requestForQuery: function(request, { dc, ns, index, id, uri }) {
export default class SessionAdapter extends Adapter {
requestForQuery(request, { dc, ns, index, id, uri }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -19,8 +19,9 @@ export default Adapter.extend({
index,
}}
`;
},
requestForQueryRecord: function(request, { dc, ns, index, id }) {
}
requestForQueryRecord(request, { dc, ns, index, id }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -32,8 +33,9 @@ export default Adapter.extend({
index,
}}
`;
},
requestForDeleteRecord: function(request, serialized, data) {
}
requestForDeleteRecord(request, serialized, data) {
const params = {
...this.formatDatacenter(data[DATACENTER_KEY]),
...this.formatNspace(data[NSPACE_KEY]),
@ -41,5 +43,5 @@ export default Adapter.extend({
return request`
PUT /v1/session/destroy/${data[SLUG_KEY]}?${params}
`;
},
});
}
}

View File

@ -1,10 +1,8 @@
import Adapter from './application';
import { inject as service } from '@ember/service';
import { SLUG_KEY } from 'consul-ui/models/token';
import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc';
import { NSPACE_KEY } from 'consul-ui/models/nspace';
import { env } from 'consul-ui/env';
import nonEmptySet from 'consul-ui/utils/non-empty-set';
@ -14,11 +12,12 @@ if (env('CONSUL_NSPACES_ENABLED')) {
} else {
Namespace = () => ({});
}
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
store: service('store'),
requestForQuery: function(request, { dc, ns, index, role, policy }) {
// TODO: Update to use this.formatDatacenter()
export default class TokenAdapter extends Adapter {
@service('store') store;
requestForQuery(request, { dc, ns, index, role, policy }) {
return request`
GET /v1/acl/tokens?${{ role, policy, dc }}
@ -27,8 +26,9 @@ export default Adapter.extend({
index,
}}
`;
},
requestForQueryRecord: function(request, { dc, ns, index, id }) {
}
requestForQueryRecord(request, { dc, ns, index, id }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -40,8 +40,9 @@ export default Adapter.extend({
index,
}}
`;
},
requestForCreateRecord: function(request, serialized, data) {
}
requestForCreateRecord(request, serialized, data) {
const params = {
...this.formatDatacenter(data[DATACENTER_KEY]),
};
@ -58,11 +59,12 @@ export default Adapter.extend({
...Namespace(serialized.Namespace),
}}
`;
},
requestForUpdateRecord: function(request, serialized, data) {
// TODO: here we check data['Rules'] not serialized['Rules']
// data.Rules is not undefined, and serialized.Rules is not null
// revisit this at some point we should probably use serialized here
}
requestForUpdateRecord(request, serialized, data) {
// TODO: here we check data['Rules'] not serialized['Rules'] data.Rules is
// not undefined, and serialized.Rules is not null revisit this at some
// point we should probably use serialized here
// If a token has Rules, use the old API
if (typeof data['Rules'] !== 'undefined') {
@ -90,8 +92,9 @@ export default Adapter.extend({
...Namespace(serialized.Namespace),
}}
`;
},
requestForDeleteRecord: function(request, serialized, data) {
}
requestForDeleteRecord(request, serialized, data) {
const params = {
...this.formatDatacenter(data[DATACENTER_KEY]),
...this.formatNspace(data[NSPACE_KEY]),
@ -99,8 +102,9 @@ export default Adapter.extend({
return request`
DELETE /v1/acl/token/${data[SLUG_KEY]}?${params}
`;
},
requestForSelf: function(request, serialized, { dc, index, secret }) {
}
requestForSelf(request, serialized, { dc, index, secret }) {
// TODO: Change here and elsewhere to use Authorization Bearer Token
// https://github.com/hashicorp/consul/pull/4502
return request`
@ -110,8 +114,9 @@ export default Adapter.extend({
${{ index }}
`;
},
requestForCloneRecord: function(request, serialized, data) {
}
requestForCloneRecord(request, serialized, data) {
// this uses snapshots
const id = data[SLUG_KEY];
if (typeof id === 'undefined') {
@ -124,12 +129,13 @@ export default Adapter.extend({
return request`
PUT /v1/acl/token/${id}/clone?${params}
`;
},
// TODO: self doesn't get passed a snapshot right now
// ideally it would just for consistency
// thing is its probably not the same shape as a 'Token',
// plus we can't create Snapshots as they are private, see services/store.js
self: function(store, type, id, unserialized) {
}
// TODO: self doesn't get passed a snapshot right now ideally it would just
// for consistency thing is its probably not the same shape as a
// 'Token', plus we can't create Snapshots as they are private, see
// services/store.js
self(store, type, id, unserialized) {
return this.rpc(
function(adapter, request, serialized, data) {
return adapter.requestForSelf(request, serialized, data);
@ -140,8 +146,9 @@ export default Adapter.extend({
unserialized,
type.modelName
);
},
clone: function(store, type, id, snapshot) {
}
clone(store, type, id, snapshot) {
return this.rpc(
function(adapter, request, serialized, data) {
return adapter.requestForCloneRecord(request, serialized, data);
@ -159,5 +166,5 @@ export default Adapter.extend({
snapshot,
type.modelName
);
},
});
}
}

View File

@ -1,7 +1,8 @@
import Adapter from './application';
// TODO: Update to use this.formatDatacenter()
export default Adapter.extend({
requestForQueryRecord: function(request, { dc, ns, index, id, uri, kind }) {
export default class TopologyAdapter extends Adapter {
requestForQueryRecord(request, { dc, ns, index, id, uri, kind }) {
if (typeof id === 'undefined') {
throw new Error('You must specify an id');
}
@ -14,5 +15,5 @@ export default Adapter.extend({
index,
}}
`;
},
});
}
}

View File

@ -1,21 +1,19 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'ID';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
Name: attr('string', {
// TODO: Why didn't I have to do this for KV's?
// this is to ensure that Name is '' and not null when creating
// maybe its due to the fact that `Key` is the primaryKey in Kv's
defaultValue: '',
}),
Type: attr('string'),
Rules: attr('string'),
CreateIndex: attr('number'),
ModifyIndex: attr('number'),
Datacenter: attr('string'),
});
export default class Acl extends Model {
@attr('string') uid;
@attr('string') ID;
@attr('string') Datacenter;
// TODO: Why didn't I have to do this for KV's? This is to ensure that Name
// is '' and not null when creating maybe its due to the fact that `Key` is
// the primaryKey in Kv's
@attr('string', { defaultValue: () => '' }) Name;
@attr('string') Type;
@attr('string') Rules;
@attr('number') CreateIndex;
@attr('number') ModifyIndex;
}

View File

@ -1,14 +1,14 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'Node';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
Coord: attr(),
Segment: attr('string'),
Datacenter: attr('string'),
SyncTime: attr('number'),
});
export default class Coordinate extends Model {
@attr('string') uid;
@attr('string') Node;
@attr() Coord; // {Vec, Error, Adjustment, Height}
@attr('string') Segment;
@attr('string') Datacenter;
@attr('number') SyncTime;
}

View File

@ -1,16 +1,12 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { hasMany } from 'ember-data/relationships';
import Model, { attr } from '@ember-data/model';
export const PRIMARY_KEY = 'uid';
export const FOREIGN_KEY = 'Datacenter';
export const SLUG_KEY = 'Name';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
// TODO: Are these required?
Services: hasMany('service'),
Nodes: hasMany('node'),
MeshEnabled: attr('boolean', { defaultValue: true }),
});
export default class Datacenter extends Model {
@attr('string') uid;
@attr('string') Name;
@attr('boolean', { defaultValue: () => true }) MeshEnabled;
}

View File

@ -1,12 +1,13 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'ServiceName';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
Datacenter: attr('string'),
Chain: attr(),
meta: attr(),
});
export default class DiscoveryChain extends Model {
@attr('string') uid;
@attr('string') ServiceName;
@attr('string') Datacenter;
@attr() Chain; // {}
@attr() meta; // {}
}

View File

@ -1,8 +1,7 @@
import Fragment from 'ember-data-model-fragments/fragment';
import { attr } from '@ember-data/model';
import { computed } from '@ember/object';
import { or } from '@ember/object/computed';
import attr from 'ember-data/attr';
import Fragment from 'ember-data-model-fragments/fragment';
export const schema = {
Name: {
@ -13,17 +12,20 @@ export const schema = {
},
};
export default Fragment.extend({
Name: attr('string'),
export default class IntentionPermission extends Fragment {
@attr('string') Name;
Exact: attr('string'),
Prefix: attr('string'),
Suffix: attr('string'),
Regex: attr('string'),
Present: attr(), // this is a boolean but we don't want it to automatically be set to false
@attr('string') Exact;
@attr('string') Prefix;
@attr('string') Suffix;
@attr('string') Regex;
// this is a boolean but we don't want it to automatically be set to false
@attr() Present;
Value: or(...schema.HeaderType.allowedValues),
HeaderType: computed(...schema.HeaderType.allowedValues, function() {
@or(...schema.HeaderType.allowedValues) Value;
@computed(...schema.HeaderType.allowedValues)
get HeaderType() {
return schema.HeaderType.allowedValues.find(prop => typeof this[prop] !== 'undefined');
}),
});
}
}

View File

@ -1,9 +1,8 @@
import attr from 'ember-data/attr';
import { computed } from '@ember/object';
import { or } from '@ember/object/computed';
import Fragment from 'ember-data-model-fragments/fragment';
import { fragmentArray, array } from 'ember-data-model-fragments/attributes';
import { attr } from '@ember-data/model';
import { computed } from '@ember/object';
import { or } from '@ember/object/computed';
export const schema = {
PathType: {
@ -14,16 +13,18 @@ export const schema = {
},
};
export default Fragment.extend({
PathExact: attr('string'),
PathPrefix: attr('string'),
PathRegex: attr('string'),
export default class IntentionPermissionHttp extends Fragment {
@attr('string') PathExact;
@attr('string') PathPrefix;
@attr('string') PathRegex;
Header: fragmentArray('intention-permission-http-header'),
Methods: array('string'),
@fragmentArray('intention-permission-http-header') Header;
@array('string') Methods;
Path: or(...schema.PathType.allowedValues),
PathType: computed(...schema.PathType.allowedValues, function() {
@or(...schema.PathType.allowedValues) Path;
@computed(...schema.PathType.allowedValues)
get PathType() {
return schema.PathType.allowedValues.find(prop => typeof this[prop] === 'string');
}),
});
}
}

View File

@ -1,7 +1,6 @@
import attr from 'ember-data/attr';
import Fragment from 'ember-data-model-fragments/fragment';
import { fragment } from 'ember-data-model-fragments/attributes';
import { attr } from '@ember-data/model';
export const schema = {
Action: {
@ -10,9 +9,7 @@ export const schema = {
},
};
export default Fragment.extend({
Action: attr('string', {
defaultValue: schema.Action.defaultValue,
}),
HTTP: fragment('intention-permission-http'),
});
export default class IntentionPermission extends Fragment {
@attr('string', { defaultValue: () => schema.Action.defaultValue }) Action;
@fragment('intention-permission-http') HTTP;
}

View File

@ -1,40 +1,43 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
import { computed } from '@ember/object';
import { fragmentArray } from 'ember-data-model-fragments/attributes';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'ID';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
Description: attr('string'),
SourceNS: attr('string', { defaultValue: 'default' }),
SourceName: attr('string', { defaultValue: '*' }),
DestinationName: attr('string', { defaultValue: '*' }),
DestinationNS: attr('string', { defaultValue: 'default' }),
Precedence: attr('number'),
Permissions: fragmentArray('intention-permission'),
SourceType: attr('string', { defaultValue: 'consul' }),
Action: attr('string'),
Meta: attr(),
LegacyID: attr('string'),
Legacy: attr('boolean', { defaultValue: true }),
IsManagedByCRD: computed('Meta', function() {
export default class Intention extends Model {
@attr('string') uid;
@attr('string') ID;
@attr('string') Datacenter;
@attr('string') Description;
@attr('string', { defaultValue: () => 'default' }) SourceNS;
@attr('string', { defaultValue: () => '*' }) SourceName;
@attr('string', { defaultValue: () => 'default' }) DestinationNS;
@attr('string', { defaultValue: () => '*' }) DestinationName;
@attr('number') Precedence;
@attr('string', { defaultValue: () => 'consul' }) SourceType;
@attr('string') Action;
@attr('string') LegacyID;
@attr('boolean', { defaultValue: () => true }) Legacy;
@attr('number') SyncTime;
@attr('date') CreatedAt;
@attr('date') UpdatedAt;
@attr('number') CreateIndex;
@attr('number') ModifyIndex;
@attr() Meta; // {}
@fragmentArray('intention-permission') Permissions;
@computed('Meta')
get IsManagedByCRD() {
const meta = Object.entries(this.Meta || {}).find(
([key, value]) => key === 'external-source' && value === 'kubernetes'
);
return typeof meta !== 'undefined';
}),
IsEditable: computed('Legacy', 'IsManagedByCRD', function() {
}
@computed('IsManagedByCRD')
get IsEditable() {
return !this.IsManagedByCRD;
}),
SyncTime: attr('number'),
Datacenter: attr('string'),
CreatedAt: attr('date'),
UpdatedAt: attr('date'),
CreateIndex: attr('number'),
ModifyIndex: attr('number'),
});
}
}

View File

@ -1,30 +1,32 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { computed, get } from '@ember/object';
import Model, { attr } from '@ember-data/model';
import { computed } from '@ember/object';
import isFolder from 'consul-ui/utils/isFolder';
export const PRIMARY_KEY = 'uid';
// not really a slug as it contains slashes but all intents and purposes
// its my 'slug'
// not really a slug as it contains slashes but all intents and purposes its
// my 'slug'
export const SLUG_KEY = 'Key';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
LockIndex: attr('number'),
Flags: attr('number'),
// TODO: Consider defaulting all strings to '' because `typeof null !== 'string'`
// look into what other transformers do with `null` also
// preferably removeNull would be done in this layer also as if a property is `null`
// default Values don't kick in, which also explains `Tags` elsewhere
Value: attr('string'), //, {defaultValue: function() {return '';}}
CreateIndex: attr('number'),
ModifyIndex: attr('number'),
Session: attr('string'),
Datacenter: attr('string'),
Namespace: attr('string'),
export default class Kv extends Model {
@attr('string') uid;
@attr('string') Key;
isFolder: computed('Key', function() {
return isFolder(get(this, 'Key') || '');
}),
});
@attr('string') Datacenter;
@attr('string') Namespace;
@attr('number') LockIndex;
@attr('number') Flags;
// TODO: Consider defaulting all strings to '' because `typeof null !==
// 'string'` look into what other transformers do with `null` also
// preferably removeNull would be done in this layer also as if a property
// is `null` default Values don't kick in, which also explains `Tags`
// elsewhere
@attr('string') Value; //, {defaultValue: function() {return '';}}
@attr('number') CreateIndex;
@attr('number') ModifyIndex;
@attr('string') Session;
@computed('Key')
get isFolder() {
return isFolder(this.Key || '');
}
}

View File

@ -1,27 +1,27 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
import { computed } from '@ember/object';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'ID';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
Address: attr('string'),
Node: attr('string'),
Meta: attr(),
Services: attr(),
Checks: attr(),
CreateIndex: attr('number'),
ModifyIndex: attr('number'),
TaggedAddresses: attr(),
Datacenter: attr('string'),
Segment: attr(),
Coord: attr(),
SyncTime: attr('number'),
meta: attr(),
Status: computed('Checks.[]', 'ChecksCritical', 'ChecksPassing', 'ChecksWarning', function() {
export default class Node extends Model {
@attr('string') uid;
@attr('string') ID;
@attr('string') Datacenter;
@attr('string') Address;
@attr('string') Node;
@attr('number') SyncTime;
@attr('number') CreateIndex;
@attr('number') ModifyIndex;
@attr() meta; // {}
@attr() Meta; // {}
@attr() TaggedAddresses; // {lan, wan}
@attr() Services; // ServiceInstances[]
@attr() Checks; // Checks[]
@computed('Checks.[]', 'ChecksCritical', 'ChecksPassing', 'ChecksWarning')
get Status() {
switch (true) {
case this.ChecksCritical !== 0:
return 'critical';
@ -32,14 +32,20 @@ export default Model.extend({
default:
return 'empty';
}
}),
ChecksCritical: computed('Checks.[]', function() {
}
@computed('Checks.[]')
get ChecksCritical() {
return this.Checks.filter(item => item.Status === 'critical').length;
}),
ChecksPassing: computed('Checks.[]', function() {
}
@computed('Checks.[]')
get ChecksPassing() {
return this.Checks.filter(item => item.Status === 'passing').length;
}),
ChecksWarning: computed('Checks.[]', function() {
}
@computed('Checks.[]')
get ChecksWarning() {
return this.Checks.filter(item => item.Status === 'warning').length;
}),
});
}
}

View File

@ -1,20 +1,22 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
export const PRIMARY_KEY = 'Name';
// keep this for consistency
export const SLUG_KEY = 'Name';
export const NSPACE_KEY = 'Namespace';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
Description: attr('string', { defaultValue: '' }),
export default class Nspace extends Model {
@attr('string') uid;
@attr('string') Name;
@attr('number') SyncTime;
@attr('string', { defaultValue: () => '' }) Description;
// TODO: Is there some sort of date we can use here
DeletedAt: attr('string'),
ACLs: attr(undefined, function() {
return { defaultValue: { PolicyDefaults: [], RoleDefaults: [] } };
}),
SyncTime: attr('number'),
});
@attr('string') DeletedAt;
@attr({
defaultValue: () => ({
PolicyDefaults: [],
RoleDefaults: [],
}),
})
ACLs;
}

View File

@ -1,15 +1,16 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'Name';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
meta: attr(),
Datacenter: attr('string'),
DisplayName: attr('string'),
Kind: attr('string'),
Namespace: attr('string'),
AuthURL: attr('string'),
});
export default class OidcProvider extends Model {
@attr('string') uid;
@attr('string') Name;
@attr('string') Datacenter;
@attr('string') Namespace;
@attr('string') Kind;
@attr('string') AuthURL;
@attr('string') DisplayName;
@attr() meta; // {}
}

View File

@ -1,43 +1,31 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
import { computed } from '@ember/object';
export const MANAGEMENT_ID = '00000000-0000-0000-0000-000000000001';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'ID';
export const MANAGEMENT_ID = '00000000-0000-0000-0000-000000000001';
export default class Policy extends Model {
@attr('string') uid;
@attr('string') ID;
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
Name: attr('string', {
defaultValue: '',
}),
Description: attr('string', {
defaultValue: '',
}),
Rules: attr('string', {
defaultValue: '',
}),
@attr('string') Datacenter;
@attr('string') Namespace;
@attr('string', { defaultValue: () => '' }) Name;
@attr('string', { defaultValue: () => '' }) Description;
@attr('string', { defaultValue: () => '' }) Rules;
@attr('number') SyncTime;
@attr('number') CreateIndex;
@attr('number') ModifyIndex;
@attr() Datacenters; // string[]
@attr() meta; // {}
// frontend only for templated policies (Identities)
@attr('string', { defaultValue: () => '' }) template;
// frontend only for ordering where CreateIndex can't be used
CreateTime: attr('number', {
defaultValue: function() {
return new Date().getTime();
},
}),
//
isGlobalManagement: computed('ID', function() {
return this.ID === MANAGEMENT_ID;
}),
Datacenter: attr('string'),
Namespace: attr('string'),
SyncTime: attr('number'),
meta: attr(),
Datacenters: attr(),
CreateIndex: attr('number'),
ModifyIndex: attr('number'),
@attr('number', { defaultValue: () => new Date().getTime() }) CreateTime;
template: attr('string', {
defaultValue: '',
}),
});
@computed('ID')
get isGlobalManagement() {
return this.ID === MANAGEMENT_ID;
}
}

View File

@ -1,16 +1,18 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'Node,ServiceID';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
ID: attr('string'),
ServiceName: attr('string'),
ServiceID: attr('string'),
Node: attr('string'),
ServiceProxy: attr(),
SyncTime: attr('number'),
Datacenter: attr('string'),
Namespace: attr('string'),
});
// TODO: This should be changed to ProxyInstance
export default class Proxy extends Model {
@attr('string') uid;
@attr('string') ID;
@attr('string') Datacenter;
@attr('string') Namespace;
@attr('string') ServiceName;
@attr('string') ServiceID;
@attr('string') Node;
@attr('number') SyncTime;
@attr() ServiceProxy; // {}
}

View File

@ -1,41 +1,25 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'ID';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
Name: attr('string', {
defaultValue: '',
}),
Description: attr('string', {
defaultValue: '',
}),
Policies: attr({
defaultValue: function() {
return [];
},
}),
ServiceIdentities: attr({
defaultValue: function() {
return [];
},
}),
NodeIdentities: attr({
defaultValue: function() {
return [];
},
}),
export default class Role extends Model {
@attr('string') uid;
@attr('string') ID;
@attr('string') Datacenter;
@attr('string') Namespace;
@attr('string', { defaultValue: () => '' }) Name;
@attr('string', { defaultValue: () => '' }) Description;
@attr({ defaultValue: () => [] }) Policies;
@attr({ defaultValue: () => [] }) ServiceIdentities;
@attr({ defaultValue: () => [] }) NodeIdentities;
@attr('number') SyncTime;
@attr('number') CreateIndex;
@attr('number') ModifyIndex;
// frontend only for ordering where CreateIndex can't be used
CreateTime: attr('date'),
//
Datacenter: attr('string'),
Namespace: attr('string'),
SyncTime: attr('number'),
@attr('number') CreateTime;
// TODO: Figure out whether we need this or not
Datacenters: attr(),
Hash: attr('string'),
CreateIndex: attr('number'),
ModifyIndex: attr('number'),
});
@attr() Datacenters; // string[]
@attr('string') Hash;
}

View File

@ -1,44 +1,43 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import { belongsTo } from 'ember-data/relationships';
import Model, { attr, belongsTo } from '@ember-data/model';
import { computed } from '@ember/object';
import { or, filter, alias } from '@ember/object/computed';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'Node.Node,Service.ID';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
Datacenter: attr('string'),
export default class ServiceInstance extends Model {
@attr('string') uid;
@attr('string') Datacenter;
// ProxyInstance is the ember-data model relationship
ProxyInstance: belongsTo('Proxy'),
@belongsTo('Proxy') ProxyInstance;
// Proxy is the actual JSON api response
Proxy: attr(),
Node: attr(),
Service: attr(),
Checks: attr(),
SyncTime: attr('number'),
meta: attr(),
Name: or('Service.ID', 'Service.Service'),
Tags: alias('Service.Tags'),
Meta: alias('Service.Meta'),
Namespace: alias('Service.Namespace'),
ExternalSources: computed('Service.Meta', function() {
@attr() Proxy;
@attr() Node;
@attr() Service;
@attr() Checks;
@attr('number') SyncTime;
@attr() meta;
@or('Service.ID', 'Service.Service') Name;
@alias('Service.Tags') Tags;
@alias('Service.Meta') Meta;
@alias('Service.Namespace') Namespace;
@filter('Checks.[]', (item, i, arr) => item.ServiceID !== '') ServiceChecks;
@filter('Checks.[]', (item, i, arr) => item.ServiceID === '') NodeChecks;
@computed('Service.Meta')
get ExternalSources() {
const sources = Object.entries(this.Service.Meta || {})
.filter(([key, value]) => key === 'external-source')
.map(([key, value]) => {
return value;
});
return [...new Set(sources)];
}),
ServiceChecks: filter('Checks.[]', function(item, i, arr) {
return item.ServiceID !== '';
}),
NodeChecks: filter('Checks.[]', function(item, i, arr) {
return item.ServiceID === '';
}),
Status: computed('ChecksPassing', 'ChecksWarning', 'ChecksCritical', function() {
}
@computed('ChecksPassing', 'ChecksWarning', 'ChecksCritical')
get Status() {
switch (true) {
case this.ChecksCritical.length !== 0:
return 'critical';
@ -49,23 +48,35 @@ export default Model.extend({
default:
return 'empty';
}
}),
ChecksPassing: computed('Checks.[]', function() {
}
@computed('Checks.[]')
get ChecksPassing() {
return this.Checks.filter(item => item.Status === 'passing');
}),
ChecksWarning: computed('Checks.[]', function() {
}
@computed('Checks.[]')
get ChecksWarning() {
return this.Checks.filter(item => item.Status === 'warning');
}),
ChecksCritical: computed('Checks.[]', function() {
}
@computed('Checks.[]')
get ChecksCritical() {
return this.Checks.filter(item => item.Status === 'critical');
}),
PercentageChecksPassing: computed('Checks.[]', 'ChecksPassing', function() {
}
@computed('Checks.[]', 'ChecksPassing')
get PercentageChecksPassing() {
return (this.ChecksPassing.length / this.Checks.length) * 100;
}),
PercentageChecksWarning: computed('Checks.[]', 'ChecksWarning', function() {
}
@computed('Checks.[]', 'ChecksWarning')
get PercentageChecksWarning() {
return (this.ChecksWarning.length / this.Checks.length) * 100;
}),
PercentageChecksCritical: computed('Checks.[]', 'ChecksCritical', function() {
}
@computed('Checks.[]', 'ChecksCritical')
get PercentageChecksCritical() {
return (this.ChecksCritical.length / this.Checks.length) * 100;
}),
});
}
}

View File

@ -1,52 +1,48 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
import { computed, get } from '@ember/object';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'Name';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
Tags: attr({
defaultValue: function() {
return [];
},
}),
InstanceCount: attr('number'),
ConnectedWithGateway: attr(),
ConnectedWithProxy: attr(),
Proxy: attr(),
GatewayConfig: attr(),
Kind: attr('string'),
ExternalSources: attr(),
Meta: attr(),
Address: attr('string'),
TaggedAddresses: attr(),
Port: attr('number'),
EnableTagOverride: attr('boolean'),
CreateIndex: attr('number'),
ModifyIndex: attr('number'),
// TODO: These should be typed
ChecksPassing: attr(),
ChecksCritical: attr(),
ChecksWarning: attr(),
Nodes: attr(),
Datacenter: attr('string'),
Namespace: attr('string'),
Node: attr(),
Service: attr(),
Checks: attr(),
SyncTime: attr('number'),
meta: attr(),
export default class Service extends Model {
@attr('string') uid;
@attr('string') Name;
@attr('string') Datacenter;
@attr('string') Namespace;
@attr('string') Kind;
@attr('number') ChecksPassing;
@attr('number') ChecksCritical;
@attr('number') ChecksWarning;
@attr('number') InstanceCount;
@attr('boolean') ConnectedWithGateway;
@attr('boolean') ConnectedWithProxy;
@attr('number') SyncTime;
@attr('number') CreateIndex;
@attr('number') ModifyIndex;
@attr({ defaultValue: () => [] }) Tags;
@attr() Nodes; // array
@attr() Proxy; // Service
@attr() GatewayConfig; // {AssociatedServiceCount: 0}
@attr() ExternalSources; // array
@attr() Meta; // {}
@attr() meta; // {}
/* Mesh properties involve both the service and the associated proxy */
MeshEnabled: computed('ConnectedWithProxy', 'ConnectedWithGateway', function() {
@computed('ConnectedWithProxy', 'ConnectedWithGateway')
get MeshEnabled() {
return this.ConnectedWithProxy || this.ConnectedWithGateway;
}),
InMesh: computed('Kind', function() {
}
@computed('MeshEnabled', 'Kind')
get InMesh() {
return this.MeshEnabled || (this.Kind || '').length > 0;
}),
MeshStatus: computed('MeshChecksPassing', 'MeshChecksWarning', 'MeshChecksCritical', function() {
}
@computed('MeshChecksPassing', 'MeshChecksWarning', 'MeshChecksCritical')
get MeshStatus() {
switch (true) {
case this.MeshChecksCritical !== 0:
return 'critical';
@ -57,57 +53,33 @@ export default Model.extend({
default:
return 'empty';
}
}),
MeshChecksPassing: computed('ChecksPassing', 'Proxy.ChecksPassing', function() {
}
@computed('ChecksPassing', 'Proxy.ChecksPassing')
get MeshChecksPassing() {
let proxyCount = 0;
if (typeof this.Proxy !== 'undefined') {
proxyCount = this.Proxy.ChecksPassing;
}
return this.ChecksPassing + proxyCount;
}),
MeshChecksWarning: computed('ChecksWarning', 'Proxy.ChecksWarning', function() {
}
@computed('ChecksWarning', 'Proxy.ChecksWarning')
get MeshChecksWarning() {
let proxyCount = 0;
if (typeof this.Proxy !== 'undefined') {
proxyCount = this.Proxy.ChecksWarning;
}
return this.ChecksWarning + proxyCount;
}),
MeshChecksCritical: computed('ChecksCritical', 'Proxy.ChecksCritical', function() {
}
@computed('ChecksCritical', 'Proxy.ChecksCritical')
get MeshChecksCritical() {
let proxyCount = 0;
if (typeof this.Proxy !== 'undefined') {
proxyCount = this.Proxy.ChecksCritical;
}
return this.ChecksCritical + proxyCount;
}),
}
/**/
passing: computed('ChecksPassing', 'Checks', function() {
let num = 0;
// TODO: use typeof
if (get(this, 'ChecksPassing') !== undefined) {
num = get(this, 'ChecksPassing');
} else {
num = get(get(this, 'Checks').filterBy('Status', 'passing'), 'length');
}
return {
length: num,
};
}),
hasStatus: function(status) {
let num = 0;
switch (status) {
case 'passing':
num = get(this, 'ChecksPassing');
break;
case 'critical':
num = get(this, 'ChecksCritical');
break;
case 'warning':
num = get(this, 'ChecksWarning');
break;
case '': // all
num = 1;
break;
}
return num > 0;
},
});
}

View File

@ -1,25 +1,22 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'ID';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
Name: attr('string'),
Node: attr('string'),
CreateIndex: attr('number'),
ModifyIndex: attr('number'),
LockDelay: attr('number'),
Behavior: attr('string'),
TTL: attr('string'),
Checks: attr({
defaultValue: function() {
return [];
},
}),
Datacenter: attr('string'),
Namespace: attr('string'),
SyncTime: attr('number'),
});
export default class Session extends Model {
@attr('string') uid;
@attr('string') ID;
@attr('string') Name;
@attr('string') Datacenter;
@attr('string') Namespace;
@attr('string') Node;
@attr('string') Behavior;
@attr('string') TTL;
@attr('number') LockDelay;
@attr('number') SyncTime;
@attr('number') CreateIndex;
@attr('number') ModifyIndex;
@attr({ defaultValue: () => [] }) Checks;
}

View File

@ -1,56 +1,41 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
import { computed } from '@ember/object';
import { MANAGEMENT_ID } from 'consul-ui/models/policy';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'AccessorID';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
IDPName: attr('string'),
SecretID: attr('string'),
export default class Token extends Model {
@attr('string') uid;
@attr('string') AccessorID;
@attr('string') Datacenter;
@attr('string') Namespace;
@attr('string') IDPName;
@attr('string') SecretID;
@attr('boolean') Legacy;
@attr('boolean') Local;
@attr('string', { defaultValue: () => '' }) Description;
@attr() meta; // {}
@attr({ defaultValue: () => [] }) Policies;
@attr({ defaultValue: () => [] }) Roles;
@attr({ defaultValue: () => [] }) ServiceIdentities;
@attr({ defaultValue: () => [] }) NodeIdentities;
@attr('date') CreateTime;
@attr('string') Hash;
@attr('number') CreateIndex;
@attr('number') ModifyIndex;
// Legacy
Type: attr('string'),
Name: attr('string', {
defaultValue: '',
}),
Rules: attr('string'),
@attr('string') Type;
@attr('string', { defaultValue: () => '' }) Name;
@attr('string') Rules;
// End Legacy
Legacy: attr('boolean'),
Description: attr('string', {
defaultValue: '',
}),
meta: attr(),
Datacenter: attr('string'),
Namespace: attr('string'),
Local: attr('boolean'),
isGlobalManagement: computed('Policies.[]', function() {
@computed('Policies.[]')
get isGlobalManagement() {
return (this.Policies || []).find(item => item.ID === MANAGEMENT_ID);
}),
Policies: attr({
defaultValue: function() {
return [];
},
}),
Roles: attr({
defaultValue: function() {
return [];
},
}),
ServiceIdentities: attr({
defaultValue: function() {
return [];
},
}),
NodeIdentities: attr({
defaultValue: function() {
return [];
},
}),
CreateTime: attr('date'),
Hash: attr('string'),
CreateIndex: attr('number'),
ModifyIndex: attr('number'),
});
}
}

View File

@ -1,16 +1,17 @@
import Model from 'ember-data/model';
import attr from 'ember-data/attr';
import Model, { attr } from '@ember-data/model';
export const PRIMARY_KEY = 'uid';
export const SLUG_KEY = 'ServiceName';
export default Model.extend({
[PRIMARY_KEY]: attr('string'),
[SLUG_KEY]: attr('string'),
Datacenter: attr('string'),
Namespace: attr('string'),
Upstreams: attr(),
Downstreams: attr(),
Protocol: attr(),
FilteredByACLs: attr(),
meta: attr(),
});
export default class Topology extends Model {
@attr('string') uid;
@attr('string') ServiceName;
@attr('string') Datacenter;
@attr('string') Namespace;
@attr('string') Protocol;
@attr('boolean') FilteredByACLs;
@attr() Upstreams; // Service[]
@attr() Downstreams; // Service[],
@attr() meta; // {}
}

View File

@ -1,10 +1,14 @@
import Serializer from './application';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/acl';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
respondForQueryRecord: function(respond, query) {
return this._super(cb => respond((headers, body) => cb(headers, body[0])), query);
},
});
export default class AclSerializer extends Serializer {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
respondForQueryRecord(respond, query) {
return super.respondForQueryRecord(
cb => respond((headers, body) => cb(headers, body[0])),
query
);
}
}

View File

@ -1,5 +1,4 @@
import Serializer from './http';
import { set } from '@ember/object';
import {
HEADERS_SYMBOL as HTTP_HEADERS_SYMBOL,
@ -27,9 +26,9 @@ const attachHeaders = function(headers, body, query = {}) {
Object.keys(headers).forEach(function(key) {
lower[key.toLowerCase()] = headers[key];
});
// Add a 'pretend' Datacenter/Nspace header, they are not headers
// the come from the request but we add them here so we can use them later
// for store reconciliation
// Add a 'pretend' Datacenter/Nspace header, they are not headers the come
// from the request but we add them here so we can use them later for store
// reconciliation
if (typeof query.dc !== 'undefined') {
lower[HTTP_HEADERS_DATACENTER.toLowerCase()] = query.dc;
}
@ -40,10 +39,11 @@ const attachHeaders = function(headers, body, query = {}) {
return body;
};
export default Serializer.extend({
attachHeaders: attachHeaders,
fingerprint: createFingerprinter(DATACENTER_KEY, NSPACE_KEY),
respondForQuery: function(respond, query) {
export default class ApplicationSerializer extends Serializer {
attachHeaders = attachHeaders;
fingerprint = createFingerprinter(DATACENTER_KEY, NSPACE_KEY);
respondForQuery(respond, query) {
return respond((headers, body) =>
attachHeaders(
headers,
@ -51,13 +51,15 @@ export default Serializer.extend({
query
)
);
},
respondForQueryRecord: function(respond, query) {
}
respondForQueryRecord(respond, query) {
return respond((headers, body) =>
attachHeaders(headers, this.fingerprint(this.primaryKey, this.slugKey, query.dc)(body), query)
);
},
respondForCreateRecord: function(respond, serialized, data) {
}
respondForCreateRecord(respond, serialized, data) {
const slugKey = this.slugKey;
const primaryKey = this.primaryKey;
return respond((headers, body) => {
@ -68,29 +70,32 @@ export default Serializer.extend({
// Creates need a primaryKey adding
return this.fingerprint(primaryKey, slugKey, data[DATACENTER_KEY])(body);
});
},
respondForUpdateRecord: function(respond, serialized, data) {
}
respondForUpdateRecord(respond, serialized, data) {
const slugKey = this.slugKey;
const primaryKey = this.primaryKey;
return respond((headers, body) => {
// If updates are true use the info we already have
// TODO: We may aswell avoid re-fingerprinting here if we are just
// going to reuse data then its already fingerprinted and as the response
// is true we don't have anything changed so the old fingerprint stays the same
// as long as nothing in the fingerprint has been edited (the namespace?)
// TODO: We may aswell avoid re-fingerprinting here if we are just going
// to reuse data then its already fingerprinted and as the response is
// true we don't have anything changed so the old fingerprint stays the
// same as long as nothing in the fingerprint has been edited (the
// namespace?)
if (body === true) {
body = data;
}
return this.fingerprint(primaryKey, slugKey, data[DATACENTER_KEY])(body);
});
},
respondForDeleteRecord: function(respond, serialized, data) {
}
respondForDeleteRecord(respond, serialized, data) {
const slugKey = this.slugKey;
const primaryKey = this.primaryKey;
return respond((headers, body) => {
// Deletes only need the primaryKey/uid returning
// and they need the slug key AND potential namespace in order to
// create the correct uid/fingerprint
// Deletes only need the primaryKey/uid returning and they need the slug
// key AND potential namespace in order to create the correct
// uid/fingerprint
return {
[primaryKey]: this.fingerprint(
primaryKey,
@ -102,24 +107,25 @@ export default Serializer.extend({
})[primaryKey],
};
});
},
// this could get confusing if you tried to override
// say `normalizeQueryResponse`
// TODO: consider creating a method for each one of the `normalize...Response` family
normalizeResponse: function(store, modelClass, payload, id, requestType) {
}
// this could get confusing if you tried to override say
// `normalizeQueryResponse`
// TODO: consider creating a method for each one of the
// `normalize...Response` family
normalizeResponse(store, modelClass, payload, id, requestType) {
const normalizedPayload = this.normalizePayload(payload, id, requestType);
// put the meta onto the response, here this is ok
// as JSON-API allows this and our specific data is now in
// response[primaryModelClass.modelName]
// so we aren't in danger of overwriting anything
// (which was the reason for the Symbol-like property earlier)
// use a method modelled on ember-data methods so we have the opportunity to
// do this on a per-model level
// put the meta onto the response, here this is ok as JSON-API allows this
// and our specific data is now in response[primaryModelClass.modelName]
// so we aren't in danger of overwriting anything (which was the reason
// for the Symbol-like property earlier) use a method modelled on
// ember-data methods so we have the opportunity to do this on a per-model
// level
const meta = this.normalizeMeta(store, modelClass, normalizedPayload, id, requestType);
if (requestType !== 'query') {
normalizedPayload.meta = meta;
}
const res = this._super(
const res = super.normalizeResponse(
store,
modelClass,
{
@ -129,22 +135,24 @@ export default Serializer.extend({
id,
requestType
);
// If the result of the super normalizeResponse is undefined
// its because the JSONSerializer (which REST inherits from)
// doesn't recognise the requestType, in this case its likely to be an 'action'
// request rather than a specific 'load me some data' one.
// Therefore its ok to bypass the store here for the moment
// we currently use this for self, but it also would affect any custom
// methods that use a serializer in our custom service/store
// If the result of the super normalizeResponse is undefined its because
// the JSONSerializer (which REST inherits from) doesn't recognise the
// requestType, in this case its likely to be an 'action' request rather
// than a specific 'load me some data' one. Therefore its ok to bypass the
// store here for the moment we currently use this for self, but it also
// would affect any custom methods that use a serializer in our custom
// service/store
if (typeof res === 'undefined') {
return payload;
}
return res;
},
timestamp: function() {
}
timestamp() {
return new Date().getTime();
},
normalizeMeta: function(store, modelClass, payload, id, requestType) {
}
normalizeMeta(store, modelClass, payload, id, requestType) {
// Pick the meta/headers back off the payload and cleanup
const headers = payload[HTTP_HEADERS_SYMBOL] || {};
delete payload[HTTP_HEADERS_SYMBOL];
@ -167,8 +175,9 @@ export default Serializer.extend({
});
}
return meta;
},
normalizePayload: function(payload, id, requestType) {
}
normalizePayload(payload, id, requestType) {
return payload;
},
});
}
}

View File

@ -1,7 +1,7 @@
import Serializer from './application';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/coordinate';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
});
export default class CoordinateSerializer extends Serializer {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
}

View File

@ -1,13 +1,15 @@
import Serializer from './application';
export default Serializer.extend({
primaryKey: 'Name',
respondForQuery: function(respond, query) {
export default class DcSerializer extends Serializer {
primaryKey = 'Name';
respondForQuery(respond, query) {
return respond(function(headers, body) {
return body;
});
},
normalizePayload: function(payload, id, requestType) {
}
normalizePayload(payload, id, requestType) {
switch (requestType) {
case 'query':
return payload.map(item => {
@ -17,5 +19,5 @@ export default Serializer.extend({
});
}
return payload;
},
});
}
}

View File

@ -1,11 +1,12 @@
import Serializer from './application';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/discovery-chain';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
respondForQueryRecord: function(respond, query) {
return this._super(function(cb) {
export default class DiscoveryChainSerializer extends Serializer {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
respondForQueryRecord(respond, query) {
return super.respondForQueryRecord(function(cb) {
return respond(function(headers, body) {
return cb(headers, {
...body,
@ -13,5 +14,5 @@ export default Serializer.extend({
});
});
}, query);
},
});
}
}

View File

@ -1,25 +1,31 @@
import Serializer from 'ember-data/serializers/rest';
import Serializer from '@ember-data/serializer/rest';
export default Serializer.extend({
respondForQuery: function(respond, query) {
export default class HttpSerializer extends Serializer {
respondForQuery(respond, query) {
return respond((headers, body) => body);
},
respondForQueryRecord: function(respond, query) {
}
respondForQueryRecord(respond, query) {
return respond((headers, body) => body);
},
respondForFindAll: function(respond, query) {
}
respondForFindAll(respond, query) {
return respond((headers, body) => body);
},
respondForCreateRecord: function(respond, data) {
}
respondForCreateRecord(respond, data) {
// TODO: Creates may need a primaryKey adding (remove from application)
return respond((headers, body) => body);
},
respondForUpdateRecord: function(respond, data) {
// TODO: Updates only need the primaryKey/uid returning (remove from application)
}
respondForUpdateRecord(respond, data) {
// TODO: Updates only need the primaryKey/uid returning (remove from
// application)
return respond((headers, body) => body);
},
respondForDeleteRecord: function(respond, data) {
}
respondForDeleteRecord(respond, data) {
// TODO: Deletes only need the primaryKey/uid returning (remove from application)
return respond((headers, body) => body);
},
});
}
}

View File

@ -4,15 +4,18 @@ import { get } from '@ember/object';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/intention';
import removeNull from 'consul-ui/utils/remove-null';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
encoder: service('encoder'),
init: function() {
this._super();
export default class IntentionSerializer extends Serializer {
@service('encoder') encoder;
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
init() {
super.init(...arguments);
this.uri = this.encoder.uriTag();
},
ensureID: function(item) {
}
ensureID(item) {
if (!get(item, 'ID.length')) {
item.Legacy = false;
} else {
@ -22,9 +25,10 @@ export default Serializer.extend({
item.ID = this
.uri`${item.SourceNS}:${item.SourceName}:${item.DestinationNS}:${item.DestinationName}`;
return item;
},
respondForQuery: function(respond, query) {
return this._super(
}
respondForQuery(respond, query) {
return super.respondForQuery(
cb =>
respond((headers, body) => {
return cb(
@ -34,9 +38,10 @@ export default Serializer.extend({
}),
query
);
},
respondForQueryRecord: function(respond, query) {
return this._super(
}
respondForQueryRecord(respond, query) {
return super.respondForQueryRecord(
cb =>
respond((headers, body) => {
body = this.ensureID(removeNull(body));
@ -44,8 +49,9 @@ export default Serializer.extend({
}),
query
);
},
respondForCreateRecord: function(respond, serialized, data) {
}
respondForCreateRecord(respond, serialized, data) {
const slugKey = this.slugKey;
const primaryKey = this.primaryKey;
return respond((headers, body) => {
@ -54,8 +60,9 @@ export default Serializer.extend({
.uri`${serialized.SourceNS}:${serialized.SourceName}:${serialized.DestinationNS}:${serialized.DestinationName}`;
return this.fingerprint(primaryKey, slugKey, body.Datacenter)(body);
});
},
respondForUpdateRecord: function(respond, serialized, data) {
}
respondForUpdateRecord(respond, serialized, data) {
const slugKey = this.slugKey;
const primaryKey = this.primaryKey;
return respond((headers, body) => {
@ -64,5 +71,5 @@ export default Serializer.extend({
body.ID = serialized.ID;
return this.fingerprint(primaryKey, slugKey, body.Datacenter)(body);
});
},
});
}
}

View File

@ -1,25 +1,31 @@
import Serializer from './application';
import { inject as service } from '@ember/service';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/kv';
import { NSPACE_KEY } from 'consul-ui/models/nspace';
import { NSPACE_QUERY_PARAM as API_NSPACE_KEY } from 'consul-ui/adapters/application';
import removeNull from 'consul-ui/utils/remove-null';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
decoder: service('atob'),
export default class KvSerializer extends Serializer {
@service('atob') decoder;
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
// TODO: Would undefined be better instead of null?
serialize: function(snapshot, options) {
serialize(snapshot, options) {
const value = snapshot.attr('Value');
return typeof value === 'string' ? this.decoder.execute(value) : null;
},
respondForQueryRecord: function(respond, query) {
return this._super(cb => respond((headers, body) => cb(headers, removeNull(body[0]))), query);
},
respondForQuery: function(respond, query) {
return this._super(
}
respondForQueryRecord(respond, query) {
return super.respondForQueryRecord(
cb => respond((headers, body) => cb(headers, removeNull(body[0]))),
query
);
}
respondForQuery(respond, query) {
return super.respondForQuery(
cb =>
respond((headers, body) => {
return cb(
@ -34,5 +40,5 @@ export default Serializer.extend({
}),
query
);
},
});
}
}

View File

@ -1,8 +1,8 @@
import Serializer from './application';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/node';
// TODO: Looks like ID just isn't used at all
// consider just using .Node for the SLUG_KEY
// TODO: Looks like ID just isn't used at all consider just using .Node for
// the SLUG_KEY
const fillSlug = function(item) {
if (item[SLUG_KEY] === '') {
item[SLUG_KEY] = item['Node'];
@ -10,22 +10,28 @@ const fillSlug = function(item) {
return item;
};
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
respondForQuery: function(respond, query) {
return this._super(cb => respond((headers, body) => cb(headers, body.map(fillSlug))), query);
},
respondForQueryRecord: function(respond, query) {
return this._super(
export default class NodeSerializer extends Serializer {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
respondForQuery(respond, query) {
return super.respondForQuery(
cb => respond((headers, body) => cb(headers, body.map(fillSlug))),
query
);
}
respondForQueryRecord(respond, query) {
return super.respondForQueryRecord(
cb =>
respond((headers, body) => {
return cb(headers, fillSlug(body));
}),
query
);
},
respondForQueryLeader: function(respond, query) {
}
respondForQueryLeader(respond, query) {
// don't call super here we don't care about
// ids/fingerprinting
return respond((headers, body) => {
@ -45,5 +51,5 @@ export default Serializer.extend({
query
);
});
},
});
}
}

View File

@ -2,10 +2,11 @@ import Serializer from './application';
import { get } from '@ember/object';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/nspace';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
respondForQuery: function(respond, serialized, data) {
export default class NspaceSerializer extends Serializer {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
respondForQuery(respond, serialized, data) {
return respond((headers, body) => {
return this.attachHeaders(
headers,
@ -16,9 +17,9 @@ export default Serializer.extend({
return item;
});
}
// Both of these might come though unset so we make sure
// we at least have an empty array here so we can add
// children to them if we need to whilst saving nspaces
// Both of these might come though unset so we make sure we at least
// have an empty array here so we can add children to them if we
// need to whilst saving nspaces
['PolicyDefaults', 'RoleDefaults'].forEach(function(prop) {
if (typeof item.ACLs === 'undefined') {
item.ACLs = [];
@ -31,33 +32,36 @@ export default Serializer.extend({
})
);
});
},
respondForQueryRecord: function(respond, serialized, data) {
// We don't attachHeaders here yet, mainly because we don't use
// blocking queries on form views yet, and by the time we do
// Serializers should have been refactored to not use attachHeaders
}
respondForQueryRecord(respond, serialized, data) {
// We don't attachHeaders here yet, mainly because we don't use blocking
// queries on form views yet, and by the time we do Serializers should
// have been refactored to not use attachHeaders
return respond((headers, body) => {
return body;
});
},
respondForCreateRecord: function(respond, serialized, data) {
}
respondForCreateRecord(respond, serialized, data) {
return respond((headers, body) => {
// The data properties sent to be saved in the backend
// or the same ones that we receive back if its successfull
// therefore we can just ignore the result and avoid ember-data
// syncing problems
// The data properties sent to be saved in the backend or the same ones
// that we receive back if its successfull therefore we can just ignore
// the result and avoid ember-data syncing problems
return {};
});
},
respondForUpdateRecord: function(respond, serialized, data) {
}
respondForUpdateRecord(respond, serialized, data) {
return respond((headers, body) => {
return body;
});
},
respondForDeleteRecord: function(respond, serialized, data) {
}
respondForDeleteRecord(respond, serialized, data) {
return respond((headers, body) => {
// Deletes only need the primaryKey/uid returning
return body;
});
},
});
}
}

View File

@ -1,21 +1,22 @@
import Serializer from './application';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/oidc-provider';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
respondForAuthorize: function(respond, serialized, data) {
// we avoid the parent serializer here as it tries to create a
// fingerprint for an 'action' request
// but we still need to pass the headers through
export default class OidcSerializer extends Serializer {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
respondForAuthorize(respond, serialized, data) {
// we avoid the parent serializer here as it tries to create a fingerprint
// for an 'action' request but we still need to pass the headers through
return respond((headers, body) => {
return this.attachHeaders(headers, body, data);
});
},
respondForQueryRecord: function(respond, query) {
}
respondForQueryRecord(respond, query) {
// add the name and nspace here so we can merge this
// TODO: Look to see if we always want the merging functionality
return this._super(
return super.respondForQueryRecord(
cb =>
respond((headers, body) =>
cb(headers, {
@ -26,5 +27,5 @@ export default Serializer.extend({
),
query
);
},
});
}
}

View File

@ -1,7 +1,7 @@
import Serializer from './application';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/policy';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
});
export default class PolicySerializer extends Serializer {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
}

View File

@ -1,7 +1,7 @@
import Serializer from './application';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/proxy';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
});
export default class ProxySerializer extends Serializer {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
}

View File

@ -1,7 +1,8 @@
import Serializer from './application';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/role';
import WithPolicies from 'consul-ui/mixins/policy/as-many';
export default Serializer.extend(WithPolicies, {
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
});
export default class RoleSerializer extends Serializer.extend(WithPolicies) {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
}

View File

@ -1,11 +1,12 @@
import Serializer from './application';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/service-instance';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
respondForQuery: function(respond, query) {
return this._super(function(cb) {
export default class ServiceInstanceSerializer extends Serializer {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
respondForQuery(respond, query) {
return super.respondForQuery(function(cb) {
return respond(function(headers, body) {
if (body.length === 0) {
const e = new Error();
@ -20,9 +21,10 @@ export default Serializer.extend({
return cb(headers, body);
});
}, query);
},
respondForQueryRecord: function(respond, query) {
return this._super(function(cb) {
}
respondForQueryRecord(respond, query) {
return super.respondForQueryRecord(function(cb) {
return respond(function(headers, body) {
body = body.find(function(item) {
return item.Node.Node === query.node && item.Service.ID === query.serviceId;
@ -41,5 +43,5 @@ export default Serializer.extend({
return cb(headers, body);
});
}, query);
},
});
}
}

View File

@ -2,15 +2,16 @@ import Serializer from './application';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/service';
import { get } from '@ember/object';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
respondForQuery: function(respond, query) {
return this._super(
export default class ServiceSerializer extends Serializer {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
respondForQuery(respond, query) {
return super.respondForQuery(
cb =>
respond((headers, body) => {
// Services and proxies all come together in the same list
// Here we map the proxies to their related services on a Service.Proxy
// Services and proxies all come together in the same list. Here we
// map the proxies to their related services on a Service.Proxy
// property for easy access later on
const services = {};
body
@ -25,8 +26,8 @@ export default Serializer.extend({
return item.Kind === 'connect-proxy';
})
.forEach(item => {
// Iterating to cover the usecase of a proxy being
// used by more than one service
// Iterating to cover the usecase of a proxy being used by more
// than one service
if (item.ProxyFor) {
item.ProxyFor.forEach(service => {
if (typeof services[service] !== 'undefined') {
@ -39,11 +40,12 @@ export default Serializer.extend({
}),
query
);
},
respondForQueryRecord: function(respond, query) {
}
respondForQueryRecord(respond, query) {
// Name is added here from the query, which is used to make the uid
// Datacenter gets added in the ApplicationSerializer
return this._super(
return super.respondForQueryRecord(
cb =>
respond((headers, body) => {
return cb(headers, {
@ -54,5 +56,5 @@ export default Serializer.extend({
}),
query
);
},
});
}
}

View File

@ -1,10 +1,14 @@
import Serializer from './application';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/session';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
respondForQueryRecord: function(respond, query) {
return this._super(cb => respond((headers, body) => cb(headers, body[0])), query);
},
});
export default class SessionSerializer extends Serializer {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
respondForQueryRecord(respond, query) {
return super.respondForQueryRecord(
cb => respond((headers, body) => cb(headers, body[0])),
query
);
}
}

View File

@ -1,18 +1,18 @@
import Serializer from './application';
import { get } from '@ember/object';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/token';
import WithPolicies from 'consul-ui/mixins/policy/as-many';
import WithRoles from 'consul-ui/mixins/role/as-many';
export default Serializer.extend(WithPolicies, WithRoles, {
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
serialize: function(snapshot, options) {
let data = this._super(...arguments);
// If a token has Rules, use the old API shape
// notice we use a null check here (not an undefined check)
// as we are dealing with the serialized model not raw user data
export default class TokenSerializer extends Serializer.extend(WithPolicies, WithRoles) {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
serialize(snapshot, options) {
let data = super.serialize(...arguments);
// If a token has Rules, use the old API shape notice we use a null check
// here (not an undefined check) as we are dealing with the serialized
// model not raw user data
if (data['Rules'] !== null) {
data = {
ID: data.SecretID,
@ -22,20 +22,22 @@ export default Serializer.extend(WithPolicies, WithRoles, {
};
}
// make sure we never send the SecretID
// TODO: If we selectively format the request payload in the adapter
// we won't have to do this here
// see side note in https://github.com/hashicorp/consul/pull/6285
// which will mean most if not all of this method can go
// TODO: If we selectively format the request payload in the adapter we
// won't have to do this here see side note in
// https://github.com/hashicorp/consul/pull/6285 which will mean most if
// not all of this method can go
if (data) {
delete data['SecretID'];
}
return data;
},
respondForSelf: function(respond, query) {
}
respondForSelf(respond, query) {
return this.respondForQueryRecord(respond, query);
},
respondForUpdateRecord: function(respond, serialized, data) {
return this._super(
}
respondForUpdateRecord(respond, serialized, data) {
return super.respondForUpdateRecord(
cb =>
respond((headers, body) => {
// Sometimes we get `Policies: null`, make null equal an empty array
@ -55,5 +57,5 @@ export default Serializer.extend(WithPolicies, WithRoles, {
serialized,
data
);
},
});
}
}

View File

@ -1,11 +1,12 @@
import Serializer from './application';
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/topology';
export default Serializer.extend({
primaryKey: PRIMARY_KEY,
slugKey: SLUG_KEY,
respondForQueryRecord: function(respond, query) {
return this._super(function(cb) {
export default class TopologySerializer extends Serializer {
primaryKey = PRIMARY_KEY;
slugKey = SLUG_KEY;
respondForQueryRecord(respond, query) {
return super.respondForQueryRecord(function(cb) {
return respond(function(headers, body) {
return cb(headers, {
...body,
@ -13,5 +14,5 @@ export default Serializer.extend({
});
});
}, query);
},
});
}
}

View File

@ -1,5 +1,5 @@
import { inject as service } from '@ember/service';
import Store from 'ember-data/store';
import Store from '@ember-data/store';
export default class StoreService extends Store {
@service('data-source/service')