Skip to content

Commit

Permalink
feat: utilize secret auth headers in remoteresource (#130)
Browse files Browse the repository at this point in the history
* added secret to create remote resource method

* broke up methods to apply resource and secret and delete

* add function template

* updated apply resources method, broke up delete method

* updated delete methods and applyresource

* Update lib/remoteResource.js

Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>

* Update lib/remoteResource.js

namespace update

Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>

* Update lib/remoteResource.js

Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>

* Update lib/remoteResource.js

Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>

* Update lib/remoteResource.js

Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>

* Update lib/remoteResource.js

Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>

* Update lib/remoteResource.js

Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>

* Update lib/remoteResource.js

Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>

* updated applyresource to take fields from json

* Update lib/remoteResource.js

Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>

* fixed error with krm being declared twice in deleteremote resources

* updated delete resources

updated create

Update lib/remoteResource.js

Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>

Update lib/remoteResource.js

Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>

Update lib/remoteResource.js

Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>

removed

* Update log.js

* publish release candidates

Co-authored-by: NAOD DERIBE <naodderibe@NAODs-MacBook-Pro.local>
Co-authored-by: Alex Lewitt <48691328+alewitt2@users.noreply.github.com>
Co-authored-by: Alexander Lewitt <alewitt2@ibm.com>
  • Loading branch information
4 people authored Mar 17, 2021
1 parent 665c593 commit a2e67ee
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 59 deletions.
31 changes: 17 additions & 14 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,41 @@ script:
# Audit npm packages. Fail build whan a PR audit fails, otherwise report the vulnerability and proceed.
- if [ "${TRAVIS_PULL_REQUEST}" != "false" ]; then npm audit; else npm audit || true; fi
- npm run lint
- if [[ "${TRAVIS_TAG}" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$ ]]; then npm version --no-git-tag-version "${TRAVIS_TAG}"; fi
- docker build --rm -t "quay.io/razee/clustersubscription:${TRAVIS_COMMIT}" .
- if [ -n "${TRAVIS_TAG}" ]; then docker tag quay.io/razee/clustersubscription:${TRAVIS_COMMIT} quay.io/razee/clustersubscription:${TRAVIS_TAG}; fi
- docker images
- ./build/process-template.sh kubernetes/ClusterSubscription/resource.yaml >/tmp/resource.yaml
- if [[ "${TRAVIS_TAG}" =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then npm version --no-git-tag-version "${TRAVIS_TAG}"; fi

before_deploy:
- docker login -u="${QUAY_ID}" -p="${QUAY_TOKEN}" quay.io

deploy:
# Deploy alpha builds
- provider: script
script: docker push "quay.io/razee/clustersubscription:${TRAVIS_TAG}"
# Publish npm package with tag "next" on release candidates
- provider: npm
email: "${NPMJS_EMAIL}"
api_key: "${NPMJS_API_KEY}"
tag: next
skip_cleanup: true
on:
tags: true
condition: ${TRAVIS_TAG} =~ ^[0-9]+\.[0-9]+\.[0-9]+_[0-9]{3}$

# Deploy released builds
condition: ${TRAVIS_TAG} =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)$
# Publish docker image on release and release candidates
- provider: script
script: docker push "quay.io/razee/clustersubscription:${TRAVIS_TAG}"
skip_cleanup: true
on:
tags: true
condition: ${TRAVIS_TAG} =~ ^[0-9]+\.[0-9]+\.[0-9]+(-rc\.[0-9]+)?$
# Publish npm package as "latest" on release
- provider: npm
email: "${NPMJS_EMAIL}"
api_key: "${NPMJS_API_KEY}"
skip_cleanup: true
on:
tags: true
condition: ${TRAVIS_TAG} =~ ^[0-9]+\.[0-9]+\.[0-9]+$
# Publish GitHub release assets on release
- provider: releases
file: /tmp/resource.yaml
skip_cleanup: true
Expand All @@ -45,10 +55,3 @@ deploy:
on:
tags: true
condition: ${TRAVIS_TAG} =~ ^[0-9]+\.[0-9]+\.[0-9]+$
- provider: npm
email: "${NPMJS_EMAIL}"
api_key: "${NPMJS_API_KEY}"
skip_cleanup: true
on:
tags: true
condition: ${TRAVIS_TAG} =~ ^[0-9]+\.[0-9]+\.[0-9]+$
2 changes: 1 addition & 1 deletion lib/log.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
const winston = require('winston');

const log = winston.createLogger({
level: (process.env.LOG_LEVEL || 'info'),
level: (process.env.LOG_LEVEL || 'info'),
format: winston.format.json(),
defaultMeta: { service: 'cluster-subscription' },
transports: [
Expand Down
137 changes: 95 additions & 42 deletions lib/remoteResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,38 +3,48 @@ const Mustache = require('mustache');
const log = require('./log');

const { KubeClass, KubeApiConfig } = require('@razee/kubernetes-util');
const objectPath = require('object-path');
const kubeApiConfig = KubeApiConfig();
const kc = new KubeClass(kubeApiConfig);

const API_VERSION = 'deploy.razee.io/v1alpha2';
const KIND = 'RemoteResource';
const RR_API_VERSION = 'deploy.razee.io/v1alpha2';
const NAMESPACE = process.env.NAMESPACE;

const requestsTemplate = `{
"options": {
"url": "{{{url}}}",
"headers": {
"razee-org-key": "{{orgKey}}"
"razee-org-key": {
"valueFrom": {
"secretKeyRef":{
"name": "{{{secretName}}}",
"namespace": "{{namespace}}",
"key": "razee-api-org-key"
}
}
}
}
}
}`;

const createRemoteResources = async (razeeApi, apiKey, subscriptions, clusterId) => {
log.info('create remote resources subscription list', { subscriptions });
try {
const krm = await kc.getKubeResourceMeta(API_VERSION, KIND, 'update');
return Promise.all(subscriptions.map(async sub => {
const apiKeyBase64 = Buffer.from(apiKey).toString('base64');
const url = `${razeeApi}/${sub.url}`;
const rendered = Mustache.render(requestsTemplate, { url: url, orgKey: apiKey });
const secretName = `clustersubscription-${sub.subscriptionUuid}-secret`;
const rendered = Mustache.render(requestsTemplate, { url: url, secretName: secretName, namespace: NAMESPACE });
const parsed = JSON.parse(rendered);
const resourceName = `clustersubscription-${sub.subscriptionUuid}`;
//console.log(parsed);
const remoteResourceName = `clustersubscription-${sub.subscriptionUuid}`;
const userName = (sub.kubeOwnerName && typeof sub.kubeOwnerName === 'string') ? sub.kubeOwnerName : 'razeedeploy';
const resourceTemplate = {
'apiVersion': API_VERSION,
'kind': KIND,
const remoteResourceJson = {
'apiVersion': RR_API_VERSION,
'kind': 'RemoteResource',
'metadata': {
'namespace': NAMESPACE,
'name': resourceName,
'name': remoteResourceName,
'annotations': {
'deploy.razee.io/clustersubscription': sub.subscriptionUuid,
'deploy.razee.io/clusterid': clusterId
Expand All @@ -47,53 +57,94 @@ const createRemoteResources = async (razeeApi, apiKey, subscriptions, clusterId)
'clusterAuth': {
'impersonateUser': userName
},
'requests': []
'requests':
[]
}
};
resourceTemplate.spec.requests.push(parsed);

const opt = { simple: false, resolveWithFullResponse: true };

const uri = krm.uri({ name: resourceName, namespace: NAMESPACE });
log.debug(resourceName);
const get = await krm.get(resourceName, NAMESPACE, opt);
if (get.statusCode === 200) {
// the remote resource already exists so use mergePatch to apply the resource
log.info(`Attempting mergePatch for an existing resource ${uri}`);
const mergeResult = await krm.mergePatch(resourceName, NAMESPACE, resourceTemplate, opt);
if (mergeResult.statusCode === 200) {
log.info('mergePatch successful', { 'statusCode': mergeResult.statusCode, 'statusMessage': mergeResult.statusMessage });
} else {
log.error('mergePatch error', { 'statusCode': mergeResult.statusCode, 'statusMessage': mergeResult.statusMessage });
}
} else if (get.statusCode === 404) {
// the remote resource does not exist so use post to apply the resource
log.info(`Attempting post for a new resource ${uri}`);
const postResult = await krm.post(resourceTemplate, opt);
if (postResult.statusCode === 200 || postResult.statusCode === 201) {
log.info('post successful', { 'statusCode': postResult.statusCode, 'statusMessage': postResult.statusMessage });
} else {
log.error('post error', { 'statusCode': postResult.statusCode, 'statusMessage': postResult.statusMessage });
remoteResourceJson.spec.requests.push(parsed);

const secretJson = {
'apiVersion': 'v1',
'kind': 'Secret',
'metadata': {
'namespace': NAMESPACE,
'name': secretName,
'annotations': {
'deploy.razee.io/clustersubscription': sub.subscriptionUuid,
'deploy.razee.io/clusterid': clusterId
},
'labels': {
'razee/watch-resource': 'lite'
}
},
'data': {
'razee-api-org-key': apiKeyBase64
}
} else {
log.error(`Get ${get.statusCode} ${uri}`);
}
};

await applyResource(secretJson);
await applyResource(remoteResourceJson);

}));

} catch (error) {
log.error('There was an error creating remote resources', { error });
}
};

const applyResource = async (resourceJson) => {
const resourceName = objectPath.get(resourceJson, 'metadata.name', '');
const resourceNamespace = objectPath.get(resourceJson, 'metadata.namespace', NAMESPACE);
const resourceApiVersion = objectPath.get(resourceJson, 'apiVersion', RR_API_VERSION);
const resourceKind = objectPath.get(resourceJson, 'kind', '');
const opt = { simple: false, resolveWithFullResponse: true };
const krm = await kc.getKubeResourceMeta(resourceApiVersion, resourceKind, 'update');

const uri = krm.uri({ name: resourceName, namespace: resourceNamespace });
log.debug(resourceName);
const get = await krm.get(resourceName, resourceNamespace, opt);
if (get.statusCode === 200) {
// the remote resource already exists so use mergePatch to apply the resource
log.info(`Attempting mergePatch for an existing resource ${uri}`);
const mergeResult = await krm.mergePatch(resourceName, resourceNamespace, resourceJson, opt);
if (mergeResult.statusCode === 200) {
log.info('mergePatch successful', { 'statusCode': mergeResult.statusCode, 'statusMessage': mergeResult.statusMessage });
} else {
log.error('mergePatch error', { 'statusCode': mergeResult.statusCode, 'statusMessage': mergeResult.statusMessage });
}
} else if (get.statusCode === 404) {
// the remote resource does not exist so use post to apply the resource
log.info(`Attempting post for a new resource ${uri}`);
const postResult = await krm.post(resourceJson, opt);
if (postResult.statusCode === 200 || postResult.statusCode === 201) {
log.info('post successful', { 'statusCode': postResult.statusCode, 'statusMessage': postResult.statusMessage });
} else {
console.log(postResult);
log.error('post error', { 'statusCode': postResult.statusCode, 'statusMessage': postResult.statusMessage });
}
} else {
log.error(`Get ${get.statusCode} ${uri}`);
}
};


const deleteRemoteResources = async (resources) => {
const krm = await kc.getKubeResourceMeta(API_VERSION, KIND, 'update');
const selfLinks = resources.map((resource) => krm.uri({ name: resource.metadata.name, namespace: resource.metadata.namespace }));
log.debug('Deleting', { selfLinks });
const krm = await kc.getKubeResourceMeta(RR_API_VERSION, 'RemoteResource', 'update');
const rrSelfLinks = resources.map((resource) => krm.uri({ name: resource.metadata.name, namespace: resource.metadata.namespace }));
log.debug('Deleting', { rrSelfLinks });
await deleteResource(rrSelfLinks, krm);
const krm_secret = await kc.getKubeResourceMeta('v1', 'Secret', 'update');
const secretSelfLinks = resources.map((resource) => krm_secret.uri({ name: `${resource.metadata.name}-secret`, namespace: resource.metadata.namespace, }));
log.debug('Deleting', { secretSelfLinks });
await deleteResource(secretSelfLinks, krm_secret);
};

const deleteResource = async (selfLinks, krm) => {
try {
selfLinks.map(async (selfLink) => {
log.info(`Delete ${selfLink}`);
const opt = { uri: selfLink, simple: false, resolveWithFullResponse: true, method: 'DELETE' };
console.log(opt);
const res = await krm.request(opt);
if (res.statusCode === 404) {
log.info(`Delete ${res.statusCode} ${opt.uri}`);
Expand All @@ -108,13 +159,14 @@ const deleteRemoteResources = async (resources) => {
} catch (error) {
log.error(error);
}

};

const getRemoteResources = async (clusterId) => {
log.debug('Getting a list of clustersubscription remote resources on this cluster');
let remoteResources = [];
try {
const krm = await kc.getKubeResourceMeta(API_VERSION, KIND, 'get');
const krm = await kc.getKubeResourceMeta(RR_API_VERSION, 'RemoteResource', 'get');
const opt = { simple: false, resolveWithFullResponse: true };
const get = await krm.get('', NAMESPACE, opt);
if (get.statusCode === 200) {
Expand All @@ -140,3 +192,4 @@ const getRemoteResources = async (clusterId) => {
exports.createRemoteResources = createRemoteResources;
exports.getRemoteResources = getRemoteResources;
exports.deleteRemoteResources = deleteRemoteResources;
exports.applyResource = applyResource;
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"graphql": "^15.5.0",
"graphql-tag": "^2.11.0",
"mustache": "^4.1.0",
"object-path": "^0.11.5",
"subscriptions-transport-ws": "^0.9.18",
"touch": "^3.1.0",
"winston": "^3.3.3"
Expand Down

0 comments on commit a2e67ee

Please sign in to comment.