Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: utilize secret auth headers in remoteresource #130

Merged
merged 22 commits into from
Mar 17, 2021
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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':
[]
}
};
nderibe marked this conversation as resolved.
Show resolved Hide resolved
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) => {
alewitt2 marked this conversation as resolved.
Show resolved Hide resolved
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