Skip to content

Commit

Permalink
Merge pull request #130 from marceldiass/upstream+targets
Browse files Browse the repository at this point in the history
Add Upstreams
  • Loading branch information
PGBI authored Nov 24, 2017
2 parents bcf6c26 + 5045c4d commit 4b7779a
Show file tree
Hide file tree
Showing 10 changed files with 594 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,11 @@
<i class="material-icons tooltipped" data-position="bottom" data-tooltip="Manage Certificates" data-delay="0">https</i>
</a>
</li>
<li>
<a href="#/upstreams">
<i class="material-icons tooltipped" data-position="bottom" data-tooltip="Manage Upstreams" data-delay="0">input</i>
</a>
</li>
</ul>
</div>
</nav>
Expand Down
58 changes: 58 additions & 0 deletions src/html/targets/form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<div class="container">
<h3 class="header">{{title}}</h3>

<div class="row">
<div class="col s5">
<div class="card-panel teal">
<p class="white-text">
A target is an ip address/hostname with a port that identifies an instance of a backend service. Every upstream can have many targets, and the targets can be dynamically added. Changes are effectuated on the fly.
Because the upstream maintains a history of target changes, the targets cannot be deleted or modified. To disable a target, post a new one with weight=0; alternatively, use the DELETE convenience method to accomplish the same.
The current target object definition is the one with the latest created_at.
</p>

<p class="white-text">
Checkout <a href="https://getkong.org/docs/latest/admin-api/#add-target" target="_blank">Kong documentation</a> for the meaning of the form parameters.
</p>
</div>
</div>
<form name="addTarget" class="col s7" novalidate ng-submit="save()">
<div class="row">
<div class="input-field col s12">
<input id="upstream_id" ng-model="upstream.name" type="text" class="validate"
ng-class="{invalid: error.upstream_name}" ng-readonly="true" >
<label for="upstream_id" class="active">Upstream</label>
</div>
<div class="input-field col s12" ng-show="isEdit()">
<input id="id" ng-model="target.id" type="text" class="validate"
ng-class="{invalid: error.id}" ng-readonly="true" >
<label for="id" class="active">ID</label>
<app-field-error error="error.id"></app-field-error>
</div>
<div class="input-field col s12">
<input id="name" autofocus ng-required="true" ng-model="target.target" type="text"
ng-class="{invalid: error.target}" class="validate" placeholder="127.0.0.1:8080" >
<label for="name" ng-class="{active:target.target}">Target</label>
<app-field-error error="error.target"></app-field-error>
</div>
<div class="input-field col s12">
<input id="weight" autofocus ng-required="true" ng-model="target.weight" type="text"
ng-class="{invalid: error.weight}" class="validate" >
<label for="weight" ng-class="{active:target.weight}">Weight</label>
<app-field-error error="error.weight"></app-field-error>
</div>
<div class="input-field col s6">
<a href="#/upstreams/{{upstream.id}}/targets" class="waves-effect waves-light btn">
<i class="material-icons left">list</i>
List Targets
</a>
</div>
<div class="input-field col s6">
<button type="submit" class="waves-effect waves-light btn right">
{{action}}
</button>
</div>
</div>
<input type="hidden" ng-model="target.id" value="{{target.id}}"/>
</form>
</div>
</div>
87 changes: 87 additions & 0 deletions src/html/targets/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<div class="container" infinite-scroll="loadMore()" infinite-scroll-distance="5" infinite-scroll-use-document-bottom="true">

<ul ng-show="targets.length >= 1" class="horizontal right">
<li class="search" style="width:300px;">

<div class="switch">
<label>
All Targets
<input type="checkbox" ng-model="active" ng-change="reloadList()"><span class="lever"></span>
Active Targets
</label>
</div>

</li>
<li>
<a href="#/upstreams/{{ upstream.id }}/targets/add" class="btn-floating btn-large waves-effect waves-light">
<i class="material-icons">add</i>
</a>
</li>
</ul>

<h3 class="header">
{{title}}
</h3>

<p class="flow-text center" ng-show="total === null" style="margin-top:50px;">
<app-loader></app-loader>
</p>

<div class ng-show="total === 0">
<p class="flow-text center">
You haven't defined any Target for {{upstream.name}}
</p>
<p class="center">
<a href="#/upstreams/{{ upstream.id }}/targets/add" class="waves-effect waves-light btn">
<i class="material-icons left">add_box</i>
Add Target
</a>
</p>
</div>

<table class="bordered" ng-show="total > 0">
<thead>
<tr>
<th>ID</th>
<th>Target</th>
<th>Weight</th>
<th>Created</th>
<th></th>
</tr>
</thead>

<tbody>
<tr ng-repeat="target in targets">
<td>{{target.id}}</td>
<td>{{target.target}}</td>
<td>{{target.weight}}</td>
<td>{{target.created_at | date}}</td>
<td class="right">
<a class="btn-floating waves-effect waves-light red modal-trigger" ng-click="showDeleteModal(target.id, target.name, target.upstream_id)">
<i class="material-icons">delete</i>
</a>
</td>
</tr>
</tbody>
</table>

<div class="row">
<div class="input-field col s6 " >
<a href="#/upstreams/{{upstream.id}}" class="waves-effect waves-light btn" >
<i class="material-icons left">arrow_back</i>
Upstream
</a>
</div>
</div>
</div>

<!-- Modal Structure -->
<div id="deleteTarget" class="modal">
<div class="modal-content">
<h5>Do you really want to delete the Target "{{current.name}}"?</h5>
</div>
<div class="modal-footer">
<a class="waves-effect waves-green btn" ng-click="abortDelete()">Noooooo!</a>
<a class="waves-effect waves-red btn red" ng-click="performDelete()" style="margin-right:10px">Yes</a>
</div>
</div>
58 changes: 58 additions & 0 deletions src/html/upstreams/form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<div class="container">
<h3 class="header">{{title}}</h3>

<div class="row">
<div class="col s5">
<div class="card-panel teal">
<p class="white-text">
The upstream object represents a virtual hostname and can be used to loadbalance incoming requests over multiple services (targets). So for example an upstream named service.v1.xyz with an API object created with an upstream_url=https://service.v1.xyz/some/path. Requests for this API would be proxied to the targets defined within the upstream.
</p>

<p class="white-text">
Checkout <a href="https://getkong.org/docs/latest/admin-api/#add-upstream" target="_blank">Kong documentation</a> for the meaning of the form parameters.
</p>
</div>
</div>
<form name="addUpstream" class="col s7" novalidate ng-submit="save()">
<div class="row">
<div class="input-field col s12" ng-show="isEdit()">
<input id="id" ng-model="upstream.id" type="text" class="validate"
ng-class="{invalid: error.id}" ng-readonly="isEdit()" >
<label for="id" ng-class="{active:upstream.id}">ID</label>
<app-field-error error="error.id"></app-field-error>
</div>
<div class="input-field col s12">
<input id="name" autofocus ng-required="true" ng-model="upstream.name" type="text"
ng-class="{invalid: error.name}" class="validate" >
<label for="name" ng-class="{active:upstream.name}">Name</label>
<app-field-error error="error.name"></app-field-error>
</div>
<div class="input-field col s12">
<input id="slots" autofocus ng-required="true" ng-model="upstream.slots" type="text"
ng-class="{invalid: error.slots}" class="validate" >
<label for="slots" ng-class="{active:upstream.slots}">Slot</label>
<app-field-error error="error.slots"></app-field-error>
</div>

<div class="input-field col s4">
<a href="#/upstreams/{{upstream.id}}/targets/add" class="waves-effect waves-light btn" ng-show="isEdit()">
<i class="material-icons left">add_box</i>
Add Target
</a>
</div>
<div class="input-field col s4">
<a href="#/upstreams/{{upstream.id}}/targets" class="waves-effect waves-light btn" ng-show="isEdit()">
<i class="material-icons left">list</i>
List Target
</a>
</div>
<div class="input-field col s4">
<button type="submit" class="waves-effect waves-light btn right">
{{action}}
</button>
</div>
</div>
<input type="hidden" ng-model="upstream.id" value="{{upstream.id}}"/>
</form>
</div>
</div>
96 changes: 96 additions & 0 deletions src/html/upstreams/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
<div class="container" infinite-scroll="loadMore()" infinite-scroll-distance="5" infinite-scroll-use-document-bottom="true">

<ul ng-show="upstreams.length >= 1" class="horizontal right">
<li class="search" style="width:300px;">
<div class="search-wrapper card">
<input class="search" placeholder="Search upstreams" value=""
ng-focus="searchBarFocused = true"
ng-blur="searchBarFocused = false"
ng-model="searchInput"
ng-change="searchUpstreams()">
<i class="material-icons">search</i>
<div class="search-results collection" ng-show="searchBarFocused || viewingResults" ng-mouseover="viewingResults = true" ng-mouseout="viewingResults = false">
<p class="collection-item grey-text" ng-if="!searchInput">
<small>
Search Upstreams by ID or name.
</small>
</p>
<p class="collection-item grey-text" ng-if="searching && Utils.keys(searchResults).length == 0">
No results found.
</p>
<a class="collection-item" ng-repeat="(id, name) in searchResults" href="#/upstreams/{{ id }}">
{{ name }}
</a>
</div>
</div>
</li>
<li>
<a href="#/upstreams/add" class="btn-floating btn-large waves-effect waves-light">
<i class="material-icons">add</i>
</a>
</li>
</ul>

<h3 class="header">
Upstreams
</h3>

<p class="flow-text center" ng-show="total === null" style="margin-top:50px;">
<app-loader></app-loader>
</p>

<div class ng-show="total === 0">
<p class="flow-text center">
You haven't defined any Upstream in Kong yet.
</p>
<p class="center">
<a href="#/upstreams/add" class="waves-effect waves-light btn">
<i class="material-icons left">add_box</i>
Add Upstream
</a>
</p>
</div>

<table class="bordered " ng-show="total > 0">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Slots</th>
<th>Created</th>
<th></th>
</tr>
</thead>

<tbody>
<tr ng-repeat="upstream in upstreams">
<td>{{upstream.id}}</td>
<td>{{upstream.name}}</td>
<td>{{upstream.slots}}</td>
<td>{{upstream.created_at | date}}</td>
<td class="right">
<a class="btn-floating waves-effect waves-light" href="#/upstreams/{{upstream.id}}/targets" alt="List Targets">
<i class="material-icons tooltipped" data-position="bottom" data-tooltip="List Targets" data-delay="0" >input</i>
</a>
<a class="btn-floating waves-effect waves-light" href="#/upstreams/{{upstream.id}}">
<i class="material-icons">mode_edit</i>
</a>
<a class="btn-floating waves-effect waves-light red modal-trigger" ng-click="showDeleteModal(upstream.id, upstream.name)">
<i class="material-icons">delete</i>
</a>
</td>
</tr>
</tbody>
</table>
</div>

<!-- Modal Structure -->
<div id="deleteUpstream" class="modal">
<div class="modal-content">
<h5>Do you really want to delete the Upstream "{{current.name}}"?</h5>
</div>
<div class="modal-footer">
<a class="waves-effect waves-green btn" ng-click="abortDelete()">Noooooo!</a>
<a class="waves-effect waves-red btn red" ng-click="performDelete()" style="margin-right:10px">Yes</a>
</div>
</div>
39 changes: 39 additions & 0 deletions src/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,45 @@ var app = angular.module('app', ['ngRoute', 'ngCookies', 'ngAnimate', 'ngSanitiz
isAppReady: isAppReady,
}
})
.when('/upstreams', {
templateUrl: 'html/upstreams/index.html',
controller: 'UpstreamsController',
resolve: {
isAppReady: isAppReady
}
})
.when('/upstreams/add', {
templateUrl: 'html/upstreams/form.html',
controller: 'UpstreamController',
resolve: {
isAppReady: isAppReady
}
})
.when('/upstreams/:id', {
templateUrl: 'html/upstreams/form.html',
controller: 'UpstreamController',
resolve: {
isAppReady: isAppReady,
}
})
.when('/upstreams/:upstream_id/targets', {
templateUrl: 'html/targets/index.html',
controller: 'TargetsController',
resolve: {
isAppReady: isAppReady,
upstream: ['Kong', '$route', function (Kong, $route) {
var id = $route.current.params.upstream_id;
return Kong.get('/upstreams/' + id);
}]
}
})
.when('/upstreams/:upstream_id/targets/add', {
templateUrl: 'html/targets/form.html',
controller: 'TargetController',
resolve: {
isAppReady: isAppReady
}
})
.otherwise({redirectTo: '/'});
}])
.run(['$rootScope', 'Kong', '$location', function($rootScope, Kong, $location) {
Expand Down
Loading

0 comments on commit 4b7779a

Please sign in to comment.