-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
UI to accompany the new ACLs APIs
- Loading branch information
Showing
301 changed files
with
6,542 additions
and
678 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import Adapter, { | ||
REQUEST_CREATE, | ||
REQUEST_UPDATE, | ||
DATACENTER_QUERY_PARAM as API_DATACENTER_KEY, | ||
} from './application'; | ||
|
||
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/policy'; | ||
import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc'; | ||
import { OK as HTTP_OK } from 'consul-ui/utils/http/status'; | ||
import { PUT as HTTP_PUT } from 'consul-ui/utils/http/method'; | ||
|
||
export default Adapter.extend({ | ||
urlForQuery: function(query, modelName) { | ||
return this.appendURL('acl/policies', [], this.cleanQuery(query)); | ||
}, | ||
urlForQueryRecord: function(query, modelName) { | ||
if (typeof query.id === 'undefined') { | ||
throw new Error('You must specify an id'); | ||
} | ||
return this.appendURL('acl/policy', [query.id], this.cleanQuery(query)); | ||
}, | ||
urlForCreateRecord: function(modelName, snapshot) { | ||
return this.appendURL('acl/policy', [], { | ||
[API_DATACENTER_KEY]: snapshot.attr(DATACENTER_KEY), | ||
}); | ||
}, | ||
urlForUpdateRecord: function(id, modelName, snapshot) { | ||
return this.appendURL('acl/policy', [snapshot.attr(SLUG_KEY)], { | ||
[API_DATACENTER_KEY]: snapshot.attr(DATACENTER_KEY), | ||
}); | ||
}, | ||
urlForDeleteRecord: function(id, modelName, snapshot) { | ||
return this.appendURL('acl/policy', [snapshot.attr(SLUG_KEY)], { | ||
[API_DATACENTER_KEY]: snapshot.attr(DATACENTER_KEY), | ||
}); | ||
}, | ||
urlForTranslateRecord: function(modelName, snapshot) { | ||
return this.appendURL('acl/policy/translate', [], {}); | ||
}, | ||
dataForRequest: function(params) { | ||
const data = this._super(...arguments); | ||
switch (params.requestType) { | ||
case REQUEST_UPDATE: | ||
case REQUEST_CREATE: | ||
return data.policy; | ||
} | ||
return data; | ||
}, | ||
handleResponse: function(status, headers, payload, requestData) { | ||
let response = payload; | ||
if (status === HTTP_OK) { | ||
const url = this.parseURL(requestData.url); | ||
switch (true) { | ||
case response === true: | ||
response = this.handleBooleanResponse(url, response, PRIMARY_KEY, SLUG_KEY); | ||
break; | ||
case Array.isArray(response): | ||
response = this.handleBatchResponse(url, response, PRIMARY_KEY, SLUG_KEY); | ||
break; | ||
default: | ||
response = this.handleSingleResponse(url, response, PRIMARY_KEY, SLUG_KEY); | ||
} | ||
} | ||
return this._super(status, headers, response, requestData); | ||
}, | ||
methodForRequest: function(params) { | ||
switch (params.requestType) { | ||
case REQUEST_CREATE: | ||
return HTTP_PUT; | ||
} | ||
return this._super(...arguments); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,199 @@ | ||
import { inject as service } from '@ember/service'; | ||
import Adapter, { | ||
REQUEST_CREATE, | ||
REQUEST_UPDATE, | ||
DATACENTER_QUERY_PARAM as API_DATACENTER_KEY, | ||
} from './application'; | ||
|
||
import { PRIMARY_KEY, SLUG_KEY } from 'consul-ui/models/token'; | ||
import { FOREIGN_KEY as DATACENTER_KEY } from 'consul-ui/models/dc'; | ||
import { OK as HTTP_OK } from 'consul-ui/utils/http/status'; | ||
import { PUT as HTTP_PUT } from 'consul-ui/utils/http/method'; | ||
|
||
import { get } from '@ember/object'; | ||
|
||
const REQUEST_CLONE = 'cloneRecord'; | ||
const REQUEST_SELF = 'querySelf'; | ||
|
||
export default Adapter.extend({ | ||
store: service('store'), | ||
cleanQuery: function(_query) { | ||
const query = this._super(...arguments); | ||
// TODO: Make sure policy is being passed through | ||
delete _query.policy; | ||
// take off the secret for /self | ||
delete query.secret; | ||
return query; | ||
}, | ||
urlForQuery: function(query, modelName) { | ||
return this.appendURL('acl/tokens', [], this.cleanQuery(query)); | ||
}, | ||
urlForQueryRecord: function(query, modelName) { | ||
if (typeof query.id === 'undefined') { | ||
throw new Error('You must specify an id'); | ||
} | ||
return this.appendURL('acl/token', [query.id], this.cleanQuery(query)); | ||
}, | ||
urlForQuerySelf: function(query, modelName) { | ||
return this.appendURL('acl/token/self', [], this.cleanQuery(query)); | ||
}, | ||
urlForCreateRecord: function(modelName, snapshot) { | ||
return this.appendURL('acl/token', [], { | ||
[API_DATACENTER_KEY]: snapshot.attr(DATACENTER_KEY), | ||
}); | ||
}, | ||
urlForUpdateRecord: function(id, modelName, snapshot) { | ||
// If a token has Rules, use the old API | ||
if (typeof snapshot.attr('Rules') !== 'undefined') { | ||
return this.appendURL('acl/update', [], { | ||
[API_DATACENTER_KEY]: snapshot.attr(DATACENTER_KEY), | ||
}); | ||
} | ||
return this.appendURL('acl/token', [snapshot.attr(SLUG_KEY)], { | ||
[API_DATACENTER_KEY]: snapshot.attr(DATACENTER_KEY), | ||
}); | ||
}, | ||
urlForDeleteRecord: function(id, modelName, snapshot) { | ||
return this.appendURL('acl/token', [snapshot.attr(SLUG_KEY)], { | ||
[API_DATACENTER_KEY]: snapshot.attr(DATACENTER_KEY), | ||
}); | ||
}, | ||
urlForRequest: function({ type, snapshot, requestType }) { | ||
switch (requestType) { | ||
case 'cloneRecord': | ||
return this.urlForCloneRecord(type.modelName, snapshot); | ||
case 'querySelf': | ||
return this.urlForQuerySelf(snapshot, type.modelName); | ||
} | ||
return this._super(...arguments); | ||
}, | ||
urlForCloneRecord: function(modelName, snapshot) { | ||
return this.appendURL('acl/token', [snapshot.attr(SLUG_KEY), 'clone'], { | ||
[API_DATACENTER_KEY]: snapshot.attr(DATACENTER_KEY), | ||
}); | ||
}, | ||
self: function(store, modelClass, snapshot) { | ||
const params = { | ||
store: store, | ||
type: modelClass, | ||
snapshot: snapshot, | ||
requestType: 'querySelf', | ||
}; | ||
// _requestFor is private... but these methods aren't, until they disappear.. | ||
const request = { | ||
method: this.methodForRequest(params), | ||
url: this.urlForRequest(params), | ||
headers: this.headersForRequest(params), | ||
data: this.dataForRequest(params), | ||
}; | ||
// TODO: private.. | ||
return this._makeRequest(request); | ||
}, | ||
clone: function(store, modelClass, id, snapshot) { | ||
const params = { | ||
store: store, | ||
type: modelClass, | ||
id: id, | ||
snapshot: snapshot, | ||
requestType: 'cloneRecord', | ||
}; | ||
// _requestFor is private... but these methods aren't, until they disappear.. | ||
const request = { | ||
method: this.methodForRequest(params), | ||
url: this.urlForRequest(params), | ||
headers: this.headersForRequest(params), | ||
data: this.dataForRequest(params), | ||
}; | ||
// TODO: private.. | ||
return this._makeRequest(request); | ||
}, | ||
handleSingleResponse: function(url, response, primary, slug) { | ||
// Sometimes we get `Policies: null`, make null equal an empty array | ||
if (typeof response.Policies === 'undefined' || response.Policies === null) { | ||
response.Policies = []; | ||
} | ||
// Convert an old style update response to a new style | ||
if (typeof response['ID'] !== 'undefined') { | ||
const item = get(this, 'store') | ||
.peekAll('token') | ||
.findBy('SecretID', response['ID']); | ||
if (item) { | ||
response['SecretID'] = response['ID']; | ||
response['AccessorID'] = get(item, 'AccessorID'); | ||
} | ||
} | ||
return this._super(url, response, primary, slug); | ||
}, | ||
handleResponse: function(status, headers, payload, requestData) { | ||
let response = payload; | ||
if (status === HTTP_OK) { | ||
const url = this.parseURL(requestData.url); | ||
switch (true) { | ||
case response === true: | ||
response = this.handleBooleanResponse(url, response, PRIMARY_KEY, SLUG_KEY); | ||
break; | ||
case Array.isArray(response): | ||
response = this.handleBatchResponse(url, response, PRIMARY_KEY, SLUG_KEY); | ||
break; | ||
default: | ||
response = this.handleSingleResponse(url, response, PRIMARY_KEY, SLUG_KEY); | ||
} | ||
} | ||
return this._super(status, headers, response, requestData); | ||
}, | ||
methodForRequest: function(params) { | ||
switch (params.requestType) { | ||
case REQUEST_CLONE: | ||
case REQUEST_CREATE: | ||
return HTTP_PUT; | ||
} | ||
return this._super(...arguments); | ||
}, | ||
headersForRequest: function(params) { | ||
switch (params.requestType) { | ||
case REQUEST_SELF: | ||
return { | ||
'X-Consul-Token': params.snapshot.secret, | ||
}; | ||
} | ||
return this._super(...arguments); | ||
}, | ||
dataForRequest: function(params) { | ||
let data = this._super(...arguments); | ||
switch (params.requestType) { | ||
case REQUEST_UPDATE: | ||
// If a token has Rules, use the old API | ||
if (typeof data.token['Rules'] !== 'undefined') { | ||
data.token['ID'] = data.token['SecretID']; | ||
data.token['Name'] = data.token['Description']; | ||
} | ||
// falls through | ||
case REQUEST_CREATE: | ||
if (Array.isArray(data.token.Policies)) { | ||
data.token.Policies = data.token.Policies.filter(function(item) { | ||
// Just incase, don't save any policies that aren't saved | ||
return !get(item, 'isNew'); | ||
}).map(function(item) { | ||
return { | ||
ID: get(item, 'ID'), | ||
Name: get(item, 'Name'), | ||
}; | ||
}); | ||
} else { | ||
delete data.token.Policies; | ||
} | ||
data = data.token; | ||
break; | ||
case REQUEST_SELF: | ||
return {}; | ||
case REQUEST_CLONE: | ||
data = {}; | ||
break; | ||
} | ||
// make sure we never send the SecretID | ||
if (data && typeof data['SecretID'] !== 'undefined') { | ||
delete data['SecretID']; | ||
} | ||
return data; | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,12 @@ | ||
import Component from '@ember/component'; | ||
|
||
import qsaFactory from 'consul-ui/utils/dom/qsa-factory'; | ||
const $$ = qsaFactory(); | ||
export default Component.extend({ | ||
mode: 'application/json', | ||
classNames: ['code-editor'], | ||
onkeyup: function() {}, | ||
didAppear: function() { | ||
const $editor = [...$$('textarea + div', this.element)][0]; | ||
$editor.CodeMirror.refresh(); | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
import Component from '@ember/component'; | ||
|
||
export default Component.extend({}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
import Component from '@ember/component'; | ||
|
||
export default Component.extend({ | ||
tagName: '', | ||
execute: function() {}, | ||
cancel: function() {}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { inject as service } from '@ember/service'; | ||
import { get } from '@ember/object'; | ||
import Component from '@ember/component'; | ||
const append = function(content) { | ||
this.element.appendChild(content); | ||
}; | ||
export default Component.extend({ | ||
buffer: service('dom-buffer'), | ||
init: function() { | ||
this._super(...arguments); | ||
this.append = append.bind(this); | ||
}, | ||
didInsertElement: function() { | ||
get(this, 'buffer').on('add', this.append); | ||
}, | ||
didDestroyElement: function() { | ||
get(this, 'buffer').off('add', this.append); | ||
}, | ||
}); |
Oops, something went wrong.