Skip to content

Commit

Permalink
Merge pull request #127 from marceldiass/snis+certs
Browse files Browse the repository at this point in the history
Add capability to manage SNIs & Certificates
  • Loading branch information
PGBI committed Oct 5, 2017
2 parents c149c48 + 466f1f9 commit 12941f1
Show file tree
Hide file tree
Showing 10 changed files with 533 additions and 0 deletions.
65 changes: 65 additions & 0 deletions src/html/certificates/form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<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 certificate object represents a public certificate/private key pair for an SSL certificate. These objects are used by Kong
to handle SSL/TLS termination for encrypted requests. Certificates are optionally associated with SNI
objects to tie a cert/key pair to one or more hostnames.
</p>

<p class="white-text">
Checkout <a href="https://getkong.org/docs/latest/admin-api/#add-certificate" target="_blank">Kong documentation</a> for the meaning of the form parameters.
</p>
</div>
</div>
<form name="addCertificate" class="col s7" novalidate ng-submit="save()">
<div class="row">

<div class="input-field col s12" ng-show="isEdit()">
<input id="id" ng-model="certificate.id" type="text" class="validate"
ng-class="{invalid: error.id}" ng-readonly="isEdit()" >
<label for="id" ng-class="{active:certificate.id}">ID</label>
<app-field-error error="error.id"></app-field-error>
</div>
<div class="input-field col s12">
<textarea autofocus id="cert" ng-model="certificate.cert" class="validate materialize-textarea"
ng-required="true" ng-class="{invalid: error.cert}" rows="4"></textarea>
<label for="cert" ng-class="{active:certificate.cert}">Cert</label>
<app-field-error error="error.cert"></app-field-error>
</div>
<div class="input-field col s12">
<textarea id="key" ng-model="certificate.key" class="validate materialize-textarea"
ng-required="true" ng-class="{invalid: error.key}" rows="4"></textarea>
<label for="key" ng-class="{active:certificate.key}">Key</label>
<app-field-error error="error.key"></app-field-error>
</div>
<div class="input-field col s12">
<input id="snis" ng-model="certificate.snis" type="text" class="validate"
ng-class="{invalid: error.snis}" ng-show="! isEdit()">
<ul ng-repeat="sni in certificate.snis" ng-show="isEdit()" ng-readonly="true" >
<li>{{sni}}</li>
</ul>
<label for="snis" ng-class="{active:certificate.snis}">SNIs</label>
<app-field-error error="error.snis"></app-field-error>
</div>

<div class="input-field col s6" >
<a href="#/snis/add/{{certificate.id}}" class="waves-effect waves-light btn" ng-show="isEdit()">
<i class="material-icons left">add_box</i>
Add SNI
</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="certificate.id" value="{{certificate.id}}" />
</form>
</div>
</div>
76 changes: 76 additions & 0 deletions src/html/certificates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<div class="container" infinite-scroll="loadMore()" infinite-scroll-distance="5" infinite-scroll-use-document-bottom="true">

<ul ng-show="certificates.length >= 1" class="horizontal right">
<li>
<a href="#/certificates/add" class="btn-floating btn-large waves-effect waves-light">
<i class="material-icons">add</i>
</a>
</li>
</ul>

<h3 class="header">
Certificates
</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 Certificates in Kong yet.
</p>
<p class="center">
<a href="#/certificates/add" class="waves-effect waves-light btn">
<i class="material-icons left">add_box</i>
Add Certificate
</a>
</p>
</div>

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

<tbody>
<tr ng-repeat="certificate in certificates">
<td>{{certificate.id}}</td>
<td>{{certificate.created_at | date}}</td>
<td>
<ul ng-repeat="sni in certificate.snis" >
<li>{{sni}}</li>
</ul>
</td>

<td class="right">
<a class="btn-floating waves-effect waves-light" href="#/certificates/{{certificate.id}}">
<i class="material-icons">mode_edit</i>
</a>
<a class="btn-floating waves-effect waves-light blue" href="#/snis/add/{{certificate.id}}">
<i class="material-icons">dns</i>
</a>
<a class="btn-floating waves-effect waves-light red modal-trigger" ng-click="showDeleteModal(certificate.id)">
<i class="material-icons">delete</i>
</a>
</td>
</tr>
</tbody>
</table>
</div>

<!-- Modal Structure -->
<div id="deleteCertificate" class="modal">
<div class="modal-content">
<h5>Do you really want to delete the Certificate "{{current.id}}"?</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>
10 changes: 10 additions & 0 deletions src/html/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
<i class="material-icons tooltipped" data-position="bottom" data-tooltip="Manage Plugins" data-delay="0">extension</i>
</a>
</li>
<li>
<a href="#/snis">
<i class="material-icons tooltipped" data-position="bottom" data-tooltip="Manage SNIS" data-delay="0">dns</i>
</a>
</li>
<li>
<a href="#/certificates">
<i class="material-icons tooltipped" data-position="bottom" data-tooltip="Manage Certificates" data-delay="0">https</i>
</a>
</li>
</ul>
</div>
</nav>
Expand Down
42 changes: 42 additions & 0 deletions src/html/snis/form.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<div class="container">
<h3 class="header">{{title}}</h3>

<div class="row">
<div class="col s5">
<div class="card-panel teal">
<p class="white-text">
An SNI object represents a many-to-one mapping of hostnames to a certificate. That is, a certificate object can have many hostnames associated with it; when Kong receives an SSL request, it uses the SNI field in the Client Hello to lookup the certificate object based on the SNI associated with the certificate.
</p>

<p class="white-text">
Checkout <a href="https://getkong.org/docs/latest/admin-api/#add-sni" target="_blank">Kong documentation</a> for the meaning of the form parameters.
</p>
</div>
</div>
<form name="addSni" class="col s7" novalidate ng-submit="save()">
<div class="row">
<div class="input-field col s12">
<input id="name" autofocus ng-required="true" ng-model="sni.name" type="text"
ng-class="{invalid: error.name}" ng-readonly="isEdit()" class="validate" >
<label for="name" ng-class="{active:sni.name}">Name</label>
<app-field-error error="error.name"></app-field-error>
</div>
<div class="input-field col s12">
<label class="active">SSL Certificate ID</label>
<select materialize-select required id="ssl_certificate_id"
ng-model="sni.ssl_certificate_id"
ng-options="cert.id as cert.id for cert in certificates"
>
</select>
<app-field-error error="error.ssl_certificate_id"></app-field-error>
</div>
<div class="input-field col s12">
<button type="submit" class="waves-effect waves-light btn right">
{{action}}
</button>
</div>
</div>
<input type="hidden" ng-model="sni.name" value="{{sni.name}}"/>
</form>
</div>
</div>
68 changes: 68 additions & 0 deletions src/html/snis/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
<div class="container" infinite-scroll="loadMore()" infinite-scroll-distance="5" infinite-scroll-use-document-bottom="true">

<ul ng-show="snis.length >= 1" class="horizontal right">
<li>
<a href="#/snis/add" class="btn-floating btn-large waves-effect waves-light">
<i class="material-icons">add</i>
</a>
</li>
</ul>

<h3 class="header">
SNIs
</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 SNI in Kong yet.
</p>
<p class="center">
<a href="#/snis/add" class="waves-effect waves-light btn">
<i class="material-icons left">add_box</i>
Add SNI
</a>
</p>
</div>

<table class="bordered" ng-show="total > 0">
<thead>
<tr>
<th>Name</th>
<th>SSL Certificate id</th>
<th>Created</th>
<th></th>
</tr>
</thead>

<tbody>
<tr ng-repeat="sni in snis">
<td>{{sni.name}}</td>
<td>{{sni.ssl_certificate_id}}</td>
<td>{{sni.created_at | date}}</td>
<td class="right">
<a class="btn-floating waves-effect waves-light" href="#/snis/{{sni.name}}">
<i class="material-icons">mode_edit</i>
</a>
<a class="btn-floating waves-effect waves-light red modal-trigger" ng-click="showDeleteModal(sni.name)">
<i class="material-icons">delete</i>
</a>
</td>
</tr>
</tbody>
</table>
</div>

<!-- Modal Structure -->
<div id="deleteSni" class="modal">
<div class="modal-content">
<h5>Do you really want to delete the SNI "{{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>
49 changes: 49 additions & 0 deletions src/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,55 @@ var app = angular.module('app', ['ngRoute', 'ngCookies', 'ngAnimate', 'ngSanitiz
}]
}
})
.when('/snis', {
templateUrl: 'html/snis/index.html',
controller: 'SnisController',
resolve: {
isAppReady: isAppReady
}
})
.when('/snis/add', {
templateUrl: 'html/snis/form.html',
controller: 'SniController',
resolve: {
isAppReady: isAppReady
}
})
.when('/snis/:name', {
templateUrl: 'html/snis/form.html',
controller: 'SniController',
resolve: {
isAppReady: isAppReady,
}
})
.when('/snis/add/:certificate_id', {
templateUrl: 'html/snis/form.html',
controller: 'SniController',
resolve: {
isAppReady: isAppReady
}
})
.when('/certificates', {
templateUrl: 'html/certificates/index.html',
controller: 'CertificatesController',
resolve: {
isAppReady: isAppReady
}
})
.when('/certificates/add', {
templateUrl: 'html/certificates/form.html',
controller: 'CertificateController',
resolve: {
isAppReady: isAppReady
}
})
.when('/certificates/:id', {
templateUrl: 'html/certificates/form.html',
controller: 'CertificateController',
resolve: {
isAppReady: isAppReady,
}
})
.otherwise({redirectTo: '/'});
}])
.run(['$rootScope', 'Kong', '$location', function($rootScope, Kong, $location) {
Expand Down
46 changes: 46 additions & 0 deletions src/js/controllers/certificate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
angular.module('app').controller("CertificateController", ["$scope", "Kong", "$location", "$routeParams", "Alert", "$route", function ($scope, Kong, $location, $routeParams, Alert, $route) {

$scope.certificate = {};

onInit();

function onInit() {
if ($routeParams.id) {
Kong.get('/certificates/' + $routeParams.id).then( function(data) {
$scope.certificate = data;
});
$scope.title = "Edit Certificate";
$scope.action = "Save";
$scope.location = $location;
} else {
$scope.title = "Add a Certificate";
$scope.action = "Create";
}
}

$scope.isEdit = function () {
return $routeParams.id != null;
}

$scope.save = function () {
if ( $scope.isEdit() ) {
Kong.patch('/certificates/' + $scope.certificate.id, $scope.certificate).then(function () {
Alert.success('Certificate updated');
$scope.error = {};
}, function (response) {
$scope.error = response.data;
});
} else {
Kong.post('/certificates', $scope.certificate).then(function () {
Alert.success('Certificate created');
// clearing inputs.
$scope.certificate = {};

// clearing errors.
$scope.error = {};
}, function (response) {
$scope.error = response.data;
});
}
};
}]);
Loading

0 comments on commit 12941f1

Please sign in to comment.