diff options
author | Kiran Kamineni <kiran.k.kamineni@intel.com> | 2018-05-04 16:50:39 -0700 |
---|---|---|
committer | Girish Havaldar <hg0071052@techmahindra.com> | 2018-05-15 17:21:53 +0000 |
commit | ac134cb099afa6be09fbc5cdad5db0bcf7aee08a (patch) | |
tree | cbcdf280db9285edfe8c6e62e094c6c4c6db302e /sms-service/doc | |
parent | d4b81c05a255a847bbf7f08caebe032492ad2ca5 (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/doc')
-rw-r--r-- | sms-service/doc/api_swagger.html | 732 | ||||
-rw-r--r-- | sms-service/doc/api_swagger.yaml | 288 | ||||
-rw-r--r-- | sms-service/doc/coverage.html | 1471 | ||||
-rw-r--r-- | sms-service/doc/coverage.md | 41 |
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> — 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> — </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> — </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> — 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> — 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> — </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> — Name of Secret to Delete </div><div class="param">domainName (required)</div> - - <div class="param-desc"><span class="param-type">Path Parameter</span> — 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> — 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> — 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> — </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 := &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 := &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 := &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 := &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 := &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 := &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" && 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() != "" && - time.Since(v.vaultTempTokenTTL) < 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 := &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 = &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 == "" && 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(&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(&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(&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(&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 := &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) - <-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 && err != http.ErrServerClosed </span><span class="cov0" title="0">{ - log.Fatal(err) - }</span> - - <span class="cov8" title="1"><-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 |