mirror of https://github.com/status-im/consul.git
ui/acls: initial commit
This commit is contained in:
parent
e08e66367c
commit
1080cb398a
162
ui/index.html
162
ui/index.html
|
@ -38,6 +38,31 @@
|
||||||
</div>
|
</div>
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script type="text/x-handlebars" data-template-name="dc/unauthorized">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 col-md-offset-2 col-sm-12 col-xs-12">
|
||||||
|
<div class="text-center vertical-center">
|
||||||
|
<p class="bold">Access Denied</p>
|
||||||
|
<p>Your ACL token, <code>foobarbaz</code>, does not
|
||||||
|
have the appropriate permissions to perform the expected action.</p>
|
||||||
|
<p>Learn more in the <a href="http://www.consul.io/docs/internals/acl.html">ACL documentation</a>.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/x-handlebars" data-template-name="dc/aclsdisabled">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-8 col-md-offset-2 col-sm-12 col-xs-12">
|
||||||
|
<div class="text-center vertical-center">
|
||||||
|
<p class="bold">ACLs Disabled</p>
|
||||||
|
<p>ACLs are disabled in this Consul cluster. This is the default behavior, as you have to implicitly enable them.</p>
|
||||||
|
</p>Learn more in the <a href="http://www.consul.io/docs/internals/acl.html">ACL documentation</a>.</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
<script type="text/x-handlebars" data-template-name="loading">
|
<script type="text/x-handlebars" data-template-name="loading">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-8 col-md-offset-2 col-sm-12 col-xs-12">
|
<div class="col-md-8 col-md-offset-2 col-sm-12 col-xs-12">
|
||||||
|
@ -524,6 +549,143 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<script type="text/x-handlebars" id="acls">
|
||||||
|
<div class="row">
|
||||||
|
<div {{ bind-attr class=":col-md-6 :col-lg-5 :padded-right-middle isShowingItem:hidden-xs isShowingItem:hidden-sm" }}>
|
||||||
|
{{view App.ActionBarView }}
|
||||||
|
|
||||||
|
{{#if filteredContent}}
|
||||||
|
|
||||||
|
{{#if condensed }}
|
||||||
|
{{#collection Ember.ListView contentBinding="filteredContent" height=800 rowHeight=44 }}
|
||||||
|
{{#link-to 'acl.show' Node tagName="div" href=false class="list-group-item list-condensed-link" }}
|
||||||
|
<div {{bind-attr class=":list-bar-horizontal"}}></div>
|
||||||
|
<div class="name">
|
||||||
|
foo
|
||||||
|
<small class="pull-right">
|
||||||
|
bar
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
{{/link-to}}
|
||||||
|
{{/collection}}
|
||||||
|
|
||||||
|
{{else}}
|
||||||
|
|
||||||
|
{{#collection Ember.ListView contentBinding="filteredContent" height=800 rowHeight=120 }}
|
||||||
|
{{#link-to 'nodes.show' Node tagName="div" href=false class="list-group-item list-link" }}
|
||||||
|
<div {{bind-attr class="hasFailingChecks:bg-orange:bg-green :list-bar"}}></div>
|
||||||
|
<h4 class="list-group-item-heading">
|
||||||
|
{{Node}}
|
||||||
|
<small>{{Address}}</small>
|
||||||
|
<div class="heading-helper">
|
||||||
|
<a class="subtle" href="#">{{checkMessage}}</a>
|
||||||
|
</div>
|
||||||
|
</h4>
|
||||||
|
<ul class="list-inline">
|
||||||
|
{{#each service in services}}
|
||||||
|
<li class="bold">{{service.Service}}</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
{{/link-to}}
|
||||||
|
{{/collection}}
|
||||||
|
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{else}}
|
||||||
|
<p class="light">There are no nodes to show.</p>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="border-left hidden-xs hidden-sm">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6 col-lg-7 border-left scrollable">
|
||||||
|
<div class="row padded-border">
|
||||||
|
{{outlet}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/x-handlebars" id="acl">
|
||||||
|
<div class="col-xs-12 col-sm-12 visible-xs visible-sm">
|
||||||
|
{{#link-to "nodes" class="btn btn-default btn-block" }}Back to all nodes{{/link-to}}
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 class="no-margin">{{ model.Node }} <small> {{ model.Address }}</small></h3>
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<h5>Services</h5>
|
||||||
|
|
||||||
|
{{#each service in model.Services }}
|
||||||
|
{{#link-to 'services.show' service.Service tagName="div" href=false class="list-group-item list-condensed-link double-line" }}
|
||||||
|
<div class="list-bar-horizontal bg-light-gray"></div>
|
||||||
|
<div class="name">
|
||||||
|
{{service.Service}}
|
||||||
|
<small class="pull-right">
|
||||||
|
:{{service.Port}}
|
||||||
|
</small>
|
||||||
|
</div>
|
||||||
|
<ul class="list-inline sub">
|
||||||
|
{{#each tag in service.Tags}}
|
||||||
|
<li>{{tag}}</li>
|
||||||
|
{{/each}}
|
||||||
|
{{serviceTagMessage service.Tags}}
|
||||||
|
</ul>
|
||||||
|
{{/link-to}}
|
||||||
|
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
<h5>Checks</h5>
|
||||||
|
|
||||||
|
{{#each check in model.Checks }}
|
||||||
|
|
||||||
|
<div class="panel">
|
||||||
|
{{ panelBar check.Status }}
|
||||||
|
<div class="panel-heading">
|
||||||
|
<h3 class="panel-title">
|
||||||
|
{{check.Name}}
|
||||||
|
<small>{{check.CheckID}}</small>
|
||||||
|
<span class="panel-note">{{check.Status}}</span>
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="panel-body">
|
||||||
|
<h5>Notes</h5>
|
||||||
|
<p>{{ check.Notes }}</p>
|
||||||
|
<h5>Output</h5>
|
||||||
|
<pre>{{check.Output}}</pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
<h5>Lock Sessions</h5>
|
||||||
|
|
||||||
|
{{#if sessions }}
|
||||||
|
{{errorMessage}}
|
||||||
|
|
||||||
|
{{#each session in sessions }}
|
||||||
|
<div class="list-group-item list-condensed double-line">
|
||||||
|
<div class="bg-light-gray list-bar-horizontal"></div>
|
||||||
|
<div class="name">
|
||||||
|
{{ sessionName session }}
|
||||||
|
<button {{ action "invalidateSession" session.ID }} {{ bind-attr class=":btn :btn-danger :pull-right :btn-list isLoading:btn-warning" }}>Invalidate</button>
|
||||||
|
</div>
|
||||||
|
<ul class="list-inline sub">
|
||||||
|
{{#each check in session.Checks}}
|
||||||
|
<li class="bold">{{check}}</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
{{else}}
|
||||||
|
<p class="light small">No sessions</p>
|
||||||
|
{{/if}}
|
||||||
|
</script>
|
||||||
|
|
||||||
<script type="text/x-handlebars" id="index">
|
<script type="text/x-handlebars" id="index">
|
||||||
<div class="col-md-8 col-md-offset-2 col-xs-offset-0 col-sm-offset-0 col-xs-12 col-sm-12 vertical-center">
|
<div class="col-md-8 col-md-offset-2 col-xs-offset-0 col-sm-offset-0 col-xs-12 col-sm-12 vertical-center">
|
||||||
<h5>Select a datacenter</h5>
|
<h5>Select a datacenter</h5>
|
||||||
|
|
|
@ -313,3 +313,36 @@ App.ServicesController = ItemBaseController.extend({
|
||||||
items: Ember.computed.alias("services"),
|
items: Ember.computed.alias("services"),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
App.AclsIndexController = Ember.ArrayController.extend({
|
||||||
|
needs: ["dc", "application"],
|
||||||
|
queryParams: ["filter"],
|
||||||
|
dc: Ember.computed.alias("controllers.dc"),
|
||||||
|
|
||||||
|
isShowingItem: function() {
|
||||||
|
var currentPath = this.get('controllers.application.currentPath');
|
||||||
|
return (currentPath === "dc.acls.show");
|
||||||
|
}.property('controllers.application.currentPath'),
|
||||||
|
|
||||||
|
filteredContent: function() {
|
||||||
|
var filter = this.get('filter');
|
||||||
|
|
||||||
|
var items = this.get('items').filter(function(item, index, enumerable){
|
||||||
|
// First try to match on the name
|
||||||
|
var nameMatch = item.get('Name').toLowerCase().match(filter.toLowerCase());
|
||||||
|
if (nameMatch.length > 0) {
|
||||||
|
return nameMatch;
|
||||||
|
// Otherwise match on the ID
|
||||||
|
} else {
|
||||||
|
return item.get('ID').toLowerCase().match(filter.toLowerCase());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}.property('filter', 'items.@each'),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
App.AclsShowController = Ember.ArrayController.extend({
|
||||||
|
needs: ["dc"],
|
||||||
|
dc: Ember.computed.alias("controllers.dc"),
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
@ -239,3 +239,9 @@ App.Key = Ember.Object.extend(Ember.Validations.Mixin, {
|
||||||
return parts.join("/") + "/";
|
return parts.join("/") + "/";
|
||||||
}.property('Key')
|
}.property('Key')
|
||||||
});
|
});
|
||||||
|
|
||||||
|
//
|
||||||
|
// An ACL
|
||||||
|
//
|
||||||
|
App.Acl = Ember.Object.extend({
|
||||||
|
});
|
||||||
|
|
|
@ -25,7 +25,14 @@ App.Router.map(function() {
|
||||||
this.route("show", { path: "/*key" });
|
this.route("show", { path: "/*key" });
|
||||||
// Edit a specific key
|
// Edit a specific key
|
||||||
this.route("edit", { path: "/*key/edit" });
|
this.route("edit", { path: "/*key/edit" });
|
||||||
})
|
});
|
||||||
|
// ACLs
|
||||||
|
this.resource("acls", { path: "/acls" }, function(){
|
||||||
|
this.route("show", { path: "/:name" });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Shows a page explaining that ACLs haven't been set-up
|
||||||
|
this.route("aclsdisabled", { path: "/aclsdisabled" });
|
||||||
});
|
});
|
||||||
|
|
||||||
// Shows a datacenter picker. If you only have one
|
// Shows a datacenter picker. If you only have one
|
||||||
|
|
|
@ -299,3 +299,36 @@ App.NodesRoute = App.BaseRoute.extend({
|
||||||
controller.set('nodes', model);
|
controller.set('nodes', model);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
App.AclsRoute = App.BaseRoute.extend({
|
||||||
|
model: function(params) {
|
||||||
|
var dc = this.modelFor('dc').dc;
|
||||||
|
// Return a promise containing the ACLS
|
||||||
|
return Ember.$.getJSON('/v1/acl/list?dc=' + dc).then(function(data) {
|
||||||
|
objs = [];
|
||||||
|
data.map(function(obj){
|
||||||
|
objs.push(App.Acl.create(obj));
|
||||||
|
});
|
||||||
|
return objs;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
error: function(error, transition) {
|
||||||
|
// If consul returns 401, ACLs are disabled
|
||||||
|
if (error && error.status === 401) {
|
||||||
|
this.transitionTo('dc.aclsdisabled');
|
||||||
|
// If consul returns 403, they key isn't authorized for that
|
||||||
|
// action.
|
||||||
|
} else if (error && error.status === 403) {
|
||||||
|
this.transitionTo('dc.unauthorized');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController: function(controller, model) {
|
||||||
|
controller.set('acls', model);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -62,3 +62,13 @@ App.KvListView = Ember.View.extend({
|
||||||
App.ActionBarView = Ember.View.extend({
|
App.ActionBarView = Ember.View.extend({
|
||||||
templateName: 'actionbar'
|
templateName: 'actionbar'
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ACLS
|
||||||
|
|
||||||
|
App.AclView = Ember.View.extend({
|
||||||
|
templateName: 'acls',
|
||||||
|
});
|
||||||
|
|
||||||
|
App.AclsShowView = Ember.View.extend({
|
||||||
|
templateName: 'acl'
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue