summaryrefslogtreecommitdiffstats
path: root/sms-service
diff options
context:
space:
mode:
authorKiran Kamineni <kiran.k.kamineni@intel.com>2018-05-04 16:50:39 -0700
committerGirish Havaldar <hg0071052@techmahindra.com>2018-05-15 17:21:53 +0000
commitac134cb099afa6be09fbc5cdad5db0bcf7aee08a (patch)
treecbcdf280db9285edfe8c6e62e094c6c4c6db302e /sms-service
parentd4b81c05a255a847bbf7f08caebe032492ad2ca5 (diff)
Adding a docs folder under sms repo
WORK IN PROGRESS Adding a docs folder under sms Issue-ID: AAF-185 Change-Id: I5ee3560cfda2100ad5207bb7e98d5cb9472e1325 Signed-off-by: Girish Havaldar <hg0071052@techmahindra.com>
Diffstat (limited to 'sms-service')
-rw-r--r--sms-service/doc/api_swagger.html732
-rw-r--r--sms-service/doc/api_swagger.yaml288
-rw-r--r--sms-service/doc/coverage.html1471
-rw-r--r--sms-service/doc/coverage.md41
4 files changed, 0 insertions, 2532 deletions
diff --git a/sms-service/doc/api_swagger.html b/sms-service/doc/api_swagger.html
deleted file mode 100644
index 7f987a3..0000000
--- a/sms-service/doc/api_swagger.html
+++ /dev/null
@@ -1,732 +0,0 @@
-<!doctype html>
-<html>
- <head>
- <title>Secret Management Service</title>
- <style type="text/css">
- body {
- font-family: Trebuchet MS, sans-serif;
- font-size: 15px;
- color: #444;
- margin-right: 24px;
-}
-
-h1 {
- font-size: 25px;
-}
-h2 {
- font-size: 20px;
-}
-h3 {
- font-size: 16px;
- font-weight: bold;
-}
-hr {
- height: 1px;
- border: 0;
- color: #ddd;
- background-color: #ddd;
-}
-
-.app-desc {
- clear: both;
- margin-left: 20px;
-}
-.param-name {
- width: 100%;
-}
-.license-info {
- margin-left: 20px;
-}
-
-.license-url {
- margin-left: 20px;
-}
-
-.model {
- margin: 0 0 0px 20px;
-}
-
-.method {
- margin-left: 20px;
-}
-
-.method-notes {
- margin: 10px 0 20px 0;
- font-size: 90%;
- color: #555;
-}
-
-pre {
- padding: 10px;
- margin-bottom: 2px;
-}
-
-.http-method {
- text-transform: uppercase;
-}
-
-pre.get {
- background-color: #0f6ab4;
-}
-
-pre.post {
- background-color: #10a54a;
-}
-
-pre.put {
- background-color: #c5862b;
-}
-
-pre.delete {
- background-color: #a41e22;
-}
-
-.huge {
- color: #fff;
-}
-
-pre.example {
- background-color: #f3f3f3;
- padding: 10px;
- border: 1px solid #ddd;
-}
-
-code {
- white-space: pre;
-}
-
-.nickname {
- font-weight: bold;
-}
-
-.method-path {
- font-size: 1.5em;
- background-color: #0f6ab4;
-}
-
-.up {
- float:right;
-}
-
-.parameter {
- width: 500px;
-}
-
-.param {
- width: 500px;
- padding: 10px 0 0 20px;
- font-weight: bold;
-}
-
-.param-desc {
- width: 700px;
- padding: 0 0 0 20px;
- color: #777;
-}
-
-.param-type {
- font-style: italic;
-}
-
-.param-enum-header {
-width: 700px;
-padding: 0 0 0 60px;
-color: #777;
-font-weight: bold;
-}
-
-.param-enum {
-width: 700px;
-padding: 0 0 0 80px;
-color: #777;
-font-style: italic;
-}
-
-.field-label {
- padding: 0;
- margin: 0;
- clear: both;
-}
-
-.field-items {
- padding: 0 0 15px 0;
- margin-bottom: 15px;
-}
-
-.return-type {
- clear: both;
- padding-bottom: 10px;
-}
-
-.param-header {
- font-weight: bold;
-}
-
-.method-tags {
- text-align: right;
-}
-
-.method-tag {
- background: none repeat scroll 0% 0% #24A600;
- border-radius: 3px;
- padding: 2px 10px;
- margin: 2px;
- color: #FFF;
- display: inline-block;
- text-decoration: none;
-}
-
- </style>
- </head>
- <body>
- <h1>Secret Management Service</h1>
- <div class="app-desc">This is a service that provides secret management facilities</div>
- <div class="app-desc">More information: <a href="https://helloreverb.com">https://helloreverb.com</a></div>
- <div class="app-desc">Contact Info: <a href="kiran.k.kamineni@intel.com">kiran.k.kamineni@intel.com</a></div>
- <div class="app-desc">Version: 1.0.0</div>
- <div class="app-desc">BasePath:/v1/sms/</div>
- <div class="license-info">Apache 2.0</div>
- <div class="license-url">http://www.apache.org/licenses/LICENSE-2.0.html</div>
- <h2>Access</h2>
- <ol>
- <li>APIKey KeyParamName:token KeyInQuery:false KeyInHeader:true</li>
- </ol>
-
- <h2><a name="__Methods">Methods</a></h2>
- [ Jump to <a href="#__Models">Models</a> ]
-
- <h3>Table of Contents </h3>
- <div class="method-summary"></div>
- <h4><a href="#Domain">Domain</a></h4>
- <ul>
- <li><a href="#domainDomainNameDelete"><code><span class="http-method">delete</span> /domain/{domainName}</code></a></li>
- <li><a href="#domainPost"><code><span class="http-method">post</span> /domain</code></a></li>
- </ul>
- <h4><a href="#Login">Login</a></h4>
- <ul>
- <li><a href="#loginPost"><code><span class="http-method">post</span> /login</code></a></li>
- </ul>
- <h4><a href="#Secret">Secret</a></h4>
- <ul>
- <li><a href="#domainDomainNameSecretGet"><code><span class="http-method">get</span> /domain/{domainName}/secret</code></a></li>
- <li><a href="#domainDomainNameSecretPost"><code><span class="http-method">post</span> /domain/{domainName}/secret</code></a></li>
- <li><a href="#domainDomainNameSecretSecretNameDelete"><code><span class="http-method">delete</span> /domain/{domainName}/secret/{secretName}</code></a></li>
- <li><a href="#domainDomainNameSecretSecretNameGet"><code><span class="http-method">get</span> /domain/{domainName}/secret/{secretName}</code></a></li>
- </ul>
- <h4><a href="#System">System</a></h4>
- <ul>
- <li><a href="#statusGet"><code><span class="http-method">get</span> /status</code></a></li>
- <li><a href="#unsealPost"><code><span class="http-method">post</span> /unseal</code></a></li>
- </ul>
-
- <h1><a name="Domain">Domain</a></h1>
- <div class="method"><a name="domainDomainNameDelete"/>
- <div class="method-path">
- <a class="up" href="#__Methods">Up</a>
- <pre class="delete"><code class="huge"><span class="http-method">delete</span> /domain/{domainName}</code></pre></div>
- <div class="method-summary">Deletes a domain by name (<span class="nickname">domainDomainNameDelete</span>)</div>
- <div class="method-notes">Deletes a domain with provided name</div>
-
- <h3 class="field-label">Path parameters</h3>
- <div class="field-items">
- <div class="param">domainName (required)</div>
-
- <div class="param-desc"><span class="param-type">Path Parameter</span> &mdash; Name of the domain </div>
- </div> <!-- field-items -->
-
-
-
-
-
-
-
- <!--Todo: process Response Object and its headers, schema, examples -->
-
-
- <h3 class="field-label">Produces</h3>
- This API call produces the following media types according to the <span class="header">Accept</span> request header;
- the media type will be conveyed by the <span class="heaader">Content-Type</span> response header.
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Responses</h3>
- <h4 class="field-label">204</h4>
- Successful Deletion
- <a href="#"></a>
- <h4 class="field-label">404</h4>
- Invalid Path or Path not found
- <a href="#"></a>
- </div> <!-- method -->
- <hr/>
- <div class="method"><a name="domainPost"/>
- <div class="method-path">
- <a class="up" href="#__Methods">Up</a>
- <pre class="post"><code class="huge"><span class="http-method">post</span> /domain</code></pre></div>
- <div class="method-summary">Add a new domain (<span class="nickname">domainPost</span>)</div>
- <div class="method-notes"></div>
-
-
- <h3 class="field-label">Consumes</h3>
- This API call consumes the following media types via the <span class="heaader">Content-Type</span> request header:
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Request body</h3>
- <div class="field-items">
- <div class="param">body <a href="#Domain">Domain</a> (required)</div>
-
- <div class="param-desc"><span class="param-type">Body Parameter</span> &mdash; </div>
-
- </div> <!-- field-items -->
-
-
-
-
- <h3 class="field-label">Return type</h3>
- <div class="return-type">
- <a href="#Domain">Domain</a>
-
- </div>
-
- <!--Todo: process Response Object and its headers, schema, examples -->
-
- <h3 class="field-label">Example data</h3>
- <div class="example-data-content-type">Content-Type: application/json</div>
- <pre class="example"><code>{
- "name" : "name",
- "uuid" : "uuid"
-}</code></pre>
-
- <h3 class="field-label">Produces</h3>
- This API call produces the following media types according to the <span class="header">Accept</span> request header;
- the media type will be conveyed by the <span class="heaader">Content-Type</span> response header.
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Responses</h3>
- <h4 class="field-label">201</h4>
- Successful Creation
- <a href="#Domain">Domain</a>
- <h4 class="field-label">400</h4>
- Invalid input
- <a href="#"></a>
- <h4 class="field-label">500</h4>
- Internal Server Error
- <a href="#"></a>
- </div> <!-- method -->
- <hr/>
- <h1><a name="Login">Login</a></h1>
- <div class="method"><a name="loginPost"/>
- <div class="method-path">
- <a class="up" href="#__Methods">Up</a>
- <pre class="post"><code class="huge"><span class="http-method">post</span> /login</code></pre></div>
- <div class="method-summary">Login with username and password (<span class="nickname">loginPost</span>)</div>
- <div class="method-notes">Operations related to logging in via username and Password</div>
-
-
- <h3 class="field-label">Consumes</h3>
- This API call consumes the following media types via the <span class="heaader">Content-Type</span> request header:
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Request body</h3>
- <div class="field-items">
- <div class="param">body <a href="#Credential">Credential</a> (required)</div>
-
- <div class="param-desc"><span class="param-type">Body Parameter</span> &mdash; </div>
-
- </div> <!-- field-items -->
-
-
-
-
- <h3 class="field-label">Return type</h3>
- <div class="return-type">
- <a href="#inline_response_200">inline_response_200</a>
-
- </div>
-
- <!--Todo: process Response Object and its headers, schema, examples -->
-
- <h3 class="field-label">Example data</h3>
- <div class="example-data-content-type">Content-Type: application/json</div>
- <pre class="example"><code>{
- "ttl" : 0,
- "token" : "token"
-}</code></pre>
-
- <h3 class="field-label">Produces</h3>
- This API call produces the following media types according to the <span class="header">Accept</span> request header;
- the media type will be conveyed by the <span class="heaader">Content-Type</span> response header.
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Responses</h3>
- <h4 class="field-label">200</h4>
- Successful Login returns a token
- <a href="#inline_response_200">inline_response_200</a>
- <h4 class="field-label">404</h4>
- Invalid Username or Password
- <a href="#"></a>
- </div> <!-- method -->
- <hr/>
- <h1><a name="Secret">Secret</a></h1>
- <div class="method"><a name="domainDomainNameSecretGet"/>
- <div class="method-path">
- <a class="up" href="#__Methods">Up</a>
- <pre class="get"><code class="huge"><span class="http-method">get</span> /domain/{domainName}/secret</code></pre></div>
- <div class="method-summary">List secret Names in this domain (<span class="nickname">domainDomainNameSecretGet</span>)</div>
- <div class="method-notes">Gets all secret names in this domain</div>
-
- <h3 class="field-label">Path parameters</h3>
- <div class="field-items">
- <div class="param">domainName (required)</div>
-
- <div class="param-desc"><span class="param-type">Path Parameter</span> &mdash; Name of the domain in which to look at </div>
- </div> <!-- field-items -->
-
-
-
-
-
-
- <h3 class="field-label">Return type</h3>
- <div class="return-type">
- <a href="#inline_response_200_2">inline_response_200_2</a>
-
- </div>
-
- <!--Todo: process Response Object and its headers, schema, examples -->
-
- <h3 class="field-label">Example data</h3>
- <div class="example-data-content-type">Content-Type: application/json</div>
- <pre class="example"><code>"{\"secretnames\":[\"secretname1\",\"secretname2\",\"secretname3\"]}"</code></pre>
-
- <h3 class="field-label">Produces</h3>
- This API call produces the following media types according to the <span class="header">Accept</span> request header;
- the media type will be conveyed by the <span class="heaader">Content-Type</span> response header.
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Responses</h3>
- <h4 class="field-label">200</h4>
- Successful operation
- <a href="#inline_response_200_2">inline_response_200_2</a>
- <h4 class="field-label">404</h4>
- Invalid Path or Path not found
- <a href="#"></a>
- </div> <!-- method -->
- <hr/>
- <div class="method"><a name="domainDomainNameSecretPost"/>
- <div class="method-path">
- <a class="up" href="#__Methods">Up</a>
- <pre class="post"><code class="huge"><span class="http-method">post</span> /domain/{domainName}/secret</code></pre></div>
- <div class="method-summary">Add a new secret (<span class="nickname">domainDomainNameSecretPost</span>)</div>
- <div class="method-notes"></div>
-
- <h3 class="field-label">Path parameters</h3>
- <div class="field-items">
- <div class="param">domainName (required)</div>
-
- <div class="param-desc"><span class="param-type">Path Parameter</span> &mdash; Name of the domain </div>
- </div> <!-- field-items -->
-
- <h3 class="field-label">Consumes</h3>
- This API call consumes the following media types via the <span class="heaader">Content-Type</span> request header:
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Request body</h3>
- <div class="field-items">
- <div class="param">body <a href="#Secret">Secret</a> (required)</div>
-
- <div class="param-desc"><span class="param-type">Body Parameter</span> &mdash; </div>
-
- </div> <!-- field-items -->
-
-
-
-
-
- <!--Todo: process Response Object and its headers, schema, examples -->
-
-
- <h3 class="field-label">Produces</h3>
- This API call produces the following media types according to the <span class="header">Accept</span> request header;
- the media type will be conveyed by the <span class="heaader">Content-Type</span> response header.
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Responses</h3>
- <h4 class="field-label">201</h4>
- Successful Creation
- <a href="#"></a>
- <h4 class="field-label">404</h4>
- Invalid Path or Path not found
- <a href="#"></a>
- </div> <!-- method -->
- <hr/>
- <div class="method"><a name="domainDomainNameSecretSecretNameDelete"/>
- <div class="method-path">
- <a class="up" href="#__Methods">Up</a>
- <pre class="delete"><code class="huge"><span class="http-method">delete</span> /domain/{domainName}/secret/{secretName}</code></pre></div>
- <div class="method-summary">Deletes a Secret (<span class="nickname">domainDomainNameSecretSecretNameDelete</span>)</div>
- <div class="method-notes"></div>
-
- <h3 class="field-label">Path parameters</h3>
- <div class="field-items">
- <div class="param">secretName (required)</div>
-
- <div class="param-desc"><span class="param-type">Path Parameter</span> &mdash; Name of Secret to Delete </div><div class="param">domainName (required)</div>
-
- <div class="param-desc"><span class="param-type">Path Parameter</span> &mdash; Path to the SecretDomain which contains the Secret </div>
- </div> <!-- field-items -->
-
-
-
-
-
-
-
- <!--Todo: process Response Object and its headers, schema, examples -->
-
-
- <h3 class="field-label">Produces</h3>
- This API call produces the following media types according to the <span class="header">Accept</span> request header;
- the media type will be conveyed by the <span class="heaader">Content-Type</span> response header.
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Responses</h3>
- <h4 class="field-label">204</h4>
- Successful Deletion
- <a href="#"></a>
- <h4 class="field-label">404</h4>
- Invalid Path or Path not found
- <a href="#"></a>
- </div> <!-- method -->
- <hr/>
- <div class="method"><a name="domainDomainNameSecretSecretNameGet"/>
- <div class="method-path">
- <a class="up" href="#__Methods">Up</a>
- <pre class="get"><code class="huge"><span class="http-method">get</span> /domain/{domainName}/secret/{secretName}</code></pre></div>
- <div class="method-summary">Find Secret by Name (<span class="nickname">domainDomainNameSecretSecretNameGet</span>)</div>
- <div class="method-notes">Returns a single secret</div>
-
- <h3 class="field-label">Path parameters</h3>
- <div class="field-items">
- <div class="param">domainName (required)</div>
-
- <div class="param-desc"><span class="param-type">Path Parameter</span> &mdash; Name of the domain in which to look at </div><div class="param">secretName (required)</div>
-
- <div class="param-desc"><span class="param-type">Path Parameter</span> &mdash; Name of the secret which is needed </div>
- </div> <!-- field-items -->
-
-
-
-
-
-
- <h3 class="field-label">Return type</h3>
- <div class="return-type">
- <a href="#Secret">Secret</a>
-
- </div>
-
- <!--Todo: process Response Object and its headers, schema, examples -->
-
- <h3 class="field-label">Example data</h3>
- <div class="example-data-content-type">Content-Type: application/json</div>
- <pre class="example"><code>{
- "values" : {
- "name" : "john",
- "Age" : 40,
- "admin" : true
- },
- "name" : "name"
-}</code></pre>
-
- <h3 class="field-label">Produces</h3>
- This API call produces the following media types according to the <span class="header">Accept</span> request header;
- the media type will be conveyed by the <span class="heaader">Content-Type</span> response header.
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Responses</h3>
- <h4 class="field-label">200</h4>
- successful operation
- <a href="#Secret">Secret</a>
- <h4 class="field-label">404</h4>
- Invalid Path or Path not found
- <a href="#"></a>
- </div> <!-- method -->
- <hr/>
- <h1><a name="System">System</a></h1>
- <div class="method"><a name="statusGet"/>
- <div class="method-path">
- <a class="up" href="#__Methods">Up</a>
- <pre class="get"><code class="huge"><span class="http-method">get</span> /status</code></pre></div>
- <div class="method-summary">Get backend status (<span class="nickname">statusGet</span>)</div>
- <div class="method-notes">Gets current backend status. This API is used only by quorum clients</div>
-
-
-
-
-
-
-
- <h3 class="field-label">Return type</h3>
- <div class="return-type">
- <a href="#inline_response_200_1">inline_response_200_1</a>
-
- </div>
-
- <!--Todo: process Response Object and its headers, schema, examples -->
-
- <h3 class="field-label">Example data</h3>
- <div class="example-data-content-type">Content-Type: application/json</div>
- <pre class="example"><code>{
- "sealstatus" : "sealstatus"
-}</code></pre>
-
- <h3 class="field-label">Produces</h3>
- This API call produces the following media types according to the <span class="header">Accept</span> request header;
- the media type will be conveyed by the <span class="heaader">Content-Type</span> response header.
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Responses</h3>
- <h4 class="field-label">200</h4>
- Successful operation
- <a href="#inline_response_200_1">inline_response_200_1</a>
- <h4 class="field-label">404</h4>
- Invalid Path or Path not found
- <a href="#"></a>
- </div> <!-- method -->
- <hr/>
- <div class="method"><a name="unsealPost"/>
- <div class="method-path">
- <a class="up" href="#__Methods">Up</a>
- <pre class="post"><code class="huge"><span class="http-method">post</span> /unseal</code></pre></div>
- <div class="method-summary">Unseal backend (<span class="nickname">unsealPost</span>)</div>
- <div class="method-notes">Sends unseal shard to unseal if backend is sealed</div>
-
-
- <h3 class="field-label">Consumes</h3>
- This API call consumes the following media types via the <span class="heaader">Content-Type</span> request header:
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Request body</h3>
- <div class="field-items">
- <div class="param">body <a href="#body">body</a> (required)</div>
-
- <div class="param-desc"><span class="param-type">Body Parameter</span> &mdash; </div>
-
- </div> <!-- field-items -->
-
-
-
-
-
- <!--Todo: process Response Object and its headers, schema, examples -->
-
-
- <h3 class="field-label">Produces</h3>
- This API call produces the following media types according to the <span class="header">Accept</span> request header;
- the media type will be conveyed by the <span class="heaader">Content-Type</span> response header.
- <ul>
- <li><code>application/json</code></li>
- </ul>
-
- <h3 class="field-label">Responses</h3>
- <h4 class="field-label">201</h4>
- Submitted unseal key
- <a href="#"></a>
- <h4 class="field-label">404</h4>
- Invalid Path or Path not found
- <a href="#"></a>
- </div> <!-- method -->
- <hr/>
-
- <h2><a name="__Models">Models</a></h2>
- [ Jump to <a href="#__Methods">Methods</a> ]
-
- <h3>Table of Contents</h3>
- <ol>
- <li><a href="#Credential"><code>Credential</code> - </a></li>
- <li><a href="#Domain"><code>Domain</code> - </a></li>
- <li><a href="#Secret"><code>Secret</code> - </a></li>
- <li><a href="#body"><code>body</code> - </a></li>
- <li><a href="#inline_response_200"><code>inline_response_200</code> - </a></li>
- <li><a href="#inline_response_200_1"><code>inline_response_200_1</code> - </a></li>
- <li><a href="#inline_response_200_2"><code>inline_response_200_2</code> - </a></li>
- </ol>
-
- <div class="model">
- <h3><a name="Credential"><code>Credential</code> - </a> <a class="up" href="#__Models">Up</a></h3>
- <div class='model-description'></div>
- <div class="field-items">
- <div class="param">username (optional)</div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> </div>
-<div class="param">password (optional)</div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> </div>
- </div> <!-- field-items -->
- </div>
- <div class="model">
- <h3><a name="Domain"><code>Domain</code> - </a> <a class="up" href="#__Models">Up</a></h3>
- <div class='model-description'></div>
- <div class="field-items">
- <div class="param">uuid (optional)</div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> Optional value provided by user. If user does not provide, server will auto generate </div>
-<div class="param">name (optional)</div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> Name of the secret domain under which all secrets will be stored </div>
- </div> <!-- field-items -->
- </div>
- <div class="model">
- <h3><a name="Secret"><code>Secret</code> - </a> <a class="up" href="#__Models">Up</a></h3>
- <div class='model-description'></div>
- <div class="field-items">
- <div class="param">name (optional)</div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> Name of the secret </div>
-<div class="param">values (optional)</div><div class="param-desc"><span class="param-type"><a href="#object">map[String, Object]</a></span> Map of key value pairs that constitute the secret </div>
- </div> <!-- field-items -->
- </div>
- <div class="model">
- <h3><a name="body"><code>body</code> - </a> <a class="up" href="#__Models">Up</a></h3>
-
- <div class="field-items">
- <div class="param">unsealshard (optional)</div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> Unseal shard that will be used along with other shards to unseal backend </div>
- </div> <!-- field-items -->
- </div>
- <div class="model">
- <h3><a name="inline_response_200"><code>inline_response_200</code> - </a> <a class="up" href="#__Models">Up</a></h3>
-
- <div class="field-items">
- <div class="param">token (optional)</div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> </div>
-<div class="param">ttl (optional)</div><div class="param-desc"><span class="param-type"><a href="#integer">Integer</a></span> ttl of returned token in seconds </div>
- </div> <!-- field-items -->
- </div>
- <div class="model">
- <h3><a name="inline_response_200_1"><code>inline_response_200_1</code> - </a> <a class="up" href="#__Models">Up</a></h3>
-
- <div class="field-items">
- <div class="param">sealstatus (optional)</div><div class="param-desc"><span class="param-type"><a href="#string">String</a></span> seal status of backend </div>
- </div> <!-- field-items -->
- </div>
- <div class="model">
- <h3><a name="inline_response_200_2"><code>inline_response_200_2</code> - </a> <a class="up" href="#__Models">Up</a></h3>
-
- <div class="field-items">
- <div class="param">secretnames (optional)</div><div class="param-desc"><span class="param-type"><a href="#string">array[String]</a></span> Array of strings referencing the secret names </div>
- </div> <!-- field-items -->
- </div>
- </body>
-</html>
diff --git a/sms-service/doc/api_swagger.yaml b/sms-service/doc/api_swagger.yaml
deleted file mode 100644
index 61cd091..0000000
--- a/sms-service/doc/api_swagger.yaml
+++ /dev/null
@@ -1,288 +0,0 @@
-swagger: '2.0'
-info:
- description: This is a service that provides secret management facilities
- version: 1.0.0
- title: Secret Management Service
- contact:
- email: kiran.k.kamineni@intel.com
- license:
- name: Apache 2.0
- url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
-host: 'aaf.onap.org:10443'
-basePath: /v1/sms/
-tags:
- - name: system
- description: Operations related to quorum client which are not useful to clients
- - name: login
- description: Operations related to username password based authentication
- - name: domain
- description: Operations related to Secret Domains
- - name: secret
- description: Operations related to Secrets
-schemes:
- - https
-paths:
- /login:
- post:
- tags:
- - login
- summary: Login with username and password
- description: Operations related to logging in via username and Password
- consumes:
- - application/json
- produces:
- - application/json
- parameters:
- - name: body
- in: body
- required: true
- schema:
- $ref: '#/definitions/Credential'
- responses:
- '200':
- description: Successful Login returns a token
- schema:
- type: object
- properties:
- token:
- type: string
- ttl:
- type: integer
- description: ttl of returned token in seconds
- '404':
- description: Invalid Username or Password
- /status:
- get:
- tags:
- - system
- description: Gets current backend status. This API is used only by quorum clients
- summary: Get backend status
- produces:
- - application/json
- responses:
- '200':
- description: Successful operation
- schema:
- type: object
- properties:
- sealstatus:
- type: string
- description: seal status of backend
- '404':
- description: Invalid Path or Path not found
- /unseal:
- post:
- tags:
- - system
- description: Sends unseal shard to unseal if backend is sealed
- summary: Unseal backend
- consumes:
- - application/json
- produces:
- - application/json
- parameters:
- - in: body
- name: body
- required: true
- schema:
- type: object
- properties:
- unsealshard:
- type: string
- description: >-
- Unseal shard that will be used along with other shards to
- unseal backend
- responses:
- '201':
- description: Submitted unseal key
- '404':
- description: Invalid Path or Path not found
- /domain:
- post:
- tags:
- - domain
- summary: Add a new domain
- description: ''
- consumes:
- - application/json
- produces:
- - application/json
- parameters:
- - in: body
- name: body
- required: true
- schema:
- $ref: '#/definitions/Domain'
- responses:
- '201':
- description: Successful Creation
- schema:
- $ref: '#/definitions/Domain'
- '400':
- description: Invalid input
- '500':
- description: Internal Server Error
- '/domain/{domainName}':
- delete:
- tags:
- - domain
- description: Deletes a domain with provided name
- summary: Deletes a domain by name
- produces:
- - application/json
- parameters:
- - name: domainName
- in: path
- description: Name of the domain
- required: true
- type: string
- responses:
- '204':
- description: Successful Deletion
- '404':
- description: Invalid Path or Path not found
- '/domain/{domainName}/secret':
- post:
- tags:
- - secret
- summary: Add a new secret
- description: ''
- consumes:
- - application/json
- produces:
- - application/json
- parameters:
- - name: domainName
- in: path
- description: Name of the domain
- required: true
- type: string
- - name: body
- in: body
- required: true
- schema:
- $ref: '#/definitions/Secret'
- responses:
- '201':
- description: Successful Creation
- '404':
- description: Invalid Path or Path not found
- get:
- tags:
- - secret
- description: Gets all secret names in this domain
- summary: List secret Names in this domain
- produces:
- - application/json
- parameters:
- - name: domainName
- in: path
- description: Name of the domain in which to look at
- required: true
- type: string
- responses:
- '200':
- description: Successful operation
- schema:
- type: object
- properties:
- secretnames:
- type: array
- items:
- type: string
- description: Array of strings referencing the secret names
- example:
- secretnames: ["secretname1", "secretname2", "secretname3"]
- '404':
- description: Invalid Path or Path not found
- '/domain/{domainName}/secret/{secretName}':
- get:
- tags:
- - secret
- summary: Find Secret by Name
- description: Returns a single secret
- produces:
- - application/json
- parameters:
- - name: domainName
- in: path
- description: Name of the domain in which to look at
- required: true
- type: string
- - name: secretName
- in: path
- description: Name of the secret which is needed
- required: true
- type: string
- responses:
- '200':
- description: successful operation
- schema:
- $ref: '#/definitions/Secret'
- '404':
- description: Invalid Path or Path not found
- delete:
- tags:
- - secret
- summary: Deletes a Secret
- description: ''
- produces:
- - application/json
- parameters:
- - name: secretName
- in: path
- description: Name of Secret to Delete
- required: true
- type: string
- - name: domainName
- in: path
- required: true
- description: Path to the SecretDomain which contains the Secret
- type: string
- responses:
- '204':
- description: Successful Deletion
- '404':
- description: Invalid Path or Path not found
-securityDefinitions:
- token:
- type: apiKey
- name: token
- in: header
-definitions:
- Credential:
- type: object
- properties:
- username:
- type: string
- password:
- type: string
- Domain:
- type: object
- properties:
- uuid:
- type: string
- description: >-
- Optional value provided by user. If user does not provide, server will
- auto generate
- name:
- type: string
- description: Name of the secret domain under which all secrets will be stored
- Secret:
- type: object
- properties:
- name:
- type: string
- description: Name of the secret
- values:
- description: Map of key value pairs that constitute the secret
- type: object
- additionalProperties:
- type: object
- example:
- name: john
- Age: 40
- admin: true
-externalDocs:
- description: Find out more about Swagger
- url: 'http://swagger.io'
diff --git a/sms-service/doc/coverage.html b/sms-service/doc/coverage.html
deleted file mode 100644
index 39ee191..0000000
--- a/sms-service/doc/coverage.html
+++ /dev/null
@@ -1,1471 +0,0 @@
-
-<!DOCTYPE html>
-<html>
- <head>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
- <style>
- body {
- background: black;
- color: rgb(80, 80, 80);
- }
- body, pre, #legend span {
- font-family: Menlo, monospace;
- font-weight: bold;
- }
- #topbar {
- background: black;
- position: fixed;
- top: 0; left: 0; right: 0;
- height: 42px;
- border-bottom: 1px solid rgb(80, 80, 80);
- }
- #content {
- margin-top: 50px;
- }
- #nav, #legend {
- float: left;
- margin-left: 10px;
- }
- #legend {
- margin-top: 12px;
- }
- #nav {
- margin-top: 10px;
- }
- #legend span {
- margin: 0 5px;
- }
- .cov0 { color: rgb(192, 0, 0) }
-.cov1 { color: rgb(128, 128, 128) }
-.cov2 { color: rgb(116, 140, 131) }
-.cov3 { color: rgb(104, 152, 134) }
-.cov4 { color: rgb(92, 164, 137) }
-.cov5 { color: rgb(80, 176, 140) }
-.cov6 { color: rgb(68, 188, 143) }
-.cov7 { color: rgb(56, 200, 146) }
-.cov8 { color: rgb(44, 212, 149) }
-.cov9 { color: rgb(32, 224, 152) }
-.cov10 { color: rgb(20, 236, 155) }
-
- </style>
- </head>
- <body>
- <div id="topbar">
- <div id="nav">
- <select id="files">
-
- <option value="file0">sms/auth/auth.go (76.1%)</option>
-
- <option value="file1">sms/backend/backend.go (80.0%)</option>
-
- <option value="file2">sms/backend/vault.go (72.5%)</option>
-
- <option value="file3">sms/config/config.go (78.6%)</option>
-
- <option value="file4">sms/handler/handler.go (63.0%)</option>
-
- <option value="file5">sms/log/logger.go (65.6%)</option>
-
- <option value="file6">sms/sms.go (77.8%)</option>
-
- </select>
- </div>
- <div id="legend">
- <span>not tracked</span>
-
- <span class="cov0">no coverage</span>
- <span class="cov1">low coverage</span>
- <span class="cov2">*</span>
- <span class="cov3">*</span>
- <span class="cov4">*</span>
- <span class="cov5">*</span>
- <span class="cov6">*</span>
- <span class="cov7">*</span>
- <span class="cov8">*</span>
- <span class="cov9">*</span>
- <span class="cov10">high coverage</span>
-
- </div>
- </div>
- <div id="content">
-
- <pre class="file" id="file0" style="display: none">/*
- * Copyright 2018 Intel Corporation, Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package auth
-
-import (
- "bytes"
- "crypto"
- "crypto/tls"
- "crypto/x509"
- "encoding/base64"
- "golang.org/x/crypto/openpgp"
- "golang.org/x/crypto/openpgp/packet"
- "io/ioutil"
-
- smslogger "sms/log"
-)
-
-// GetTLSConfig initializes a tlsConfig using the CA's certificate
-// This config is then used to enable the server for mutual TLS
-func GetTLSConfig(caCertFile string) (*tls.Config, error) <span class="cov10" title="3">{
-
- // Initialize tlsConfig once
- caCert, err := ioutil.ReadFile(caCertFile)
-
- if err != nil </span><span class="cov1" title="1">{
- return nil, err
- }</span>
-
- <span class="cov6" title="2">caCertPool := x509.NewCertPool()
- caCertPool.AppendCertsFromPEM(caCert)
-
- tlsConfig := &amp;tls.Config{
- // Change to RequireAndVerify once we have mandatory certs
- ClientAuth: tls.VerifyClientCertIfGiven,
- ClientCAs: caCertPool,
- MinVersion: tls.VersionTLS12,
- }
- tlsConfig.BuildNameToCertificate()
- return tlsConfig, nil</span>
-}
-
-// GeneratePGPKeyPair produces a PGP key pair and returns
-// two things:
-// A base64 encoded form of the public part of the entity
-// A base64 encoded form of the private key
-func GeneratePGPKeyPair() (string, string, error) <span class="cov10" title="3">{
-
- var entity *openpgp.Entity
- config := &amp;packet.Config{
- DefaultHash: crypto.SHA256,
- }
-
- entity, err := openpgp.NewEntity("aaf.sms.init", "PGP Key for unsealing", "", config)
- if smslogger.CheckError(err, "Create Entity") != nil </span><span class="cov0" title="0">{
- return "", "", err
- }</span>
-
- // Sign the identity in the entity
- <span class="cov10" title="3">for _, id := range entity.Identities </span><span class="cov10" title="3">{
- err = id.SelfSignature.SignUserId(id.UserId.Id, entity.PrimaryKey, entity.PrivateKey, nil)
- if smslogger.CheckError(err, "Sign Entity") != nil </span><span class="cov0" title="0">{
- return "", "", err
- }</span>
- }
-
- // Sign the subkey in the entity
- <span class="cov10" title="3">for _, subkey := range entity.Subkeys </span><span class="cov10" title="3">{
- err := subkey.Sig.SignKey(subkey.PublicKey, entity.PrivateKey, nil)
- if smslogger.CheckError(err, "Sign Subkey") != nil </span><span class="cov0" title="0">{
- return "", "", err
- }</span>
- }
-
- <span class="cov10" title="3">buffer := new(bytes.Buffer)
- entity.Serialize(buffer)
- pbkey := base64.StdEncoding.EncodeToString(buffer.Bytes())
-
- buffer.Reset()
- entity.SerializePrivate(buffer, nil)
- prkey := base64.StdEncoding.EncodeToString(buffer.Bytes())
-
- return pbkey, prkey, nil</span>
-}
-
-// EncryptPGPString takes data and a public key and encrypts using that
-// public key
-func EncryptPGPString(data string, pbKey string) (string, error) <span class="cov6" title="2">{
-
- pbKeyBytes, err := base64.StdEncoding.DecodeString(pbKey)
- if smslogger.CheckError(err, "Decoding Base64 Public Key") != nil </span><span class="cov0" title="0">{
- return "", err
- }</span>
-
- <span class="cov6" title="2">dataBytes := []byte(data)
-
- pbEntity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(pbKeyBytes)))
- if smslogger.CheckError(err, "Reading entity from PGP key") != nil </span><span class="cov0" title="0">{
- return "", err
- }</span>
-
- // encrypt string
- <span class="cov6" title="2">buf := new(bytes.Buffer)
- out, err := openpgp.Encrypt(buf, []*openpgp.Entity{pbEntity}, nil, nil, nil)
- if smslogger.CheckError(err, "Creating Encryption Pipe") != nil </span><span class="cov0" title="0">{
- return "", err
- }</span>
-
- <span class="cov6" title="2">_, err = out.Write(dataBytes)
- if smslogger.CheckError(err, "Writing to Encryption Pipe") != nil </span><span class="cov0" title="0">{
- return "", err
- }</span>
-
- <span class="cov6" title="2">err = out.Close()
- if smslogger.CheckError(err, "Closing Encryption Pipe") != nil </span><span class="cov0" title="0">{
- return "", err
- }</span>
-
- <span class="cov6" title="2">crp := base64.StdEncoding.EncodeToString(buf.Bytes())
- return crp, nil</span>
-}
-
-// DecryptPGPString decrypts a PGP encoded input string and returns
-// a base64 representation of the decoded string
-func DecryptPGPString(data string, prKey string) (string, error) <span class="cov1" title="1">{
-
- // Convert private key to bytes from base64
- prKeyBytes, err := base64.StdEncoding.DecodeString(prKey)
- if smslogger.CheckError(err, "Decoding Base64 Private Key") != nil </span><span class="cov0" title="0">{
- return "", err
- }</span>
-
- <span class="cov1" title="1">dataBytes, err := base64.StdEncoding.DecodeString(data)
- if smslogger.CheckError(err, "Decoding base64 data") != nil </span><span class="cov0" title="0">{
- return "", err
- }</span>
-
- <span class="cov1" title="1">prEntity, err := openpgp.ReadEntity(packet.NewReader(bytes.NewBuffer(prKeyBytes)))
- if smslogger.CheckError(err, "Read Entity") != nil </span><span class="cov0" title="0">{
- return "", err
- }</span>
-
- <span class="cov1" title="1">prEntityList := &amp;openpgp.EntityList{prEntity}
- message, err := openpgp.ReadMessage(bytes.NewBuffer(dataBytes), prEntityList, nil, nil)
- if smslogger.CheckError(err, "Decrypting Message") != nil </span><span class="cov0" title="0">{
- return "", err
- }</span>
-
- <span class="cov1" title="1">var retBuf bytes.Buffer
- retBuf.ReadFrom(message.UnverifiedBody)
-
- return retBuf.String(), nil</span>
-}
-
-// ReadFromFile reads a file and loads the PGP key into
-// a string
-func ReadFromFile(fileName string) (string, error) <span class="cov6" title="2">{
-
- data, err := ioutil.ReadFile(fileName)
- if smslogger.CheckError(err, "Read from file") != nil </span><span class="cov0" title="0">{
- return "", err
- }</span>
- <span class="cov6" title="2">return string(data), nil</span>
-}
-
-// WriteToFile writes a PGP key into a file.
-// It will truncate the file if it exists
-func WriteToFile(data string, fileName string) error <span class="cov0" title="0">{
-
- err := ioutil.WriteFile(fileName, []byte(data), 0600)
- if smslogger.CheckError(err, "Write to file") != nil </span><span class="cov0" title="0">{
- return err
- }</span>
- <span class="cov0" title="0">return nil</span>
-}
-</pre>
-
- <pre class="file" id="file1" style="display: none">/*
- * Copyright 2018 Intel Corporation, Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package backend
-
-import (
- smsconfig "sms/config"
- smslogger "sms/log"
-)
-
-// SecretDomain is where Secrets are stored.
-// A single domain can have any number of secrets
-type SecretDomain struct {
- UUID string `json:"uuid"`
- Name string `json:"name"`
-}
-
-// Secret is the struct that defines the structure of a secret
-// It consists of a name and map containing key value pairs
-type Secret struct {
- Name string `json:"name"`
- Values map[string]interface{} `json:"values"`
-}
-
-// SecretBackend interface that will be implemented for various secret backends
-type SecretBackend interface {
- Init() error
- GetStatus() (bool, error)
- Unseal(shard string) error
- RegisterQuorum(pgpkey string) (string, error)
-
- GetSecret(dom string, sec string) (Secret, error)
- ListSecret(dom string) ([]string, error)
-
- CreateSecretDomain(name string) (SecretDomain, error)
- CreateSecret(dom string, sec Secret) error
-
- DeleteSecretDomain(name string) error
- DeleteSecret(dom string, name string) error
-}
-
-// InitSecretBackend returns an interface implementation
-func InitSecretBackend() (SecretBackend, error) <span class="cov8" title="1">{
- backendImpl := &amp;Vault{
- vaultAddress: smsconfig.SMSConfig.BackendAddress,
- vaultToken: smsconfig.SMSConfig.VaultToken,
- }
-
- err := backendImpl.Init()
- if smslogger.CheckError(err, "InitSecretBackend") != nil </span><span class="cov0" title="0">{
- return nil, err
- }</span>
-
- <span class="cov8" title="1">return backendImpl, nil</span>
-}
-
-// LoginBackend Interface that will be implemented for various login backends
-type LoginBackend interface {
-}
-</pre>
-
- <pre class="file" id="file2" style="display: none">/*
- * Copyright 2018 Intel Corporation, Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package backend
-
-import (
- uuid "github.com/hashicorp/go-uuid"
- vaultapi "github.com/hashicorp/vault/api"
- smsauth "sms/auth"
- smslogger "sms/log"
-
- "errors"
- "fmt"
- "strings"
- "sync"
- "time"
-)
-
-// Vault is the main Struct used in Backend to initialize the struct
-type Vault struct {
- sync.Mutex
- initRoleDone bool
- policyName string
- roleID string
- secretID string
- vaultAddress string
- vaultClient *vaultapi.Client
- vaultMountPrefix string
- internalDomain string
- internalDomainMounted bool
- vaultTempTokenTTL time.Time
- vaultToken string
- shards []string
- prkey string
-}
-
-// initVaultClient will create the initial
-// Vault strcuture and populate it with the
-// right values and it will also create
-// a vault client
-func (v *Vault) initVaultClient() error <span class="cov6" title="11">{
-
- vaultCFG := vaultapi.DefaultConfig()
- vaultCFG.Address = v.vaultAddress
- client, err := vaultapi.NewClient(vaultCFG)
- if smslogger.CheckError(err, "Create new vault client") != nil </span><span class="cov0" title="0">{
- return err
- }</span>
-
- <span class="cov6" title="11">v.initRoleDone = false
- v.policyName = "smsvaultpolicy"
- v.vaultClient = client
- v.vaultMountPrefix = "sms"
- v.internalDomain = "smsinternaldomain"
- v.internalDomainMounted = false
- v.prkey = ""
- return nil</span>
-}
-
-// Init will initialize the vault connection
-// It will also initialize vault if it is not
-// already initialized.
-// The initial policy will also be created
-func (v *Vault) Init() error <span class="cov1" title="1">{
-
- v.initVaultClient()
- // Initialize vault if it is not already
- // Returns immediately if it is initialized
- v.initializeVault()
-
- err := v.initRole()
- if smslogger.CheckError(err, "InitRole First Attempt") != nil </span><span class="cov0" title="0">{
- smslogger.WriteInfo("InitRole will try again later")
- }</span>
-
- <span class="cov1" title="1">return nil</span>
-}
-
-// GetStatus returns the current seal status of vault
-func (v *Vault) GetStatus() (bool, error) <span class="cov3" title="3">{
-
- sys := v.vaultClient.Sys()
- sealStatus, err := sys.SealStatus()
- if smslogger.CheckError(err, "Getting Status") != nil </span><span class="cov0" title="0">{
- return false, errors.New("Error getting status")
- }</span>
-
- <span class="cov3" title="3">return sealStatus.Sealed, nil</span>
-}
-
-// RegisterQuorum registers the PGP public key for a quorum client
-// We will return a shard to the client that is registering
-func (v *Vault) RegisterQuorum(pgpkey string) (string, error) <span class="cov0" title="0">{
-
- v.Lock()
- defer v.Unlock()
-
- if v.shards == nil </span><span class="cov0" title="0">{
- smslogger.WriteError("Invalid operation in RegisterQuorum")
- return "", errors.New("Invalid operation")
- }</span>
- // Pop the slice
- <span class="cov0" title="0">var sh string
- sh, v.shards = v.shards[len(v.shards)-1], v.shards[:len(v.shards)-1]
- if len(v.shards) == 0 </span><span class="cov0" title="0">{
- v.shards = nil
- }</span>
-
- // Decrypt with SMS pgp Key
- <span class="cov0" title="0">sh, _ = smsauth.DecryptPGPString(sh, v.prkey)
- // Encrypt with Quorum client pgp key
- sh, _ = smsauth.EncryptPGPString(sh, pgpkey)
-
- return sh, nil</span>
-}
-
-// Unseal is a passthrough API that allows any
-// unseal or initialization processes for the backend
-func (v *Vault) Unseal(shard string) error <span class="cov0" title="0">{
-
- sys := v.vaultClient.Sys()
- _, err := sys.Unseal(shard)
- if smslogger.CheckError(err, "Unseal Operation") != nil </span><span class="cov0" title="0">{
- return errors.New("Unable to execute unseal operation with specified shard")
- }</span>
-
- <span class="cov0" title="0">return nil</span>
-}
-
-// GetSecret returns a secret mounted on a particular domain name
-// The secret itself is referenced via its name which translates to
-// a mount path in vault
-func (v *Vault) GetSecret(dom string, name string) (Secret, error) <span class="cov5" title="7">{
-
- err := v.checkToken()
- if smslogger.CheckError(err, "Tocken Check") != nil </span><span class="cov0" title="0">{
- return Secret{}, errors.New("Token check failed")
- }</span>
-
- <span class="cov5" title="7">dom = v.vaultMountPrefix + "/" + dom
-
- sec, err := v.vaultClient.Logical().Read(dom + "/" + name)
- if smslogger.CheckError(err, "Read Secret") != nil </span><span class="cov0" title="0">{
- return Secret{}, errors.New("Unable to read Secret at provided path")
- }</span>
-
- // sec and err are nil in the case where a path does not exist
- <span class="cov5" title="7">if sec == nil </span><span class="cov0" title="0">{
- smslogger.WriteWarn("Vault read was empty. Invalid Path")
- return Secret{}, errors.New("Secret not found at the provided path")
- }</span>
-
- <span class="cov5" title="7">return Secret{Name: name, Values: sec.Data}, nil</span>
-}
-
-// ListSecret returns a list of secret names on a particular domain
-// The values of the secret are not returned
-func (v *Vault) ListSecret(dom string) ([]string, error) <span class="cov3" title="3">{
-
- err := v.checkToken()
- if smslogger.CheckError(err, "Token Check") != nil </span><span class="cov0" title="0">{
- return nil, errors.New("Token check failed")
- }</span>
-
- <span class="cov3" title="3">dom = v.vaultMountPrefix + "/" + dom
-
- sec, err := v.vaultClient.Logical().List(dom)
- if smslogger.CheckError(err, "Read Secret") != nil </span><span class="cov0" title="0">{
- return nil, errors.New("Unable to read Secret at provided path")
- }</span>
-
- // sec and err are nil in the case where a path does not exist
- <span class="cov3" title="3">if sec == nil </span><span class="cov0" title="0">{
- smslogger.WriteWarn("Vaultclient returned empty data")
- return nil, errors.New("Secret not found at the provided path")
- }</span>
-
- <span class="cov3" title="3">val, ok := sec.Data["keys"].([]interface{})
- if !ok </span><span class="cov0" title="0">{
- smslogger.WriteError("Secret not found at the provided path")
- return nil, errors.New("Secret not found at the provided path")
- }</span>
-
- <span class="cov3" title="3">retval := make([]string, len(val))
- for i, v := range val </span><span class="cov5" title="7">{
- retval[i] = fmt.Sprint(v)
- }</span>
-
- <span class="cov3" title="3">return retval, nil</span>
-}
-
-// Mounts the internal Domain if its not already mounted
-func (v *Vault) mountInternalDomain(name string) error <span class="cov5" title="8">{
-
- if v.internalDomainMounted </span><span class="cov1" title="1">{
- return nil
- }</span>
-
- <span class="cov5" title="7">name = strings.TrimSpace(name)
- mountPath := v.vaultMountPrefix + "/" + name
- mountInput := &amp;vaultapi.MountInput{
- Type: "kv",
- Description: "Mount point for domain: " + name,
- Local: false,
- SealWrap: false,
- Config: vaultapi.MountConfigInput{},
- }
-
- err := v.vaultClient.Sys().Mount(mountPath, mountInput)
- if smslogger.CheckError(err, "Mount internal Domain") != nil </span><span class="cov1" title="1">{
- if strings.Contains(err.Error(), "existing mount") </span><span class="cov1" title="1">{
- // It is already mounted
- v.internalDomainMounted = true
- return nil
- }</span>
- // Ran into some other error mounting it.
- <span class="cov0" title="0">return errors.New("Unable to mount internal Domain")</span>
- }
-
- <span class="cov5" title="6">v.internalDomainMounted = true
- return nil</span>
-}
-
-// Stores the UUID created for secretdomain in vault
-// under v.vaultMountPrefix / smsinternal domain
-func (v *Vault) storeUUID(uuid string, name string) error <span class="cov5" title="8">{
-
- // Check if token is still valid
- err := v.checkToken()
- if smslogger.CheckError(err, "Token Check") != nil </span><span class="cov0" title="0">{
- return errors.New("Token Check failed")
- }</span>
-
- <span class="cov5" title="8">err = v.mountInternalDomain(v.internalDomain)
- if smslogger.CheckError(err, "Mount Internal Domain") != nil </span><span class="cov0" title="0">{
- return err
- }</span>
-
- <span class="cov5" title="8">secret := Secret{
- Name: name,
- Values: map[string]interface{}{
- "uuid": uuid,
- },
- }
-
- err = v.CreateSecret(v.internalDomain, secret)
- if smslogger.CheckError(err, "Write UUID to domain") != nil </span><span class="cov0" title="0">{
- return err
- }</span>
-
- <span class="cov5" title="8">return nil</span>
-}
-
-// CreateSecretDomain mounts the kv backend on a path with the given name
-func (v *Vault) CreateSecretDomain(name string) (SecretDomain, error) <span class="cov5" title="8">{
-
- // Check if token is still valid
- err := v.checkToken()
- if smslogger.CheckError(err, "Token Check") != nil </span><span class="cov0" title="0">{
- return SecretDomain{}, errors.New("Token Check failed")
- }</span>
-
- <span class="cov5" title="8">name = strings.TrimSpace(name)
- mountPath := v.vaultMountPrefix + "/" + name
- mountInput := &amp;vaultapi.MountInput{
- Type: "kv",
- Description: "Mount point for domain: " + name,
- Local: false,
- SealWrap: false,
- Config: vaultapi.MountConfigInput{},
- }
-
- err = v.vaultClient.Sys().Mount(mountPath, mountInput)
- if smslogger.CheckError(err, "Create Domain") != nil </span><span class="cov0" title="0">{
- return SecretDomain{}, errors.New("Unable to create Secret Domain")
- }</span>
-
- <span class="cov5" title="8">uuid, _ := uuid.GenerateUUID()
- err = v.storeUUID(uuid, name)
- if smslogger.CheckError(err, "Store UUID") != nil </span><span class="cov0" title="0">{
- // Mount was successful at this point.
- // Rollback the mount operation since we could not
- // store the UUID for the mount.
- v.vaultClient.Sys().Unmount(mountPath)
- return SecretDomain{}, errors.New("Unable to store Secret Domain UUID. Retry")
- }</span>
-
- <span class="cov5" title="8">return SecretDomain{uuid, name}, nil</span>
-}
-
-// CreateSecret creates a secret mounted on a particular domain name
-// The secret itself is mounted on a path specified by name
-func (v *Vault) CreateSecret(dom string, sec Secret) error <span class="cov7" title="18">{
-
- err := v.checkToken()
- if smslogger.CheckError(err, "Token Check") != nil </span><span class="cov0" title="0">{
- return errors.New("Token check failed")
- }</span>
-
- <span class="cov7" title="18">dom = v.vaultMountPrefix + "/" + dom
-
- // Vault return is empty on successful write
- // TODO: Check if values is not empty
- _, err = v.vaultClient.Logical().Write(dom+"/"+sec.Name, sec.Values)
- if smslogger.CheckError(err, "Create Secret") != nil </span><span class="cov0" title="0">{
- return errors.New("Unable to create Secret at provided path")
- }</span>
-
- <span class="cov7" title="18">return nil</span>
-}
-
-// DeleteSecretDomain deletes a secret domain which translates to
-// an unmount operation on the given path in Vault
-func (v *Vault) DeleteSecretDomain(name string) error <span class="cov3" title="3">{
-
- err := v.checkToken()
- if smslogger.CheckError(err, "Token Check") != nil </span><span class="cov0" title="0">{
- return errors.New("Token Check Failed")
- }</span>
-
- <span class="cov3" title="3">name = strings.TrimSpace(name)
- mountPath := v.vaultMountPrefix + "/" + name
-
- err = v.vaultClient.Sys().Unmount(mountPath)
- if smslogger.CheckError(err, "Delete Domain") != nil </span><span class="cov0" title="0">{
- return errors.New("Unable to delete domain specified")
- }</span>
-
- <span class="cov3" title="3">return nil</span>
-}
-
-// DeleteSecret deletes a secret mounted on the path provided
-func (v *Vault) DeleteSecret(dom string, name string) error <span class="cov5" title="7">{
-
- err := v.checkToken()
- if smslogger.CheckError(err, "Token Check") != nil </span><span class="cov0" title="0">{
- return errors.New("Token check failed")
- }</span>
-
- <span class="cov5" title="7">dom = v.vaultMountPrefix + "/" + dom
-
- // Vault return is empty on successful delete
- _, err = v.vaultClient.Logical().Delete(dom + "/" + name)
- if smslogger.CheckError(err, "Delete Secret") != nil </span><span class="cov0" title="0">{
- return errors.New("Unable to delete Secret at provided path")
- }</span>
-
- <span class="cov5" title="7">return nil</span>
-}
-
-// initRole is called only once during SMS bring up
-// It initially creates a role and secret id associated with
-// that role. Later restarts will use the existing role-id
-// and secret-id stored on disk
-func (v *Vault) initRole() error <span class="cov10" title="56">{
-
- if v.initRoleDone </span><span class="cov9" title="48">{
- return nil
- }</span>
-
- // Use the root token once here
- <span class="cov5" title="8">v.vaultClient.SetToken(v.vaultToken)
- defer v.vaultClient.ClearToken()
-
- // Check if roleID and secretID has already been created
- rID, error := smsauth.ReadFromFile("auth/role")
- if error != nil </span><span class="cov5" title="7">{
- smslogger.WriteWarn("Unable to find RoleID. Generating...")
- }</span><span class="cov1" title="1"> else {
- sID, error := smsauth.ReadFromFile("auth/secret")
- if error != nil </span><span class="cov0" title="0">{
- smslogger.WriteWarn("Unable to find secretID. Generating...")
- }</span><span class="cov1" title="1"> else {
- v.roleID = rID
- v.secretID = sID
- v.initRoleDone = true
- return nil
- }</span>
- }
-
- <span class="cov5" title="7">rules := `path "sms/*" { capabilities = ["create", "read", "update", "delete", "list"] }
- path "sys/mounts/sms*" { capabilities = ["update","delete","create"] }`
- err := v.vaultClient.Sys().PutPolicy(v.policyName, rules)
- if smslogger.CheckError(err, "Creating Policy") != nil </span><span class="cov0" title="0">{
- return errors.New("Unable to create policy for approle creation")
- }</span>
-
- //Check if applrole is mounted
- <span class="cov5" title="7">authMounts, err := v.vaultClient.Sys().ListAuth()
- if smslogger.CheckError(err, "Mount Auth Backend") != nil </span><span class="cov0" title="0">{
- return errors.New("Unable to get mounted auth backends")
- }</span>
-
- <span class="cov5" title="7">approleMounted := false
- for k, v := range authMounts </span><span class="cov5" title="7">{
- if v.Type == "approle" &amp;&amp; k == "approle/" </span><span class="cov0" title="0">{
- approleMounted = true
- break</span>
- }
- }
-
- // Mount approle in case its not already mounted
- <span class="cov5" title="7">if !approleMounted </span><span class="cov5" title="7">{
- v.vaultClient.Sys().EnableAuth("approle", "approle", "")
- }</span>
-
- <span class="cov5" title="7">rName := v.vaultMountPrefix + "-role"
- data := map[string]interface{}{
- "token_ttl": "60m",
- "policies": [2]string{"default", v.policyName},
- }
-
- // Create a role-id
- v.vaultClient.Logical().Write("auth/approle/role/"+rName, data)
- sec, err := v.vaultClient.Logical().Read("auth/approle/role/" + rName + "/role-id")
- if smslogger.CheckError(err, "Create RoleID") != nil </span><span class="cov0" title="0">{
- return errors.New("Unable to create role ID for approle")
- }</span>
- <span class="cov5" title="7">v.roleID = sec.Data["role_id"].(string)
-
- // Create a secret-id to go with it
- sec, err = v.vaultClient.Logical().Write("auth/approle/role/"+rName+"/secret-id",
- map[string]interface{}{})
- if smslogger.CheckError(err, "Create SecretID") != nil </span><span class="cov0" title="0">{
- return errors.New("Unable to create secret ID for role")
- }</span>
-
- <span class="cov5" title="7">v.secretID = sec.Data["secret_id"].(string)
- v.initRoleDone = true
- /*
- * Revoke the Root token.
- * If a new Root Token is needed, it will need to be created
- * using the unseal shards.
- */
- err = v.vaultClient.Auth().Token().RevokeSelf(v.vaultToken)
- if smslogger.CheckError(err, "Revoke Root Token") != nil </span><span class="cov0" title="0">{
- smslogger.WriteWarn("Unable to Revoke Token")
- }</span><span class="cov5" title="7"> else {
- // Revoked successfully and clear it
- v.vaultToken = ""
- }</span>
-
- // Store the role-id and secret-id
- // We will need this if SMS restarts
- <span class="cov5" title="7">smsauth.WriteToFile(v.roleID, "auth/role")
- smsauth.WriteToFile(v.secretID, "auth/secret")
-
- return nil</span>
-}
-
-// Function checkToken() gets called multiple times to create
-// temporary tokens
-func (v *Vault) checkToken() error <span class="cov9" title="54">{
-
- v.Lock()
- defer v.Unlock()
-
- // Init Role if it is not yet done
- // Role needs to be created before token can be created
- err := v.initRole()
- if err != nil </span><span class="cov0" title="0">{
- smslogger.WriteError(err.Error())
- return errors.New("Unable to initRole in checkToken")
- }</span>
-
- // Return immediately if token still has life
- <span class="cov9" title="54">if v.vaultClient.Token() != "" &amp;&amp;
- time.Since(v.vaultTempTokenTTL) &lt; time.Minute*50 </span><span class="cov9" title="47">{
- return nil
- }</span>
-
- // Create a temporary token using our roleID and secretID
- <span class="cov5" title="7">out, err := v.vaultClient.Logical().Write("auth/approle/login",
- map[string]interface{}{"role_id": v.roleID, "secret_id": v.secretID})
- if smslogger.CheckError(err, "Create Temp Token") != nil </span><span class="cov0" title="0">{
- return errors.New("Unable to create Temporary Token for Role")
- }</span>
-
- <span class="cov5" title="7">tok, err := out.TokenID()
-
- v.vaultTempTokenTTL = time.Now()
- v.vaultClient.SetToken(tok)
- return nil</span>
-}
-
-// vaultInit() is used to initialize the vault in cases where it is not
-// initialized. This happens once during intial bring up.
-func (v *Vault) initializeVault() error <span class="cov2" title="2">{
-
- // Check for vault init status and don't exit till it is initialized
- for </span><span class="cov2" title="2">{
- init, err := v.vaultClient.Sys().InitStatus()
- if smslogger.CheckError(err, "Get Vault Init Status") != nil </span><span class="cov0" title="0">{
- smslogger.WriteInfo("Trying again in 10s...")
- time.Sleep(time.Second * 10)
- continue</span>
- }
- // Did not get any error
- <span class="cov2" title="2">if init == true </span><span class="cov1" title="1">{
- smslogger.WriteInfo("Vault is already Initialized")
- return nil
- }</span>
-
- // init status is false
- // break out of loop and finish initialization
- <span class="cov1" title="1">smslogger.WriteInfo("Vault is not initialized. Initializing...")
- break</span>
- }
-
- // Hardcoded this to 3. We should make this configurable
- // in the future
- <span class="cov1" title="1">initReq := &amp;vaultapi.InitRequest{
- SecretShares: 3,
- SecretThreshold: 3,
- }
-
- pbkey, prkey, err := smsauth.GeneratePGPKeyPair()
-
- if smslogger.CheckError(err, "Generating PGP Keys") != nil </span><span class="cov0" title="0">{
- smslogger.WriteError("Error Generating PGP Keys. Vault Init will not use encryption!")
- }</span><span class="cov1" title="1"> else {
- initReq.PGPKeys = []string{pbkey, pbkey, pbkey}
- initReq.RootTokenPGPKey = pbkey
- }</span>
-
- <span class="cov1" title="1">resp, err := v.vaultClient.Sys().Init(initReq)
- if smslogger.CheckError(err, "Initialize Vault") != nil </span><span class="cov0" title="0">{
- return errors.New("FATAL: Unable to initialize Vault")
- }</span>
-
- <span class="cov1" title="1">if resp != nil </span><span class="cov1" title="1">{
- v.prkey = prkey
- v.shards = resp.KeysB64
- v.vaultToken, _ = smsauth.DecryptPGPString(resp.RootToken, prkey)
- return nil
- }</span>
-
- <span class="cov0" title="0">return errors.New("FATAL: Init response was empty")</span>
-}
-</pre>
-
- <pre class="file" id="file3" style="display: none">/*
- * Copyright 2018 Intel Corporation, Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package config
-
-import (
- "encoding/json"
- "os"
- smslogger "sms/log"
-)
-
-// SMSConfiguration loads up all the values that are used to configure
-// backend implementations
-// TODO: Review these and see if they can be created/discovered dynamically
-type SMSConfiguration struct {
- CAFile string `json:"cafile"`
- ServerCert string `json:"servercert"`
- ServerKey string `json:"serverkey"`
-
- BackendAddress string `json:"smsdbaddress"`
- VaultToken string `json:"vaulttoken"`
- DisableTLS bool `json:"disable_tls"`
- BackendAddressEnvVariable string `json:"smsdburlenv"`
-}
-
-// SMSConfig is the structure that stores the configuration
-var SMSConfig *SMSConfiguration
-
-// ReadConfigFile reads the specified smsConfig file to setup some env variables
-func ReadConfigFile(file string) (*SMSConfiguration, error) <span class="cov10" title="3">{
- if SMSConfig == nil </span><span class="cov10" title="3">{
- f, err := os.Open(file)
- if err != nil </span><span class="cov1" title="1">{
- return nil, err
- }</span>
- <span class="cov6" title="2">defer f.Close()
-
- // Default behaviour is to enable TLS
- SMSConfig = &amp;SMSConfiguration{DisableTLS: false}
- decoder := json.NewDecoder(f)
- err = decoder.Decode(SMSConfig)
- if err != nil </span><span class="cov0" title="0">{
- return nil, err
- }</span>
-
- <span class="cov6" title="2">if SMSConfig.BackendAddress == "" &amp;&amp; SMSConfig.BackendAddressEnvVariable != "" </span><span class="cov0" title="0">{
- // Get the value from ENV variable
- smslogger.WriteInfo("Using Environment Variable: " + SMSConfig.BackendAddressEnvVariable)
- SMSConfig.BackendAddress = os.Getenv(SMSConfig.BackendAddressEnvVariable)
- }</span>
- }
-
- <span class="cov6" title="2">return SMSConfig, nil</span>
-}
-</pre>
-
- <pre class="file" id="file4" style="display: none">/*
- * Copyright 2018 Intel Corporation, Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package handler
-
-import (
- "encoding/json"
- "github.com/gorilla/mux"
- "net/http"
-
- smsbackend "sms/backend"
- smslogger "sms/log"
-)
-
-// handler stores two interface implementations that implement
-// the backend functionality
-type handler struct {
- secretBackend smsbackend.SecretBackend
- loginBackend smsbackend.LoginBackend
-}
-
-// createSecretDomainHandler creates a secret domain with a name provided
-func (h handler) createSecretDomainHandler(w http.ResponseWriter, r *http.Request) <span class="cov6" title="3">{
- var d smsbackend.SecretDomain
-
- err := json.NewDecoder(r.Body).Decode(&amp;d)
- if smslogger.CheckError(err, "CreateSecretDomainHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }</span>
-
- <span class="cov6" title="3">dom, err := h.secretBackend.CreateSecretDomain(d.Name)
- if smslogger.CheckError(err, "CreateSecretDomainHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-
- <span class="cov6" title="3">w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(http.StatusCreated)
- err = json.NewEncoder(w).Encode(dom)
- if smslogger.CheckError(err, "CreateSecretDomainHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-}
-
-// deleteSecretDomainHandler deletes a secret domain with the name provided
-func (h handler) deleteSecretDomainHandler(w http.ResponseWriter, r *http.Request) <span class="cov6" title="3">{
- vars := mux.Vars(r)
- domName := vars["domName"]
-
- err := h.secretBackend.DeleteSecretDomain(domName)
- if smslogger.CheckError(err, "DeleteSecretDomainHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-
- <span class="cov6" title="3">w.WriteHeader(http.StatusNoContent)</span>
-}
-
-// createSecretHandler handles creation of secrets on a given domain name
-func (h handler) createSecretHandler(w http.ResponseWriter, r *http.Request) <span class="cov10" title="7">{
- // Get domain name from URL
- vars := mux.Vars(r)
- domName := vars["domName"]
-
- // Get secrets to be stored from body
- var b smsbackend.Secret
- err := json.NewDecoder(r.Body).Decode(&amp;b)
- if smslogger.CheckError(err, "CreateSecretHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }</span>
-
- <span class="cov10" title="7">err = h.secretBackend.CreateSecret(domName, b)
- if smslogger.CheckError(err, "CreateSecretHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-
- <span class="cov10" title="7">w.WriteHeader(http.StatusCreated)</span>
-}
-
-// getSecretHandler handles reading a secret by given domain name and secret name
-func (h handler) getSecretHandler(w http.ResponseWriter, r *http.Request) <span class="cov10" title="7">{
- vars := mux.Vars(r)
- domName := vars["domName"]
- secName := vars["secretName"]
-
- sec, err := h.secretBackend.GetSecret(domName, secName)
- if smslogger.CheckError(err, "GetSecretHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-
- <span class="cov10" title="7">w.Header().Set("Content-Type", "application/json")
- err = json.NewEncoder(w).Encode(sec)
- if smslogger.CheckError(err, "GetSecretHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-}
-
-// listSecretHandler handles listing all secrets under a particular domain name
-func (h handler) listSecretHandler(w http.ResponseWriter, r *http.Request) <span class="cov6" title="3">{
- vars := mux.Vars(r)
- domName := vars["domName"]
-
- secList, err := h.secretBackend.ListSecret(domName)
- if smslogger.CheckError(err, "ListSecretHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-
- // Creating an anonymous struct to store the returned list of data
- <span class="cov6" title="3">var retStruct = struct {
- SecretNames []string `json:"secretnames"`
- }{
- secList,
- }
-
- w.Header().Set("Content-Type", "application/json")
- err = json.NewEncoder(w).Encode(retStruct)
- if smslogger.CheckError(err, "ListSecretHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-}
-
-// deleteSecretHandler handles deleting a secret by given domain name and secret name
-func (h handler) deleteSecretHandler(w http.ResponseWriter, r *http.Request) <span class="cov10" title="7">{
- vars := mux.Vars(r)
- domName := vars["domName"]
- secName := vars["secretName"]
-
- err := h.secretBackend.DeleteSecret(domName, secName)
- if smslogger.CheckError(err, "DeleteSecretHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-
- <span class="cov10" title="7">w.WriteHeader(http.StatusNoContent)</span>
-}
-
-// statusHandler returns information related to SMS and SMS backend services
-func (h handler) statusHandler(w http.ResponseWriter, r *http.Request) <span class="cov7" title="4">{
- s, err := h.secretBackend.GetStatus()
- if smslogger.CheckError(err, "StatusHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-
- <span class="cov7" title="4">status := struct {
- Seal bool `json:"sealstatus"`
- }{
- s,
- }
-
- w.Header().Set("Content-Type", "application/json")
- err = json.NewEncoder(w).Encode(status)
- if smslogger.CheckError(err, "StatusHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-}
-
-// loginHandler handles login via password and username
-func (h handler) loginHandler(w http.ResponseWriter, r *http.Request) {<span class="cov0" title="0">
-
-}</span>
-
-// unsealHandler is a pass through that sends requests from quorum client
-// to the backend.
-func (h handler) unsealHandler(w http.ResponseWriter, r *http.Request) <span class="cov0" title="0">{
- // Get shards to be used for unseal
- type unsealStruct struct {
- UnsealShard string `json:"unsealshard"`
- }
-
- var inp unsealStruct
- decoder := json.NewDecoder(r.Body)
- decoder.DisallowUnknownFields()
- err := decoder.Decode(&amp;inp)
- if smslogger.CheckError(err, "UnsealHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, "Bad input JSON", http.StatusBadRequest)
- return
- }</span>
-
- <span class="cov0" title="0">err = h.secretBackend.Unseal(inp.UnsealShard)
- if smslogger.CheckError(err, "UnsealHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-}
-
-// registerHandler allows the quorum clients to register with SMS
-// with their PGP public keys that are then used by sms for backend
-// initialization
-func (h handler) registerHandler(w http.ResponseWriter, r *http.Request) <span class="cov1" title="1">{
- // Get shards to be used for unseal
- type registerStruct struct {
- PGPKey string `json:"pgpkey"`
- QuorumID string `json:"quorumid"`
- }
-
- var inp registerStruct
- decoder := json.NewDecoder(r.Body)
- decoder.DisallowUnknownFields()
- err := decoder.Decode(&amp;inp)
- if smslogger.CheckError(err, "RegisterHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, "Bad input JSON", http.StatusBadRequest)
- return
- }</span>
-
- <span class="cov1" title="1">sh, err := h.secretBackend.RegisterQuorum(inp.PGPKey)
- if smslogger.CheckError(err, "RegisterHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-
- // Creating a struct for return data
- <span class="cov1" title="1">shStruct := struct {
- Shard string `json:"shard"`
- }{
- sh,
- }
-
- w.Header().Set("Content-Type", "application/json")
- err = json.NewEncoder(w).Encode(shStruct)
- if smslogger.CheckError(err, "RegisterHandler") != nil </span><span class="cov0" title="0">{
- http.Error(w, err.Error(), http.StatusInternalServerError)
- return
- }</span>
-}
-
-// CreateRouter returns an http.Handler for the registered URLs
-// Takes an interface implementation as input
-func CreateRouter(b smsbackend.SecretBackend) http.Handler <span class="cov4" title="2">{
- h := handler{secretBackend: b}
-
- // Create a new mux to handle URL endpoints
- router := mux.NewRouter()
-
- router.HandleFunc("/v1/sms/login", h.loginHandler).Methods("POST")
-
- // Initialization APIs which will be used by quorum client
- // to unseal and to provide root token to sms service
- router.HandleFunc("/v1/sms/quorum/status", h.statusHandler).Methods("GET")
- router.HandleFunc("/v1/sms/quorum/unseal", h.unsealHandler).Methods("POST")
- router.HandleFunc("/v1/sms/quorum/register", h.registerHandler).Methods("POST")
-
- router.HandleFunc("/v1/sms/domain", h.createSecretDomainHandler).Methods("POST")
- router.HandleFunc("/v1/sms/domain/{domName}", h.deleteSecretDomainHandler).Methods("DELETE")
-
- router.HandleFunc("/v1/sms/domain/{domName}/secret", h.createSecretHandler).Methods("POST")
- router.HandleFunc("/v1/sms/domain/{domName}/secret", h.listSecretHandler).Methods("GET")
- router.HandleFunc("/v1/sms/domain/{domName}/secret/{secretName}", h.getSecretHandler).Methods("GET")
- router.HandleFunc("/v1/sms/domain/{domName}/secret/{secretName}", h.deleteSecretHandler).Methods("DELETE")
-
- return router
-}</span>
-</pre>
-
- <pre class="file" id="file5" style="display: none">/*
- * Copyright 2018 Intel Corporation, Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package log
-
-import (
- "fmt"
- "log"
- "os"
-)
-
-var errL, warnL, infoL *log.Logger
-var stdErr, stdWarn, stdInfo *log.Logger
-
-// Init will be called by sms.go before any other packages use it
-func Init(filePath string) <span class="cov1" title="1">{
-
- stdErr = log.New(os.Stderr, "ERROR: ", log.Lshortfile|log.LstdFlags)
- stdWarn = log.New(os.Stdout, "WARNING: ", log.Lshortfile|log.LstdFlags)
- stdInfo = log.New(os.Stdout, "INFO: ", log.Lshortfile|log.LstdFlags)
-
- if filePath == "" </span><span class="cov0" title="0">{
- // We will just to std streams
- return
- }</span>
-
- <span class="cov1" title="1">f, err := os.Create(filePath)
- if err != nil </span><span class="cov0" title="0">{
- stdErr.Println("Unable to create log file: " + err.Error())
- return
- }</span>
-
- <span class="cov1" title="1">errL = log.New(f, "ERROR: ", log.Lshortfile|log.LstdFlags)
- warnL = log.New(f, "WARNING: ", log.Lshortfile|log.LstdFlags)
- infoL = log.New(f, "INFO: ", log.Lshortfile|log.LstdFlags)</span>
-}
-
-// WriteError writes output to the writer we have
-// defined during its creation with ERROR prefix
-func WriteError(msg string) <span class="cov0" title="0">{
- if errL != nil </span><span class="cov0" title="0">{
- errL.Output(2, fmt.Sprintln(msg))
- }</span>
- <span class="cov0" title="0">if stdErr != nil </span><span class="cov0" title="0">{
- stdErr.Output(2, fmt.Sprintln(msg))
- }</span>
-}
-
-// WriteWarn writes output to the writer we have
-// defined during its creation with WARNING prefix
-func WriteWarn(msg string) <span class="cov0" title="0">{
- if warnL != nil </span><span class="cov0" title="0">{
- warnL.Output(2, fmt.Sprintln(msg))
- }</span>
- <span class="cov0" title="0">if stdWarn != nil </span><span class="cov0" title="0">{
- stdWarn.Output(2, fmt.Sprintln(msg))
- }</span>
-}
-
-// WriteInfo writes output to the writer we have
-// defined during its creation with INFO prefix
-func WriteInfo(msg string) <span class="cov1" title="1">{
- if infoL != nil </span><span class="cov1" title="1">{
- infoL.Output(2, fmt.Sprintln(msg))
- }</span>
- <span class="cov1" title="1">if stdInfo != nil </span><span class="cov1" title="1">{
- stdInfo.Output(2, fmt.Sprintln(msg))
- }</span>
-}
-
-//CheckError is a helper function to reduce
-//repitition of error checkign blocks of code
-func CheckError(err error, topic string) error <span class="cov10" title="116">{
- if err != nil </span><span class="cov1" title="1">{
- msg := topic + ": " + err.Error()
- if errL != nil </span><span class="cov1" title="1">{
- errL.Output(2, fmt.Sprintln(msg))
- }</span>
- <span class="cov1" title="1">if stdErr != nil </span><span class="cov1" title="1">{
- stdErr.Output(2, fmt.Sprintln(msg))
- }</span>
- <span class="cov1" title="1">return err</span>
- }
- <span class="cov9" title="115">return nil</span>
-}
-</pre>
-
- <pre class="file" id="file6" style="display: none">/*
- * Copyright 2018 Intel Corporation, Inc
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package main
-
-import (
- "context"
- "log"
- "net/http"
- "os"
- "os/signal"
-
- smsauth "sms/auth"
- smsbackend "sms/backend"
- smsconfig "sms/config"
- smshandler "sms/handler"
- smslogger "sms/log"
-)
-
-func main() <span class="cov8" title="1">{
- // Initialize logger
- smslogger.Init("sms.log")
-
- // Read Configuration File
- smsConf, err := smsconfig.ReadConfigFile("smsconfig.json")
- if err != nil </span><span class="cov0" title="0">{
- log.Fatal(err)
- }</span>
-
- <span class="cov8" title="1">backendImpl, err := smsbackend.InitSecretBackend()
- if err != nil </span><span class="cov0" title="0">{
- log.Fatal(err)
- }</span>
-
- <span class="cov8" title="1">httpRouter := smshandler.CreateRouter(backendImpl)
-
- httpServer := &amp;http.Server{
- Handler: httpRouter,
- Addr: ":10443",
- }
-
- // Listener for SIGINT so that it returns cleanly
- connectionsClose := make(chan struct{})
- go func() </span><span class="cov8" title="1">{
- c := make(chan os.Signal, 1)
- signal.Notify(c, os.Interrupt)
- &lt;-c
- httpServer.Shutdown(context.Background())
- close(connectionsClose)
- }</span>()
-
- // Start in TLS mode by default
- <span class="cov8" title="1">if smsConf.DisableTLS == true </span><span class="cov0" title="0">{
- smslogger.WriteWarn("TLS is Disabled")
- err = httpServer.ListenAndServe()
- }</span><span class="cov8" title="1"> else {
- // TODO: Use CA certificate from AAF
- tlsConfig, err := smsauth.GetTLSConfig(smsConf.CAFile)
- if err != nil </span><span class="cov0" title="0">{
- log.Fatal(err)
- }</span>
-
- <span class="cov8" title="1">httpServer.TLSConfig = tlsConfig
- err = httpServer.ListenAndServeTLS(smsConf.ServerCert, smsConf.ServerKey)</span>
- }
-
- <span class="cov8" title="1">if err != nil &amp;&amp; err != http.ErrServerClosed </span><span class="cov0" title="0">{
- log.Fatal(err)
- }</span>
-
- <span class="cov8" title="1">&lt;-connectionsClose</span>
-}
-</pre>
-
- </div>
- </body>
- <script>
- (function() {
- var files = document.getElementById('files');
- var visible;
- files.addEventListener('change', onChange, false);
- function select(part) {
- if (visible)
- visible.style.display = 'none';
- visible = document.getElementById(part);
- if (!visible)
- return;
- files.value = part;
- visible.style.display = 'block';
- location.hash = part;
- }
- function onChange() {
- select(files.value);
- window.scrollTo(0, 0);
- }
- if (location.hash != "") {
- select(location.hash.substr(1));
- }
- if (!visible) {
- select("file0");
- }
- })();
- </script>
-</html>
diff --git a/sms-service/doc/coverage.md b/sms-service/doc/coverage.md
deleted file mode 100644
index 6168342..0000000
--- a/sms-service/doc/coverage.md
+++ /dev/null
@@ -1,41 +0,0 @@
-## Code Coverage Reports for Golang Applications ##
-
-This document covers how to generate HTML Code Coverage Reports for
-Golang Applications.
-
-#### Generate a test executable which calls your main()
-
-```sh
-$ go test -c -covermode=count -coverpkg ./...
-```
-
-#### Run the generated application to produce a new coverage report
-
-```sh
-$ ./sms.test -test.run "^TestMain$" -test.coverprofile=coverage.cov
-```
-
-#### Run your unit tests to produce their coverage report
-
-```sh
-$ go test -test.covermode=count -test.coverprofile=unit.out ./...
-```
-
-#### Merge the two coverage Reports
-
-```sh
-$ go get github.com/wadey/gocovmerge
-$ gocovmerge unit.out coverage.cov > all.out
-```
-
-#### Generate HTML Report
-
-```sh
-$ go tool cover -html all.out -o coverage.html
-```
-
-#### Generate Function Report
-
-```sh
-$ go tool cover -func all.out
-``` \ No newline at end of file