Skip to content

Commit

Permalink
TRITON-2053 imgapi could have better support for self-signed certs (#27)
Browse files Browse the repository at this point in the history
Reviewed by: Trent Mick <trentm@gmail.com>
Reviewed by: Todd Whiteman <todd.whiteman@joyent.com>
  • Loading branch information
jlevon committed Jan 28, 2020
1 parent f189bed commit f0352ad
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 27 deletions.
4 changes: 4 additions & 0 deletions CHANGES.md
@@ -1,5 +1,9 @@
# IMGAPI changelog

## 4.9.0

- TRITON-2053 standalone imgapi could be easier to test with

## 4.8.0

- TRITON-2052 sdc-imgadm import should import from any channel by default
Expand Down
3 changes: 2 additions & 1 deletion bin/imgapi-standalone-gen-setup-config
Expand Up @@ -7,7 +7,7 @@
*/

/*
* Copyright (c) 2017, Joyent, Inc.
* Copyright 2020 Joyent, Inc.
*/

/*
Expand Down Expand Up @@ -50,6 +50,7 @@ var setupConfigVars = [
'channels',
'serverName',
'mantaUrl',
'mantaInsecure',
'mantaUser',
'mantaBaseDir',

Expand Down
4 changes: 1 addition & 3 deletions boot/standalone/setup.sh
Expand Up @@ -6,7 +6,7 @@
#

#
# Copyright 2017 Joyent, Inc.
# Copyright 2020 Joyent, Inc.
#

#
Expand Down Expand Up @@ -145,9 +145,7 @@ EMOTD

# SMF services
/usr/sbin/svccfg import /opt/smartdc/imgapi/smf/manifests/imgapi.xml
/usr/sbin/svccfg delete pkgsrc/haproxy # avoid 'haproxy' FMRI collison
/usr/sbin/svccfg import /opt/smartdc/imgapi/smf/manifests/haproxy-standalone.xml
/usr/sbin/svccfg delete pkgsrc/stud # avoid 'stud' FMRI collison
/usr/sbin/svccfg import /opt/smartdc/imgapi/smf/manifests/stud-standalone.xml

# Note completion
Expand Down
34 changes: 22 additions & 12 deletions docs/operator-guide.md
Expand Up @@ -28,9 +28,8 @@ There are two main types of IMGAPI:

# Image

Both types of IMGAPI instances use "imgapi" images built from sdc-imgapi.git and
mountain-gorilla.git on Joyent's internal CI build system and released to
[Joyent's Updates Image repository](https://updates.joyent.com).
Both types of IMGAPI instances use "imgapi" images built from sdc-imgapi.git,
released to [Joyent's Updates Image repository](https://updates.joyent.com).


# DC-Mode Setup
Expand Down Expand Up @@ -243,7 +242,7 @@ This isn't the only place that authkeys can be added. See the
[Authentication](#authentication) section below for full details.


## Standalone Setup Step 6: set CNS service tag
## Standalone Setup Step 7: set CNS service tag

This step is optional.

Expand Down Expand Up @@ -271,6 +270,15 @@ Then, even if your instance is recycled and replaced, DNS will still work.
And when imgapi supports multiple instances (for HA), DNS will map to all your
instances using the "myimages" cns tag.

## Standalone Setup Step 8: configure downstream imgapi

If you have not completed step 5, the instance will be using a self-signed
certificate. In this case, for testing purposes you may wish to configure
another imgapi instance such that it will allow importing from the standalone,
for example:

$ service=$(sdc-sapi /services?name=imgapi | json -H 0.uuid)
$ sapiadm update $service metadata.IMGAPI_ALLOW_INSECURE=true

# Update

Expand Down Expand Up @@ -452,6 +460,7 @@ For example: if providing `manta`, one must provide the whole `manta` object.
| channels | Array | - | Set this make this IMGAPI server support [channels](#channels). It must be an array of channel definition objects of the form `{"name": "<name>", "description": "<desc>"[, "default": true]}`. |
| placeholderImageLifespanDays | Number | 7 | The number of days after which a "placeholder" image (one with state 'failed' or 'creating') is purged from the database. |
| allowLocalCreateImageFromVm | Boolean | false | Whether to allow CreateImageFromVm using local storage (i.e. if no manta storage is configured). This should only be enabled for testing. For SDC installations of IMGAPI `"IMGAPI_ALLOW_LOCAL_CREATE_IMAGE_FROM_VM": true` can be set on the metadata for the 'imgapi' SAPI service to enable this. |
| allowInsecure | Boolean | false | Whether to allow insecure connection to another IMGAPI instance when importing from it. This should only be enabled for testing. For SDC installations of IMGAPI `"IMGAPI_ALLOW_INSECURE": true` can be set on the metadata for the 'imgapi' SAPI service to enable this. |
| minImageCreationPlatform | Array | see defaults.json | The minimum platform version, `["<sdc version>", "<platform build timestamp>"]`, on which the proto VM for image creation must reside. This is about the minimum platform with sufficient `imgadm` tooling. This is used as an early failure guard for [CreateImageFromVm](#CreateImageFromVm). |
| authType | String | signature | One of 'none' or 'signature' ([HTTP Signature auth](https://github.com/joyent/node-http-signature)). |
| authKeys | Object | - | Optional. A mapping of username to an array of ssh public keys. Only used for HTTP signature auth (`config.authType === "signature"`). |
Expand Down Expand Up @@ -521,14 +530,15 @@ number of keys can be provided on instance metadata for this initial rendering.
These are called "setup config vars". At time of writing they are (see
`setupConfigVars` in imgapi-standalone-gen-setup-config):

| Key | Corresponds to this key from the "Configuration" table |
| ------------ | ------------------------------------------------------ |
| mode | mode |
| serverName | serverName |
| mantaUrl | manta.url |
| mantaUser | manta.user |
| mantaBaseDir | manta.baseDir |
| channels | channels; This may also by the special value `standard`, which will be substituted by the "standard" channels (a set of channels used by updates.joyent.com). |
| Key | Corresponds to this key from the "Configuration" table |
| ------------- | ------------------------------------------------------ |
| mode | mode |
| serverName | serverName |
| mantaUrl | manta.url |
| mantaUser | manta.user |
| mantaBaseDir | manta.baseDir |
| mantaInsecure | manta.insecure |
| channels | channels; This may also by the special value `standard`, which will be substituted by the "standard" channels (a set of channels used by updates.joyent.com). |

## x-DC Image Copying

Expand Down
1 change: 1 addition & 0 deletions etc/standalone/imgapi.config.json.handlebars
Expand Up @@ -8,6 +8,7 @@
"user": "{{{mantaUser}}}",
"key": "{{{mantaKey}}}",
"keyId": "{{{mantaKeyId}}}",
{{#if mantaInsecure}}"insecure": {{{mantaInsecure}}},{{/if}}
"baseDir": "{{{mantaBaseDir}}}"
},
{{/if}}
Expand Down
5 changes: 5 additions & 0 deletions lib/images.js
Expand Up @@ -886,6 +886,11 @@ function createImportImageJob(req, uuid, source, skipOwnerCheck, log, cb) {
// tell the job to import them first.
opts.origins = origins;
}

if (app.config.hasOwnProperty('allowInsecure')) {
opts.allowInsecure = app.config['allowInsecure'];
}

wfapi.createImportRemoteImageJob(opts, function (err2, juuid) {
if (err2) {
return next(err2);
Expand Down
6 changes: 5 additions & 1 deletion lib/utils.js
Expand Up @@ -5,7 +5,7 @@
*/

/*
* Copyright (c) 2015, Joyent, Inc.
* Copyright 2020 Joyent, Inc.
*/

/*
Expand Down Expand Up @@ -428,6 +428,10 @@ function commonHttpClientOpts(clientOpts, req) {
}
}

if (app.config.hasOwnProperty('allowInsecure')) {
clientOpts.rejectUnauthorized = !app.config['allowInsecure'];
}

return clientOpts;
}

Expand Down
3 changes: 2 additions & 1 deletion lib/wfapi.js
Expand Up @@ -5,7 +5,7 @@
*/

/*
* Copyright (c) 2014, Joyent, Inc.
* Copyright 2020 Joyent, Inc.
*/

/*
Expand Down Expand Up @@ -219,6 +219,7 @@ Wfapi.prototype.createImportRemoteImageJob = function (options, cb) {
req_id: options.req.getId(),
source: options.source,
skip_owner_check: options.skipOwnerCheck,
allowInsecure: options.allowInsecure,
task: 'import-remote-image',
target: format('/import-remote-%s', options.uuid)
};
Expand Down
61 changes: 53 additions & 8 deletions lib/workflows/import-remote-image.js
Expand Up @@ -5,7 +5,7 @@
*/

/*
* Copyright 2017 Joyent, Inc.
* Copyright 2020 Joyent, Inc.
*/

/*
Expand All @@ -21,10 +21,17 @@ var imgapiUrl;
var VERSION = '7.0.7';



function importImage(job, cb) {
var uuid = job.params.image_uuid;
var imgapi = new sdcClients.IMGAPI({url: imgapiUrl});
var insecure = false;

if (job.params.hasOwnProperty('allowInsecure')) {
insecure = job.params['allowInsecure'];
}

var imgapi = new sdcClients.IMGAPI({ url: imgapiUrl,
rejectUnauthorized: !insecure});

var opts = {
skipOwnerCheck: job.params.skip_owner_check,
source: job.params.source
Expand All @@ -43,7 +50,14 @@ function originImportImages(job, cb) {
return cb(null, 'No origins (skipping import of origins)');
}

var imgapi = new sdcClients.IMGAPI({url: imgapiUrl});
var insecure = false;

if (job.params.hasOwnProperty('allowInsecure')) {
insecure = job.params['allowInsecure'];
}

var imgapi = new sdcClients.IMGAPI({ url: imgapiUrl,
rejectUnauthorized: !insecure});

async.mapSeries(job.params.origins, importRemoteImage, afterImports);

Expand Down Expand Up @@ -102,7 +116,15 @@ function originImportImages(job, cb) {

function addImageFile(job, cb) {
var uuid = job.params.image_uuid;
var imgapi = new sdcClients.IMGAPI({url: imgapiUrl});
var insecure = false;

if (job.params.hasOwnProperty('allowInsecure')) {
insecure = job.params['allowInsecure'];
}

var imgapi = new sdcClients.IMGAPI({ url: imgapiUrl,
rejectUnauthorized: !insecure});

var opts = {
uuid: uuid,
source: job.params.source
Expand All @@ -119,7 +141,15 @@ function addImageFile(job, cb) {

function activateImage(job, cb) {
var uuid = job.params.image_uuid;
var imgapi = new sdcClients.IMGAPI({url: imgapiUrl});
var insecure = false;

if (job.params.hasOwnProperty('allowInsecure')) {
insecure = job.params['allowInsecure'];
}

var imgapi = new sdcClients.IMGAPI({ url: imgapiUrl,
rejectUnauthorized: !insecure});

imgapi.activateImage(uuid, function (err) {
if (err) {
job.log.info(err, 'failed to activate image %s', uuid);
Expand All @@ -132,7 +162,15 @@ function activateImage(job, cb) {

function deleteImage(job, cb) {
var uuid = job.params.image_uuid;
var imgapi = new sdcClients.IMGAPI({url: imgapiUrl});
var insecure = false;

if (job.params.hasOwnProperty('allowInsecure')) {
insecure = job.params['allowInsecure'];
}

var imgapi = new sdcClients.IMGAPI({ url: imgapiUrl,
rejectUnauthorized: !insecure});

imgapi.deleteImage(uuid, function (err) {
if (!err) {
cb(null, 'Image ' + uuid + ' deleted');
Expand All @@ -150,7 +188,14 @@ function originDeleteImages(job, cb) {
if (!job.params.origins) {
return cb(null, 'No origin images to delete');
}
var imgapi = new sdcClients.IMGAPI({url: imgapiUrl});
var insecure = false;

if (job.params.hasOwnProperty('allowInsecure')) {
insecure = job.params['allowInsecure'];
}

var imgapi = new sdcClients.IMGAPI({ url: imgapiUrl,
rejectUnauthorized: !insecure});

var originsToDelete = job.params.origins.slice().reverse();
async.mapSeries(originsToDelete, deleteOriginImage, afterDelete);
Expand Down
2 changes: 1 addition & 1 deletion package.json
@@ -1,7 +1,7 @@
{
"name": "imgapi",
"description": "Image API to manage images for Triton Data Center",
"version": "4.8.0",
"version": "4.9.0",
"author": "Joyent (joyent.com)",
"private": true,
"dependencies": {
Expand Down
3 changes: 3 additions & 0 deletions sapi_manifests/imgapi/template
Expand Up @@ -12,6 +12,9 @@
{{#IMGAPI_ALLOW_LOCAL_CREATE_IMAGE_FROM_VM}}
"allowLocalCreateImageFromVm": {{{IMGAPI_ALLOW_LOCAL_CREATE_IMAGE_FROM_VM}}},
{{/IMGAPI_ALLOW_LOCAL_CREATE_IMAGE_FROM_VM}}
{{#IMGAPI_ALLOW_INSECURE}}
"allowInsecure": {{{IMGAPI_ALLOW_INSECURE}}},
{{/IMGAPI_ALLOW_INSECURE}}
{{#experimental_fluentd_host}}
"fluentd_host": "{{{experimental_fluentd_host}}}",
{{/experimental_fluentd_host}}
Expand Down

0 comments on commit f0352ad

Please sign in to comment.