Skip to content

Commit

Permalink
feat(enricher): Adds the rh-metering flag for adding Red Hat Runtimes…
Browse files Browse the repository at this point in the history
… metering to your application. (#543)

* feat(enricher): Adds the rh-metering flag for adding Red Hat Runtimes metering to your application.

* The new flag is `--rh-metering`.  can also be used as `--rh-metering.nodeVersion=NODE_VERSION`

* This is currently an undocumented feature since it is more for those using Red Hat Runtimes build of Node.js
  • Loading branch information
lholmquist committed Feb 18, 2021
1 parent 089809e commit 0486d33
Show file tree
Hide file tree
Showing 9 changed files with 315 additions and 17 deletions.
10 changes: 10 additions & 0 deletions bin/nodeshift
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,16 @@ function createOptions (argv) {

options.useDeployment = argv.useDeployment;

// User wants to add red hat metering
// This could be just use defaults based on the rh node image
// or can override the node version
// Keeping this feature undocumented for now
options.metering = argv['rh-metering'];

if (Array.isArray(options.metering)) {
options.metering = helpers.parseMeteringEntry(options.metering);
}

// Not sure about storing these
options.username = argv.username;
options.password = argv.password;
Expand Down
6 changes: 6 additions & 0 deletions lib/config/nodeshift-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ const { promisify } = require('util');
const readFile = promisify(fs.readFile);
const _ = require('lodash');

const DEFAULT_DOCKER_IMAGE = 'registry.access.redhat.com/ubi8/nodejs-14';
const DEFAULT_DOCKER_TAG = 'latest';

async function setup (options = {}) {
options.nodeshiftDirectory = '.nodeshift';
options.projectLocation = options.projectLocation || process.cwd();
Expand Down Expand Up @@ -153,6 +156,9 @@ async function setup (options = {}) {
options.build.strategy = 'Source';
}

options.dockerImge = options.dockerImage || DEFAULT_DOCKER_IMAGE;
options.imageTag = options.imageTag || DEFAULT_DOCKER_TAG;

// Return a new object with the config, the rest client and other data.
const result = Object.assign({}, config, {
projectPackage,
Expand Down
10 changes: 2 additions & 8 deletions lib/definitions/build-strategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,6 @@

const logger = require('../common-log')();

// Perhaps we should define this in another location
const DEFAULT_DOCKER_IMAGE = 'registry.access.redhat.com/ubi8/nodejs-14';
const DEFAULT_DOCKER_TAG = 'latest';

// Default docker image for web-apps
const DEFAULT_WEB_APP_DOCKER_IMAGE = 'nodeshift/ubi8-s2i-web-app';
// Adding in the DOCKER build strategy
Expand Down Expand Up @@ -51,10 +47,8 @@ module.exports = (options) => {
options.dockerImage = options.webApp ? DEFAULT_WEB_APP_DOCKER_IMAGE : options.dockerImage;

// Just doing the source strategy
const dockerImage = options.dockerImage ? options.dockerImage : DEFAULT_DOCKER_IMAGE;
const dockerTag = options.imageTag ? options.imageTag : DEFAULT_DOCKER_TAG;
logger.info(`Using s2i image ${dockerImage} with tag ${dockerTag}`);
const dockerImageName = `${dockerImage}:${dockerTag}`;
logger.info(`Using s2i image ${options.dockerImage} with tag ${options.imageTag}`);
const dockerImageName = `${options.dockerImage}:${options.imageTag}`;

strategy.sourceStrategy = {
env: env,
Expand Down
11 changes: 10 additions & 1 deletion lib/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,14 @@ function generateUUID () {
return Math.random().toString(26).slice(2);
}

function parseMeteringEntry (arr) {
return arr.reduce((accum, curr, index, sourceArray) => {
if (typeof curr === 'object') {
return Object.assign({}, accum, curr);
}
}, {});
}

module.exports = {
yamlToJson: yamlToJson,
normalizeFileList: normalizeFileList,
Expand All @@ -121,5 +129,6 @@ module.exports = {
awaitRequest,
parseIgnoreFile,
matchRule,
generateUUID
generateUUID,
parseMeteringEntry
};
2 changes: 1 addition & 1 deletion lib/resource-enrichers/default-enrichers.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[
"deployment-config", "deployment-env", "service", "route", "labels", "git-info", "health-check", "runtime-label"
"deployment-config", "deployment-env", "service", "route", "labels", "git-info", "health-check", "runtime-label", "meterting"
]
2 changes: 1 addition & 1 deletion lib/resource-enrichers/deployment-enrichers.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[
"deployment", "service", "route", "labels", "git-info", "health-check", "runtime-label"
"deployment", "service", "route", "labels", "git-info", "health-check", "runtime-label", "meterting"
]
86 changes: 86 additions & 0 deletions lib/resource-enrichers/metering-enricher.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
*
* Copyright 2016-2017 Red Hat, Inc, and individual contributors.
*
* 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.
*
*/

'use strict';

// Enricher for adding metering metadata
const METERING_LABELS = {
'com.redhat.component-name': 'Node.js',
'com.redhat.component-type': 'application',
'com.redhat.component-version': '14.x.x', // Need to look at the image
'com.redhat.product-name': 'Red_Hat_Runtimes',
'com.redhat.product-version': '2021/Q1' // Node 14 - 2021/Q1 Node 16 2021/Q4(?)
};

const _ = require('lodash');

function parseNodeMajor (nodeVersion) {
return nodeVersion.split('.')[0];
}

function getProductVersion (nodeVersion) {
let productVersion;
switch (parseNodeMajor(nodeVersion)) {
case '14':
productVersion = '2021/Q1';
break;
default:
productVersion = 'unknown';
break;
}

return productVersion;
}

function parseNodeImage (imageName) {
const split = imageName.split('/');

const justNode = split.find((val) => {
return val.includes('nodejs');
});

const nodeVersion = justNode.split('-')[1];
return nodeVersion;
}

async function addMeteringInfo (config, resourceList) {
return resourceList.map((resource) => {
if (resource.kind === 'DeploymentConfig' || resource.kind === 'Deployment') {
// Check that the metering flag was added
// Also check that a "Red Hat" image is being used?
if (!config.metering) {
return resource;
}

const nodeVersion = config.metering.nodeVersion ? config.metering.nodeVersion : parseNodeImage(config.dockerImage);

resource.spec.template.metadata.labels = _.merge({}, METERING_LABELS, resource.spec.template.metadata.labels);
resource.spec.template.metadata.labels['com.redhat.component-version'] = nodeVersion;
resource.spec.template.metadata.labels['com.redhat.product-version'] = getProductVersion(nodeVersion);

return resource;
}

return resource;
});
}

module.exports = {
enrich: addMeteringInfo,
name: 'metering'
};
12 changes: 6 additions & 6 deletions test/definitions-tests/build-strategy-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ const test = require('tape');
const buildStrategy = require('../../lib/definitions/build-strategy');

test('default strategy', (t) => {
const result = buildStrategy({ buildStrategy: 'Source' });
const result = buildStrategy({ buildStrategy: 'Source', dockerImage: 'registry.access.redhat.com/ubi8/nodejs-14', imageTag: 'latest' });

t.equal(result.type, 'Source', 'default is Source type');
t.ok(result.sourceStrategy, 'Source strategy object');
Expand All @@ -15,7 +15,7 @@ test('default strategy', (t) => {
});

test('strategy with changed dockerTag', (t) => {
const result = buildStrategy({ imageTag: '1-20', buildStrategy: 'Source' });
const result = buildStrategy({ imageTag: '1-20', buildStrategy: 'Source', dockerImage: 'registry.access.redhat.com/ubi8/nodejs-14' });
t.equal(result.sourceStrategy.from.name, 'registry.access.redhat.com/ubi8/nodejs-14:1-20', 'docker image should be 1-20 ubi8/nodejs-14 image');
t.end();
});
Expand Down Expand Up @@ -45,7 +45,7 @@ test('strategy with changed incremental to false', (t) => {
});

test('strategy with change dockerImage', (t) => {
const result = buildStrategy({ dockerImage: 'lholmquist/centos7-s2i-nodejs', buildStrategy: 'Source' });
const result = buildStrategy({ dockerImage: 'lholmquist/centos7-s2i-nodejs', buildStrategy: 'Source', imageTag: 'latest' });

t.equal(result.sourceStrategy.from.name, 'lholmquist/centos7-s2i-nodejs:latest', 'docker image should be latest lholmquist image');
t.end();
Expand All @@ -68,21 +68,21 @@ test('strategy with env vars', (t) => {
});

test('defaults to using latest ubi8/nodejs-14 s2i builder image', t => {
const result = buildStrategy({ buildStrategy: 'Source' });
const result = buildStrategy({ buildStrategy: 'Source', dockerImage: 'registry.access.redhat.com/ubi8/nodejs-14', imageTag: 'latest' });

t.equals(result.sourceStrategy.from.name, 'registry.access.redhat.com/ubi8/nodejs-14:latest');
t.end();
});

test('accepts a node version using imageTag option', t => {
const result = buildStrategy({ imageTag: '1-20', buildStrategy: 'Source' });
const result = buildStrategy({ imageTag: '1-20', buildStrategy: 'Source', dockerImage: 'registry.access.redhat.com/ubi8/nodejs-14' });

t.equals(result.sourceStrategy.from.name, 'registry.access.redhat.com/ubi8/nodejs-14:1-20');
t.end();
});

test('strategy with web-app option enabled', (t) => {
const result = buildStrategy({ webApp: true, buildStrategy: 'Source' });
const result = buildStrategy({ webApp: true, buildStrategy: 'Source', imageTag: 'latest' });

t.equal(result.sourceStrategy.from.name, 'nodeshift/ubi8-s2i-web-app:latest', 'docker image should be latest web-app image');
t.end();
Expand Down

0 comments on commit 0486d33

Please sign in to comment.