diff --git a/.codefresh/codefresh.yaml b/.codefresh/codefresh.yaml
index 07f19f82..c33081a5 100644
--- a/.codefresh/codefresh.yaml
+++ b/.codefresh/codefresh.yaml
@@ -22,6 +22,7 @@ steps:
commands:
- export VERSION=$(jq -r ".version" package.json)
- cf_export VERSION
+ # - export FILE_VERSION= $(cat ./venonactl/VERSION)
- cf_export FILE_VERSION=$(cat ./venonactl/VERSION)
when:
steps:
diff --git a/.codefresh/test-agent.yaml b/.codefresh/test-agent.yaml
deleted file mode 100644
index 02f5bf76..00000000
--- a/.codefresh/test-agent.yaml
+++ /dev/null
@@ -1,82 +0,0 @@
-version: '1.0'
-
-stages:
-- Test
-- Notification
-
-mode: parallel
-
-steps:
-
- create_namespace:
- stage: Test
- title: 'Create namespace in Kuberentes'
- image: codefresh/kube-helm
- commands:
- - kubectl config use-context $KUBE_CONTEXT
- - kubectl create namespace $KUBE_NAMESPACE
-
- install_agent:
- stage: Test
- title: 'Install agent'
- image: codefresh/cli
- commands:
- # Install agent, runtime and attach it
- - codefresh install agent --name $AGENT_NAME --kube-namespace $KUBE_NAMESPACE --install-runtime --kube-context-name $KUBE_CONTEXT --kube-config-path $KUBECONFIG
- - codefresh run -b master $TEST_PIPELINE_ID
- when:
- steps:
- - name: create_namespace
- on:
- - success
-
- uninstall_agent:
- stage: Test
- title: 'Uninstall agent'
- image: codefresh/cli
- commands:
- # Uninstall agent, runtime
- - codefresh uninstall agent --name $AGENT_NAME --kube-namespace $KUBE_NAMESPACE
- - codefresh uninstall runtime --runtime-name $KUBE_CONTEXT/$KUBE_NAMESPACE --kube-namespace $KUBE_NAMESPACE --kube-context-name $KUBE_CONTEXT --kube-config-path $KUBECONFIG
- when:
- steps:
- - name: install_agent
- on:
- - success
-
- delete_namespace:
- stage: Test
- title: 'Delete namespace in Kuberentes'
- image: codefresh/kube-helm
- commands:
- - kubectl delete namespace $KUBE_NAMESPACE
- when:
- steps:
- - name: uninstall_agent
- on:
- - success
-
-
- reported_failure:
- stage: Notification
- title: Report failure to Slack
- type: slack-message-sender
- arguments:
- WEBHOOK_URL: ${{SLACK_WEBHOOK_URL}}
- MESSAGE: "Venona installation failed, link: $CF_BUILD_URL"
- when:
- steps:
- any:
- - name: create_namespace
- on:
- - failure
- - name: create_namespace
- on:
- - failure
- - name: delete_namespace
- on:
- - failure
- - name: uninstall_agent
- on:
- - failure
-
diff --git a/.eslintrc.yml b/.eslintrc.yml
index 37b3f05a..0d80a269 100644
--- a/.eslintrc.yml
+++ b/.eslintrc.yml
@@ -23,7 +23,7 @@ rules:
semi:
- error
- always
- "jest/no-disabled-tests": "error"
+ "jest/no-disabled-tests": "warn"
"jest/no-focused-tests": "error"
"jest/no-identical-title": "error"
"jest/prefer-to-have-length": "warn"
diff --git a/.gitignore b/.gitignore
index 84cc8ec8..976800d2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,4 +16,3 @@ telepresence.log
venonactl/dist/*
venonactl-linux
venonalog.json
-.venonaconf
diff --git a/README.md b/README.md
index ddba15fe..c1658fab 100644
--- a/README.md
+++ b/README.md
@@ -2,72 +2,6 @@
[![Go Report Card](https://goreportcard.com/badge/github.com/codefresh-io/venona)](https://goreportcard.com/report/github.com/codefresh-io/venona)
[![Codefresh build status]( https://g.codefresh.io/api/badges/pipeline/codefresh-inc/codefresh-io%2Fvenona%2Fvenona?type=cf-1)]( https://g.codefresh.io/public/accounts/codefresh-inc/pipelines/codefresh-io/venona/venona)
-## Version 1.x.x
-Version 1.0.0 is released now, read more about migration from older version [here](#Migration)
-We highly suggest to use [Codefresh official CLI](https://codefresh-io.github.io/cli/) to install the agent:
-```bash
-kubectl create namespace codefresh
-codefresh install agent --kube-namespace codefresh --install-runtime
-```
-
-The last command will:
-1. Install the agent on the namespace `codefresh`
-2. Install the runtime on the same namespace
-3. Attach the runtime to the agent
-
-It is still possible, for advanced users to install all manually, for example:
-One process of Venona can manage multiple runtime environments
-NOTE: Please make sure that the process where Venona is installed there is a network connection to the clusters where the runtimes will be installed
-```bash
-# 1. Create namespace for the agent:
-kubectl create namespace codefresh-agent
-
-# 2. Install the agent on the namespace ( give your agent a unique):
-# Print a token that the Venona process will be using.
-codefresh create agent $NAME
-codefresh install agent --token $TOKEN --kube-namespace codefresh-agent
-
-# 3. Create namespace for the first runtime:
-kubectl create namespace codefresh-runtime-1
-
-# 4. Install the first runtime on the namespace
-# 5. the runtime name is printed
-codefresh install runtime --kube-namespace codefresh-runtime-1
-
-# 6. Attach the first runtime to agent:
-codefresh attach runtime --agent-name $AGENT_NAME --agent-kube-namespace codefresh-agent --runtime-name $RUNTIME_NAME --kube-namespace codefresh-runtime-1
-
-# 7. Restart the venona pod in namespace `codefresh-agent`
-kubectl delete pods $VENONA_POD
-
-# 8. Create namespace for the second runtime
-kubectl create namespace codefresh-runtime-2
-
-# 9. Install the second runtime on the namespace
-codefresh install runtime --kube-namespace codefresh-runtime-2
-
-# 10. Attach the second runtime to agent and restart the Venoa pod automatically
-codefresh attach runtime --agent-name $AGENT_NAME --agent-kube-namespace codefresh-agent --runtime-name $RUNTIME_NAME --runtime-kube-namespace codefresh-runtime-1 --restart-agent
-
-```
-
-## Migration
-Migrating from Venona `< 1.x.x` to `> 1.x.x` is not done automatically, please use the [migration script](https://github.com/codefresh-io/venona/blob/master/scripts/migration.sh) to do that, check out which environment variables are required to run it.
-```bash
-# This script comes to migrate old versions of Venona installation ( version < 1.x.x ) to new version (version >= 1.0.0 )
-# Please read carefully what the script does.
-# There will be a "downtime" in terms of your builds targeted to this runtime environment
-# Once the script is finished, all the builds during the downtime will start
-# The script will:
-# 1. Create new agent entity in Codefresh using Codefresh CLI - give it a name $CODEFRESH_AGENT_NAME, default is "codefresh"
-# 2. Install the agent on you cluster pass variables:
-# a. $VENONA_KUBE_NAMESPACE - required
-# b. $VENONA_KUBE_CONTEXT - default is current-context
-# c. $VENONA_KUBECONFIG_PATH - default is $HOME/.kube/config
-# 3. Attach runtime to the new agent (downtime ends) - pass $CODEFRESH_RUNTIME_NAME - required
-```
-
-
## Installation
### Prerequisite:
@@ -78,13 +12,42 @@ Migrating from Venona `< 1.x.x` to `> 1.x.x` is not done automatically, please u
* [Codefresh](https://codefresh-io.github.io/cli/) - Used to create resource in Codefresh
* Authenticated context exist under `$HOME/.cfconfig` or authenticate with [Codefesh CLI](https://codefresh-io.github.io/cli/getting-started/#authenticate)
+
### Install venona
* Download [venona's](https://github.com/codefresh-io/venona/releases) binary
* With homebrew:
* `brew tap codefresh-io/venona`
* `brew install venona`
-
+* Create namespace where venona should run
+ > `kubectl create namespace codefresh-runtime`
+* Create *new* runtime-environment with Venona's agents installed
+ > `venona install --kube-namespace codefresh-runtime`
+* Get the status
+ > `venona status`
+ > `kubectl get pods -n codefresh-runtime`
+
+#### Install Options
+
+| Option Argument | Type | Description |
+| -------------------- | -------- | --------------------------------------------------- |
+| --build-annotations | stringArray | The kubernetes metadata.annotations as "key=value" to be used by venona build resources (default is no node selector) |
+| --build-node-selector | string | The kubernetes node selector "key=value" to be used by venona build resources (default is no node selector) |
+| --cluster-name | string | cluster name (if not passed runtime-environment will be created cluster-less); this is a friendly name used for metadata does not need to match the literal cluster name. Limited to 20 Characters. |
+| --dry-run | boolean | Set to true to simulate installation |
+| -h, --help | boolean | help for install |
+| --in-cluster | boolean | Set flag if venona is been installed from inside a cluster |
+| --kube-context-name | string | Name of the kubernetes context on which venona should be installed (default is current-context) [$KUBE_CONTEXT] |
+| --kube-namespace | string |Name of the namespace on which venona should be installed [$KUBE_NAMESPACE] |
+| --kube-node-selector | string | The kubernetes node selector "key=value" to be used by venona resources (default is no node selector) |
+| --kubernetes-runner-type | boolean | Set the runner type to kubernetes (alpha feature) |
+| --only-runtime-environment | boolean | Set to true to onlky configure namespace as runtime-environment for Codefresh |
+| --runtime-environment | string | if --skip-runtime-installation set, will try to configure venona on current runtime-environment |
+| --set-default | boolean | Mark the install runtime-environment as default one after installation |
+| --skip-runtime-installation | boolean | Set flag if you already have a configured runtime-environment, add --runtime-environment flag with name |
+| --storage-class | string | Set a name of your custom storage class, note: this will not install volume provisioning components |
+| --tolerations | string | The kubernetes tolerations as JSON string to be used by venona resources (default is no tolerations). If prefixed with "@", loads from a file: @/tmp/tolerations.json |
+| --venona-version | string | Version of venona to install (default is the latest) |
#### Install on cluster version < 1.10
* Make sure the `PersistentLocalVolumes` [feature gate](https://kubernetes.io/docs/reference/command-line-tools-reference/feature-gates/) is turned on
@@ -115,11 +78,27 @@ Each one has own RBAC needs and therefore, created roles(and cluster-roles)
The resource descriptors are avaliable [here](https://github.com/codefresh-io/venona/tree/master/venonactl/templates/kubernetes)
List of the resources that will be created
* Agent (grouped by `/.*.venona.yaml/`)
- * `service-account.re.yaml` - The service account that the Venona pod will use to create the resource on the runtime namespace(the resoucre installed on the runtime namespace)
- * `role.re.yaml` - Allow to GET, CREATE and DELETE pods and persistentvolumeclaims
- * `role-binding.re.yaml` - The agent is spinning up pods and pvc, this biniding binds `role.venona.yaml` to `service-account.venona.yaml`
+ * `service-account.venona.yaml` - The service account that the agent's pod will use at the end
* `cluster-role-binding.venona.yaml` - The agent discovering K8S apis by calling to `openapi/v2`, this ClusterRoleBinding binds bootstraped ClusterRole by Kubernetes `system:discovery` to `service-account.venona.yaml`. This role has only permissions to make a GET calls to non resources urls
+ * `role.venona.yaml` - Allow to GET, CREATE and DELETE pods and persistentvolumeclaims
+ * `role-binding.venona.yaml` - The agent is spinning up pods and pvc, this biniding binds `role.venona.yaml` to `service-account.venona.yaml`
* Runtime-environment (grouped by `/.*.re.yaml/`) Kubernetes controller that spins up all required resources to provide a good caching expirience during pipeline execution
* `service-account.dind-volume-provisioner.re.yaml` - The service account that the controller will use
* `cluster-role.dind-volume-provisioner.re.yaml` Defines all the permission needed for the controller to operate correctly
* `cluster-role-binding.dind-volume-provisioner.yaml` - Binds the ClusterRole to `service-account.dind-volume-provisioner.re.yaml`
+
+### Access the cluster from executed pipeline
+After a successfull installation of Venona, you'll be able to run a Codefresh pipeline on the configured cluster.
+However, the pipeline itself dosent have any permission to connect to the hosted cluster.
+To make it work you need to add the cluster to Codefresh (make sure the service acount has all the permissions you need)
+> codefresh create cluster --kube-context CONTEXT_NAME --namespace NAMESPACE --serviceaccount SERVICE_ACCOUNT --behind-firewall
+
+#### Upgrade
+To upgrade existing runtime-environment, a one that was created without Venona's agent, run:
+* Find the name of the cluster was linked to that runtime environment
+Example: `codefresh get cluster`
+* Install
+Example: `venona install --cluster-name CLUSTER`
+* Get the status
+Example: `venona status RUNTIME-ENVIRONMENT`
+Example: `kubectl get pods -n NAMESPACE`
diff --git a/__mocks__/recursive-readdir.js b/__mocks__/recursive-readdir.js
deleted file mode 100644
index d8205362..00000000
--- a/__mocks__/recursive-readdir.js
+++ /dev/null
@@ -1,15 +0,0 @@
-let files = [];
-
-const recursive = async (path, ignore, cb) => {
- return cb(null, files);
-};
-
-recursive.__setFiles = (names) => {
- files = files.concat(names);
-};
-
-recursive.__clear = () => {
- files = [];
-};
-
-module.exports = recursive;
\ No newline at end of file
diff --git a/agent/__tests__/index.spec.js b/agent/__tests__/index.spec.js
index d531095f..f83b20ab 100644
--- a/agent/__tests__/index.spec.js
+++ b/agent/__tests__/index.spec.js
@@ -1,31 +1,24 @@
-
+const _ = require('lodash');
const Promise = require('bluebird');
const scheduler = require('node-schedule');
-const fs = require('fs');
-const path = require('path');
-const _ = require('lodash');
-const recursive = require('recursive-readdir');
const Agent = require('./../');
const Codefresh = require('./../../services/Codefresh');
+const Kubernetes = require('./../../services/Kubernetes');
const Logger = require('./../../services/Logger');
const { Server } = require('./../../server');
const TaskPullerJob = require('./../../jobs/TaskPullerJob/TaskPuller.job');
const StatusReporterJob = require('./../../jobs/StatusReporterJob/StatusReporter.job');
-const Kubernetes = require('./../../services/Kubernetes');
jest.mock('./../../services/Codefresh');
-jest.mock('./../../services/Logger');
jest.mock('./../../services/Kubernetes');
+jest.mock('./../../services/Logger');
jest.mock('./../../server');
-jest.mock('fs');
-jest.mock('recursive-readdir');
const buildTestConfig = () => ({
metadata: {
name: 'agent',
version: '1.0',
mode: 'mode',
- venonaConfDir: '/path/to/venona/config/dir'
},
server: {
port: '9000',
@@ -60,13 +53,6 @@ const buildTestConfig = () => ({
}
});
-const loadActualJobs = () => {
- recursive.__setFiles([
- path.join(__dirname, '../../', 'jobs/StatusReporterJob/StatusReporter.job.js'),
- path.join(__dirname, '../../', 'jobs/TaskPullerJob/TaskPuller.job.js'),
- ]);
-};
-
beforeEach(() => {
Server.mockImplementationOnce(() => ({
init: jest.fn(),
@@ -74,149 +60,181 @@ beforeEach(() => {
Codefresh.mockImplementationOnce(() => ({
init: jest.fn(),
}));
- recursive.__setFiles([]);
- fs.readdir.mockImplementationOnce((path, cb) => {
- cb(null, []);
- });
-});
-
-afterEach(() => {
- recursive.__clear();
+ Kubernetes.mockImplementationOnce(() => ({
+ init: jest.fn(),
+ }));
+ Kubernetes.buildFromConfig = jest.fn(Kubernetes);
+ Kubernetes.buildFromInCluster = jest.fn(Kubernetes);
});
describe('Agent unit test', () => {
+ describe('Constructing new Agent', () => {
+
+ describe('positive', () => {
+ it('Should construct successfully', () => {
+ const agent = new Agent(buildTestConfig());
+ expect(Object.keys(agent).sort()).toEqual([
+ 'kubernetesAPI',
+ 'codefreshAPI',
+ 'logger',
+ 'jobs',
+ 'queue',
+ 'server',
+ ].sort());
+ });
+
+ it('Should create logger during construction', () => {
+ new Agent(buildTestConfig());
+ expect(Logger.create).toHaveBeenCalled();
+ });
+
+ it('Should create logger during construction with specific keys', () => {
+ new Agent(buildTestConfig());
+ const callsArguments = Logger.create.mock.calls[0];
+ expect(Object.keys(callsArguments[0])).toEqual(['name', 'version', 'mode']);
+ expect(Object.keys(callsArguments[1])).toEqual(['prettyPrint', 'level']);
+ });
+
+ it('Should call logger with message during construction', () => {
+ new Agent(buildTestConfig());
+ const callsArguments = Logger.create.mock.instances[1].info.mock.calls[0][0];
+ expect(callsArguments).toEqual('Starting agent');
+ });
+
+ it('Should Codefresh API service during construction just once', () => {
+ new Agent(buildTestConfig());
+ const totalCallsToCodefreshConstructor = Codefresh.mock.calls;
+ expect(totalCallsToCodefreshConstructor).toHaveLength(1);
+ });
+
+ it('Should construct CodefreshAPI service with specific keys', () => {
+ new Agent(buildTestConfig());
+ const callsArguments = Codefresh.mock.calls[0];
+ expect(callsArguments).toHaveLength(2);
+ expect(Object.keys(callsArguments[0])).toEqual(['name', 'version', 'mode']);
+ expect(Object.keys(callsArguments[1])).toEqual(['baseURL', 'token']);
+ });
+
+ it('Should construct KubernetesAPI service with specific keys', () => {
+ new Agent(buildTestConfig());
+ const callsArguments = Kubernetes.buildFromConfig.mock.calls[0];
+ expect(callsArguments).toHaveLength(2);
+ expect(Object.keys(callsArguments[0])).toEqual(['name', 'version', 'mode']);
+ expect(Object.keys(callsArguments[1])).toEqual(['config']);
+ });
+
+ it('Should construct KubernetesAPI service when agent running from inside a cluster', () => {
+ Kubernetes.buildFromInCluster = jest.fn();
+ new Agent(_.merge(buildTestConfig(), { metadata: { name: 'fake-name', mode: 'InCluster' } }));
+ const callsArguments = Kubernetes.buildFromInCluster.mock.calls[0];
+ expect(Kubernetes.buildFromInCluster).toHaveBeenCalled();
+ expect(Object.keys(callsArguments[0])).toEqual(['name', 'version', 'mode']);
+ });
+
+ it('Should construct Server with specific keys', () => {
+ new Agent(buildTestConfig());
+ const callsArguments = Server.mock.calls[0];
+ expect(callsArguments).toHaveLength(3);
+ expect(Object.keys(callsArguments[0])).toEqual(['name', 'version', 'mode']);
+ expect(Object.keys(callsArguments[1])).toEqual(['port']);
+ expect(Object.keys(callsArguments[2])).toEqual(['info', 'child', 'error']);
+ });
+
+ });
+
+ describe('negative', () => {
+ it('Should throw an error in case the agent was not constructed correctly', () => {
+ try {
+ Logger.create.mockImplementationOnce(() => {
+ throw new Error('error');
+ });
+ new Agent(buildTestConfig());
+ } catch (err) {
+ expect(err.toString()).toEqual('Error: error');
+ }
+ });
+ });
+
+ });
describe('Initializing agent', () => {
describe('positive', () => {
- it('Should report all services been initialized', async () => {
- const agent = new Agent();
- await agent.init(buildTestConfig());
- const loggerSuccessMessage = Logger.create.mock.instances[1].info.mock.calls[2][0];
- expect(loggerSuccessMessage).toEqual('All services has been initialized');
-
+ it('Should report all services been initialized', () => {
+ return new Agent(buildTestConfig())
+ .init()
+ .then(() => {
+ const loggerSuccessMessage = Logger.create.mock.instances[1].info.mock.calls[2][0];
+ expect(loggerSuccessMessage).toEqual('All services has been initialized');
+ });
});
- it('Should call to Server initialization process during agent initialization', async () => {
+ it('Should call to Server initialization process during agent initialization', () => {
const serverInitSpy = jest.fn();
Server.mockReset();
Server.mockImplementationOnce(() => ({
init: serverInitSpy,
}));
- const agent = new Agent();
- await agent.init(buildTestConfig());
- expect(serverInitSpy).toHaveBeenCalledTimes(1);
- expect(serverInitSpy).toHaveBeenCalledWith();
-
+ return new Agent(buildTestConfig())
+ .init()
+ .then(() => {
+ expect(serverInitSpy).toHaveBeenCalledTimes(1);
+ expect(serverInitSpy).toHaveBeenCalledWith();
+ });
});
- it('Should call to CodefreshAPI initialization process during agent initialization', async () => {
+ it('Should call to CodefreshAPI initialization process during agent initialization', () => {
const codefreshInitSpy = jest.fn();
Codefresh.mockReset();
Codefresh.mockImplementation(() => ({
init: codefreshInitSpy,
}));
- jest.unmock('recursive-readdir');
- const agent = new Agent();
- await agent.init(buildTestConfig());
- expect(codefreshInitSpy).toHaveBeenCalledTimes(1);
- expect(codefreshInitSpy).toHaveBeenCalledWith();
+ return new Agent(buildTestConfig())
+ .init()
+ .then(() => {
+ expect(codefreshInitSpy).toHaveBeenCalledTimes(1);
+ expect(codefreshInitSpy).toHaveBeenCalledWith();
+ });
+ });
+ it('Should call to KubernetesAPI initialization process during agent initialization', () => {
+ const kubernetesInitSpy = jest.fn();
+ Kubernetes.mockReset();
+ Kubernetes.mockImplementation(() => ({
+ init: kubernetesInitSpy,
+ }));
+ return new Agent(buildTestConfig())
+ .init()
+ .then(() => {
+ expect(kubernetesInitSpy).toHaveBeenCalledTimes(1);
+ expect(kubernetesInitSpy).toHaveBeenCalledWith();
+ });
});
- it('Should call to _startJob for both supported tasks', async () => {
- loadActualJobs();
- const agent = new Agent();
+ it('Should call to _startJob for both supported tasks', () => {
+ const agent = new Agent(buildTestConfig());
agent._startJob = jest.fn();
- await agent.init(buildTestConfig());
- expect(agent._startJob).toHaveBeenCalledTimes(2);
- expect(agent._startJob).toHaveBeenNthCalledWith(1, StatusReporterJob);
- expect(agent._startJob).toHaveBeenNthCalledWith(2, TaskPullerJob);
-
+ return agent
+ .init()
+ .then(() => {
+ expect(agent._startJob).toHaveBeenCalledTimes(2);
+ expect(agent._startJob).toHaveBeenNthCalledWith(1, StatusReporterJob);
+ expect(agent._startJob).toHaveBeenNthCalledWith(2, TaskPullerJob);
+ });
});
});
-
- describe('Prepare server', () => {
+
+ describe('negative', () => {
+
it('Should throw an error when initialization crashed', () => {
Server.mockReset();
Server.mockImplementationOnce(() => ({
init: jest.fn().mockRejectedValue(new Error('Error!')),
}));
- return expect(new Agent().init(buildTestConfig())).rejects.toThrow('Failed to initialize agent with error, message: Error!');
+ return expect(new Agent(buildTestConfig()).init()).rejects.toThrow('Failed to initialize agent with error message');
});
});
- describe('Prepare runtimes', () => {
- it('Should fail to init in case failed to read metadata.venonaConfDir directory', async () => {
- fs.readdir.mockReset();
- fs.readdir.mockImplementationOnce((path, cb) => cb(new Error('Failed to read directory')));
- const agent = new Agent();
- return expect(agent.init(buildTestConfig())).rejects.toThrow('Failed to initialize agent with error, message: Failed to read directory');
- });
- it('Should log warning that nasted directory under metadata.venonaConfDir is not going to be read', async () => {
- fs.readdir.mockReset();
- fs.readdir.mockImplementationOnce((path, cb) => cb(null, [
- 'sub-dir',
- ]));
- fs.stat.mockImplementation((path, cb) => {
- if (path.includes('sub-di')) {
- cb(null, {
- isDirectory: () => true,
- });
- }
- });
-
- const agent = new Agent();
- await agent.init(buildTestConfig());
- expect(agent.logger.warn).toHaveBeenCalledTimes(1);
- expect(agent.logger.warn).toHaveBeenCalledWith('Directory "sub-dir" ignored, Venona loading only files that are mached to regexp /.*\\.runtime\\.yaml/');
- });
- it('Should log warning that file that is not matched to the regexp is ignored from being loaded', async () => {
- fs.readdir.mockReset();
- fs.readdir.mockImplementationOnce((path, cb) => cb(null, [
- 'file',
- ]));
- fs.stat.mockImplementation((path, cb) => {
- cb(null, {
- isDirectory: () => false,
- });
- });
-
- const agent = new Agent();
- await agent.init(buildTestConfig());
- expect(agent.logger.warn).toHaveBeenCalledTimes(1);
- expect(agent.logger.warn).toHaveBeenCalledWith('File "file" ignored, Venona loading only files that are mached to regexp /.*\\.runtime\\.yaml/');
- });
- it('Should log warning in case found duplication of runtimes', async () => {
- const db = {
- 'a.runtime.yaml': 'name: runtime',
- 'b.runtime.yaml': 'name: runtime',
- };
- fs.readdir.mockReset();
- fs.readdir.mockImplementationOnce((path, cb) => {
- cb(null, _.keys(db));
- });
- fs.stat.mockImplementation((path, cb) => {
- cb(null, {
- isDirectory: () => false,
- });
- });
- fs.readFile.mockImplementation((location, cb) => {
- cb(null, db[path.basename(location)]);
- });
- fs.access.mockImplementation((path, cb) => {
- cb(null);
- });
- Kubernetes.mockImplementation(() => ({
- init: Promise.resolve,
- }));
- Kubernetes.buildFromConfig = jest.fn(Kubernetes);
-
- const agent = new Agent();
- await expect(agent.init(buildTestConfig())).resolves.toEqual();
- expect(agent.logger.warn).toHaveBeenCalledWith('Ignoring runtime "runtime", already been configured, conflict with file: "/path/to/venona/config/dir/b.runtime.yaml"');
- });
- });
});
describe('Queue', () => {
@@ -226,8 +244,7 @@ describe('Agent unit test', () => {
cb();
});
const spy = jest.fn();
- const agent = new Agent();
- await agent.init(buildTestConfig());
+ const agent = new Agent(buildTestConfig());
const FakeJob = function() {
this.exec = spy;
return this;
@@ -243,8 +260,7 @@ describe('Agent unit test', () => {
cb();
});
const error = new Error('my error');
- const agent = new Agent();
- await agent.init(buildTestConfig());
+ const agent = new Agent(buildTestConfig());
const FakeJob = function() {
this.exec = jest.fn().mockRejectedValue(error);
return this;
@@ -264,8 +280,7 @@ describe('Agent unit test', () => {
cb();
});
const error = new Error('my error');
- const agent = new Agent();
- await agent.init(buildTestConfig());
+ const agent = new Agent(buildTestConfig());
const FakeJob = function() {
this.exec = jest.fn(() => {
throw (error);
@@ -282,12 +297,13 @@ describe('Agent unit test', () => {
expect(handleErrorSpy).toHaveBeenCalledWith(error);
});
+ it.skip('Should call cb with an error in case a job timedout', () => {});
+
it('Should call cb in case the job was resolved', async () => {
scheduler.scheduleJob = jest.fn((_ex, cb) => {
cb();
});
- const agent = new Agent();
- await agent.init(buildTestConfig());
+ const agent = new Agent(buildTestConfig());
const FakeJob = function() {
this.exec = jest.fn();
return this;
@@ -306,8 +322,7 @@ describe('Agent unit test', () => {
scheduler.scheduleJob = jest.fn((_ex, cb) => {
cb();
});
- const agent = new Agent();
- await agent.init(buildTestConfig());
+ const agent = new Agent(buildTestConfig());
const FakeJob = function() {
this.exec = jest.fn();
return this;
@@ -324,10 +339,9 @@ describe('Agent unit test', () => {
describe('Auto jobs load', () => {
it('Should load only jobs that related to agent', async () => {
- loadActualJobs();
- const agent = new Agent();
+ const agent = new Agent(buildTestConfig());
agent._startJob = jest.fn();
- await agent.init(buildTestConfig());
+ await agent._loadJobs();
expect(agent._startJob).toHaveBeenCalledTimes(2);
});
});
@@ -338,8 +352,7 @@ describe('Agent unit test', () => {
scheduler.scheduleJob = jest.fn((_ex, cb) => {
cb();
});
- const agent = new Agent();
- await agent.init(buildTestConfig());
+ const agent = new Agent(buildTestConfig());
const FakeJob = function() {
this.exec = jest.fn();
return this;
@@ -350,12 +363,11 @@ describe('Agent unit test', () => {
expect(agent.logger.child).toHaveBeenCalledTimes(1);
});
- it('Should pass all services and runtimes the Job constructor', async () => {
+ it('Should pass all services to the Job constructor', async () => {
scheduler.scheduleJob = jest.fn((_ex, cb) => {
cb();
});
- const agent = new Agent();
- await agent.init(buildTestConfig());
+ const agent = new Agent(buildTestConfig());
const FakeJob = jest.fn().mockImplementation(() => {
this.exec = jest.fn();
return this;
@@ -366,15 +378,14 @@ describe('Agent unit test', () => {
});
agent._startJob(FakeJob);
await Promise.delay(100);
- expect(FakeJob).toHaveBeenCalledWith(agent.codefreshAPI, {}, newTaskLogger);
+ expect(FakeJob).toHaveBeenCalledWith(agent.codefreshAPI, agent.kubernetesAPI, newTaskLogger);
});
it('Should push the job to the queue', async () => {
scheduler.scheduleJob = jest.fn((_ex, cb) => {
cb();
});
- const agent = new Agent();
- await agent.init(buildTestConfig());
+ const agent = new Agent(buildTestConfig());
const FakeJob = function() {
this.exec = jest.fn();
return this;
diff --git a/agent/index.js b/agent/index.js
index e31e8284..995fe678 100644
--- a/agent/index.js
+++ b/agent/index.js
@@ -3,80 +3,32 @@ const Chance = require('chance');
const scheduler = require('node-schedule');
const path = require('path');
const _ = require('lodash');
-const fs = require('fs');
-const yaml = require('js-yaml');
const Queue = require('async/priorityQueue');
const recursive = require('recursive-readdir');
const Codefresh = require('./../services/Codefresh');
const Kubernetes = require('./../services/Kubernetes');
const Logger = require('./../services/Logger');
const { Server } = require('./../server');
-const { LOGGER_NAMESPACES } = require('./../constants');
+const { LOGGER_NAMESPACES, AGENT_MODES } = require('./../constants');
-const ERROR_MESSAGES = {};
+const ERROR_MESSAGES = {
+};
class Agent {
-
- async init(config = {}) {
- try {
- this.logger = Logger.create(config.metadata, config.logger);
- this.logger.info('Initializing agent');
- this.server = new Server(config.metadata, config.server, this.logger.child({
- namespace: LOGGER_NAMESPACES.SERVER,
- }));
- this.codefreshAPI = new Codefresh(config.metadata, config.codefresh);
- this.jobs = config.jobs;
- this.queue = Queue(this._queueRunner.bind(this), config.jobs.queue.concurrency);
- this.queue.drain = this._onEmptyQueue.bind(this);
- await Promise.all([
- this.server.init(),
- this.codefreshAPI.init(),
- this._prepareRuntimes(config),
- ]);
- this.logger.info('All services has been initialized');
- await this._loadJobs();
- } catch(err) {
- const message = `Failed to initialize agent with error, message: ${err.message}`;
- this.logger.error(message);
- throw new Error(message);
- }
- }
-
- async _prepareRuntimes(config = {}) {
- this.logger.info(`Reading Venona config file directory: ${config.metadata.venonaConfDir}`);
- const cnf = await this._readFromVenonaConfDir(config.metadata.venonaConfDir);
- this.runtimes = {};
- _.map(cnf, (runtimecnf) => {
- if (this.runtimes[runtimecnf.name]) {
- this.logger.warn(`Ignoring runtime "${runtimecnf.name}", already been configured, conflict with file: "${runtimecnf.file}"`);
- return;
- }
- this.runtimes[runtimecnf.name] = {
- spec: _.omit(runtimecnf, 'name'),
- };
- });
- await Promise.all(_.map(this.runtimes, async (runtime, name) => {
- this.logger.info(`Initializing Kubernetes client for runtime: ${name}`);
- const opt = {
- config: {
- url: runtime.spec.host,
- auth: {
- bearer: runtime.spec.token
- },
- ca: runtime.spec.crt
- },
- };
- const client = Kubernetes.buildFromConfig(config.metadata, opt);
- try {
- await client.init();
- runtime.kubernetesAPI = client;
- this.logger.info(`Runtime ${name} was loaded successfuly`);
- } catch(err) {
- this.logger.error(`Failed to initiate runtime: ${name}, error: ${err.message}`);
- runtime.metadata.error = err.message;
- }
+ constructor(config = {}) {
+ this.logger = Logger.create(config.metadata, config.logger);
+ this.logger.info('Starting agent');
+ this.server = new Server(config.metadata, config.server, this.logger.child({
+ namespace: LOGGER_NAMESPACES.SERVER,
}));
+ this.codefreshAPI = new Codefresh(config.metadata, config.codefresh);
+ this.kubernetesAPI = config.metadata.mode === AGENT_MODES.IN_CLUSTER
+ ? Kubernetes.buildFromInCluster(config.metadata)
+ : Kubernetes.buildFromConfig(config.metadata, config.kubernetes);
+ this.jobs = config.jobs;
+ this.queue = Queue(this._queueRunner.bind(this), config.jobs.queue.concurrency);
+ this.queue.drain = this._onEmptyQueue.bind(this);
}
_onEmptyQueue() {
@@ -92,6 +44,7 @@ class Agent {
async _loadJobs() {
const ignorePaths = [(file, stats) => {
+
return !(new RegExp(/.*job.js/g).test(file)) && !stats.isDirectory();
}];
return Promise
@@ -100,32 +53,25 @@ class Agent {
.map(Job => this._startJob(Job));
}
- async _readFromVenonaConfDir(dir) {
- const runtimeRegexp = /.*\.runtime\.yaml/;
- const data = await Promise.fromCallback(cb => fs.readdir(dir, cb));
- const runtimes = await Promise.all(_.map(data, async(f) => {
- const fullPath = path.join(dir, f);
- const stat = await Promise.fromCallback(cb => fs.stat(fullPath, cb));
- if (stat.isDirectory()) {
- this.logger.warn(`Directory "${f}" ignored, Venona loading only files that are mached to regexp ${runtimeRegexp.toString()}`);
- return Promise.resolve();
- }
- if (runtimeRegexp.test(f)) {
- await Promise.fromCallback(cb => fs.access(fullPath, cb));
- const venonaConf = await Promise.fromCallback(cb => fs.readFile(fullPath, cb));
- return {
- ...yaml.safeLoad(venonaConf.toString()),
- file: fullPath,
- };
- } else {
- this.logger.warn(`File "${f}" ignored, Venona loading only files that are mached to regexp ${runtimeRegexp.toString()}`);
- return Promise.resolve();
- }
- }));
- return _.compact(runtimes);
- }
+ async init() {
+ try {
+ this.logger.info('Initializing agent');
+ await Promise.all([
+ this.server.init(),
+ this.codefreshAPI.init(),
+ this.kubernetesAPI.init(),
+ ]);
+ this.logger.info('All services has been initialized');
+ await this._loadJobs();
+ } catch(err) {
+ const message = `Failed to initialize agent with error message: ${err.message}`;
+ this.logger.error(message);
+ throw new Error(message);
+ }
+ }
+
_startJob(Job) {
const cron = _.get(this, `jobs.${Job.name}.cronExpression`, this.jobs.DEFAULT_CRON);
this.logger.info(`Preparing job: ${Job.name} with cron: ${cron}`);
@@ -135,7 +81,7 @@ class Agent {
job: Job.name,
uid: new Chance().guid(),
});
- const job = new Job(this.codefreshAPI, this.runtimes, taskLogger);
+ const job = new Job(this.codefreshAPI, this.kubernetesAPI, taskLogger);
this.logger.info(`Pushing job: ${Job.name} to queue`);
this.queue.push(job, 1, this._handleJobError(job));
});
diff --git a/config/index.js b/config/index.js
index 14382980..df518707 100644
--- a/config/index.js
+++ b/config/index.js
@@ -6,8 +6,7 @@ function build() {
return {
metadata: {
version,
- id: process.env.AGENT_ID,
- venonaConfDir: process.env.VENONA_CONFIG_DIR,
+ mode: process.env.AGENT_MODE,
},
logger: {
...(!process.env.LOGGER_MODE && {
@@ -21,9 +20,16 @@ function build() {
port: process.env.PORT || '9000',
},
kubernetes: {
+ config: {
+ url: process.env.KUBERNETES_HOST,
+ auth: {
+ bearer: process.env.KUBERNETES_AUTH_BEARER_TOKEN,
+ },
+ ca: process.env.KUBERNETES_CA_CERT,
+ },
metadata: {
name: process.env.SELF_POD_NAME,
- namespace: process.env.SELF_POD_NAMESPACE
+ namepsace: process.env.SELF_POD_NAMESPACE,
}
},
codefresh: {
diff --git a/constants.js b/constants.js
index 89879d46..8feb7b05 100644
--- a/constants.js
+++ b/constants.js
@@ -1,4 +1,7 @@
-
+const AGENT_MODES = {
+ // The agent will run inside a cluster as a pod
+ IN_CLUSTER: 'InCluster',
+};
const TASK_PRIORITY = {
HIGH: 1,
@@ -22,6 +25,7 @@ const CRON = {
};
module.exports = {
+ AGENT_MODES,
LOGGER_NAMESPACES,
LOGGER_MODES,
CRON,
diff --git a/index.js b/index.js
index 5b38a7c8..0906bdbe 100644
--- a/index.js
+++ b/index.js
@@ -1,11 +1,11 @@
const Agent = require('./agent');
const buildConfig = require('./config');
-const agent = new Agent();
+const agent = new Agent(buildConfig());
(async () => {
try {
- await agent.init(buildConfig());
+ await agent.init();
} catch (err) {
setTimeout(() => {
process.exit(1);
diff --git a/jobs/BaseJob.js b/jobs/BaseJob.js
index c34019a9..2dd907f1 100644
--- a/jobs/BaseJob.js
+++ b/jobs/BaseJob.js
@@ -1,9 +1,7 @@
-const _ = require('lodash');
-
class Job {
- constructor(codefreshAPI, runtimes, logger) {
+ constructor(codefreshAPI, kubernetesAPI, logger) {
this.codefreshAPI = codefreshAPI;
- this.runtimes = runtimes;
+ this.kubernetesAPI = kubernetesAPI;
this.logger = logger;
}
@@ -19,17 +17,6 @@ class Job {
async validate() {
throw new Error('not implemented');
}
-
- async getKubernetesService(runtime) {
- if (!_.has(this, `runtimes[${runtime}]`)) {
- throw new Error(`Kubernetes client for runtime "${runtime}" was not found`);
- }
- if (!_.has(this, `runtimes[${runtime}].kubernetesAPI`)) {
- const err = _.get(this, `runtimes[${runtime}].metadata.error`, '');
- throw new Error(`Kubernetes client for runtime "${runtime}" was not created due to error: ${err}`);
- }
- return this.runtimes[runtime].kubernetesAPI;
- }
}
module.exports = Job;
diff --git a/jobs/TaskPullerJob/TaskPuller.job.js b/jobs/TaskPullerJob/TaskPuller.job.js
index 01e04d03..0ab14893 100644
--- a/jobs/TaskPullerJob/TaskPuller.job.js
+++ b/jobs/TaskPullerJob/TaskPuller.job.js
@@ -57,7 +57,7 @@ class TaskPullerJob extends Base {
task: Task.name,
taskUid: new Chance().guid()
});
- const task = new Task(this.codefreshAPI, this.runtimes, logger);
+ const task = new Task(this.codefreshAPI, this.kubernetesAPI, logger);
return task.exec(taskSpec);
};
}
diff --git a/jobs/TaskPullerJob/tasks/CreatePod.task.js b/jobs/TaskPullerJob/tasks/CreatePod.task.js
index ace48ffa..50425ff7 100644
--- a/jobs/TaskPullerJob/tasks/CreatePod.task.js
+++ b/jobs/TaskPullerJob/tasks/CreatePod.task.js
@@ -1,6 +1,5 @@
const Joi = require('joi');
const Base = require('../../BaseJob');
-const _ = require('lodash');
const { TASK_PRIORITY } = require('../../../constants');
const ERROR_MESSAGES = {
@@ -11,8 +10,7 @@ class CreatePodTask extends Base {
async run(task) {
this.logger.info('Running CreatePod task');
try {
- const service = await this.getKubernetesService(_.get(task, 'metadata.reName'));
- const pod = await service.createPod(this.logger, task.spec);
+ const pod = await this.kubernetesAPI.createPod(this.logger, task.spec);
return pod;
} catch (err) {
const message = `${ERROR_MESSAGES.FAILED_TO_EXECUTE_TASK}: ${err.message}`;
diff --git a/jobs/TaskPullerJob/tasks/CreatePvc.task.js b/jobs/TaskPullerJob/tasks/CreatePvc.task.js
index 9f08221e..a939d74c 100644
--- a/jobs/TaskPullerJob/tasks/CreatePvc.task.js
+++ b/jobs/TaskPullerJob/tasks/CreatePvc.task.js
@@ -1,6 +1,5 @@
const Joi = require('joi');
const Base = require('../../BaseJob');
-const _ = require('lodash');
const { TASK_PRIORITY } = require('../../../constants');
const ERROR_MESSAGES = {
@@ -11,8 +10,7 @@ class CreatePvcTask extends Base {
async run(task) {
this.logger.info('Running CreatePvc task');
try {
- const service = await this.getKubernetesService(_.get(task, 'metadata.reName'));
- const pvc = await service.createPvc(this.logger, task.spec);
+ const pvc = await this.kubernetesAPI.createPvc(this.logger, task.spec);
return pvc;
} catch (err) {
const message = `${ERROR_MESSAGES.FAILED_TO_EXECUTE_TASK}: ${err.message}`;
diff --git a/jobs/TaskPullerJob/tasks/DeletePod.task.js b/jobs/TaskPullerJob/tasks/DeletePod.task.js
index 386e1355..41270f92 100644
--- a/jobs/TaskPullerJob/tasks/DeletePod.task.js
+++ b/jobs/TaskPullerJob/tasks/DeletePod.task.js
@@ -11,8 +11,7 @@ class DeletePodTask extends Base {
async run(task) {
this.logger.info('Running DeletePod task');
try {
- const service = await this.getKubernetesService(_.get(task, 'metadata.reName'));
- await service.deletePod(this.logger, task.spec.namespace, task.spec.name);
+ await this.kubernetesAPI.deletePod(this.logger, task.spec.namespace, task.spec.name);
} catch (err) {
// we treat 404 as if the operation succeeded
if (_.get(err, 'code') !== 404) {
diff --git a/jobs/TaskPullerJob/tasks/DeletePvc.task.js b/jobs/TaskPullerJob/tasks/DeletePvc.task.js
index c5f3b9ad..d45c8f77 100644
--- a/jobs/TaskPullerJob/tasks/DeletePvc.task.js
+++ b/jobs/TaskPullerJob/tasks/DeletePvc.task.js
@@ -11,8 +11,7 @@ class DeletePvcTask extends Base {
async run(task) {
this.logger.info('Running DeletePvc task');
try {
- const service = await this.getKubernetesService(_.get(task, 'metadata.reName'));
- await service.deletePvc(this.logger, task.spec.namespace, task.spec.name);
+ await this.kubernetesAPI.deletePvc(this.logger, task.spec.namespace, task.spec.name);
} catch (err) {
// we treat 404 as if the operation succeeded
if (_.get(err, 'code') !== 404) {
diff --git a/jobs/TaskPullerJob/tasks/__tests__/CreatePod.task.spec.js b/jobs/TaskPullerJob/tasks/__tests__/CreatePod.task.spec.js
index 6ba43464..33543bd2 100644
--- a/jobs/TaskPullerJob/tasks/__tests__/CreatePod.task.spec.js
+++ b/jobs/TaskPullerJob/tasks/__tests__/CreatePod.task.spec.js
@@ -14,16 +14,8 @@ describe('CreatePod task unit tests', () => {
const kubernetesAPIMock = {
createPod: jest.fn().mockRejectedValue(new Error('Error!!!')),
};
- const taskDef = {
- metadata: {
- reName: 'runtime'
- }
- };
- const task = new CreatePodTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const taskDef = {};
+ const task = new CreatePodTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.run(taskDef)).rejects.toThrowError('Failed to run task CreatePod: Error!!!');
});
});
@@ -37,16 +29,9 @@ describe('CreatePod task unit tests', () => {
createPod: spy,
};
const taskDef = {
- metadata: {
- reName: 'runtime'
- },
spec: {}
};
- const task = new CreatePodTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new CreatePodTask(_.noop(), kubernetesAPIMock, logger);
return task.run(taskDef)
.then(() => {
const loggerMacher = expect.objectContaining({
@@ -71,15 +56,10 @@ describe('CreatePod task unit tests', () => {
createPod: spy,
};
const taskDef = {
- metadata: {
- reName: 'runtime'
- },
+ runtime: {},
+ dockerDaemon: {},
};
- const task = new CreatePodTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new CreatePodTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.run(taskDef)).resolves.toEqual(spyResult);
});
diff --git a/jobs/TaskPullerJob/tasks/__tests__/CreatePvc.task.spec.js b/jobs/TaskPullerJob/tasks/__tests__/CreatePvc.task.spec.js
index 186f5cde..22e5e3f1 100644
--- a/jobs/TaskPullerJob/tasks/__tests__/CreatePvc.task.spec.js
+++ b/jobs/TaskPullerJob/tasks/__tests__/CreatePvc.task.spec.js
@@ -14,16 +14,8 @@ describe('CreatePvc task unit tests', () => {
const kubernetesAPIMock = {
createPvc: jest.fn().mockRejectedValue(new Error('Error!!!')),
};
- const taskDef = {
- metadata: {
- reName: 'runtime'
- }
- };
- const task = new CreatePvcTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const taskDef = {};
+ const task = new CreatePvcTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.run(taskDef)).rejects.toThrowError('Failed to run task CreatePvc: Error!!!');
});
@@ -31,16 +23,8 @@ describe('CreatePvc task unit tests', () => {
it('should throw error in case the task in not valid', () => {
const logger = createLogger();
const kubernetesAPIMock = {};
- const taskDef = {
- metadata: {
- reName: 'runtime'
- }
- };
- const task = new CreatePvcTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const taskDef = {};
+ const task = new CreatePvcTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.validate(taskDef)).rejects.toThrowError('child "spec" fails because ["spec" is required]');
});
});
@@ -55,16 +39,9 @@ describe('CreatePvc task unit tests', () => {
createPvc: spy,
};
const taskDef = {
- metadata: {
- reName: 'runtime'
- },
spec: {}
};
- const task = new CreatePvcTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new CreatePvcTask(_.noop(), kubernetesAPIMock, logger);
return task.run(taskDef)
.then(() => {
const loggerMacher = expect.objectContaining({
@@ -89,15 +66,10 @@ describe('CreatePvc task unit tests', () => {
createPvc: spy,
};
const taskDef = {
- metadata: {
- reName: 'runtime'
- }
+ runtime: {},
+ dockerDaemon: {},
};
- const task = new CreatePvcTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new CreatePvcTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.run(taskDef)).resolves.toEqual(spyResult);
});
diff --git a/jobs/TaskPullerJob/tasks/__tests__/DeletePod.task.spec.js b/jobs/TaskPullerJob/tasks/__tests__/DeletePod.task.spec.js
index 875c956b..f51ff62c 100644
--- a/jobs/TaskPullerJob/tasks/__tests__/DeletePod.task.spec.js
+++ b/jobs/TaskPullerJob/tasks/__tests__/DeletePod.task.spec.js
@@ -7,9 +7,6 @@ jest.mock('./../../../../services/Logger');
const getValidTaskDef = () => {
return {
- metadata: {
- reName: 'runtime'
- },
spec: {
namespace: 'namespace',
name: 'docker-daemon-name'
@@ -27,11 +24,7 @@ describe('DeletePod task unit tests', () => {
deletePod: jest.fn().mockRejectedValue(new Error('Error!!!')),
};
- const task = new DeletePodTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePodTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.exec(getValidTaskDef())).rejects.toThrowError('Failed to run task DeletePod: Error!!!');
});
@@ -45,11 +38,7 @@ describe('DeletePod task unit tests', () => {
const taskDef = getValidTaskDef();
delete taskDef.spec;
- const task = new DeletePodTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePodTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.exec(taskDef)).rejects.toThrowError('child "spec" fails because ["spec" is required]');
});
@@ -62,11 +51,7 @@ describe('DeletePod task unit tests', () => {
const taskDef = getValidTaskDef();
delete taskDef.spec.namespace;
- const task = new DeletePodTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePodTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.exec(taskDef)).rejects.toThrowError('child "spec" fails because [child "namespace" fails because ["namespace" is required]]');
});
@@ -79,11 +64,7 @@ describe('DeletePod task unit tests', () => {
const taskDef = getValidTaskDef();
delete taskDef.spec.name;
- const task = new DeletePodTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePodTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.exec(taskDef)).rejects.toThrowError('child "spec" fails because [child "name" fails because ["name" is required]]');
});
});
@@ -98,11 +79,7 @@ describe('DeletePod task unit tests', () => {
};
const taskDef = getValidTaskDef();
- const task = new DeletePodTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePodTask(_.noop(), kubernetesAPIMock, logger);
return task.exec(taskDef)
.then(() => {
const loggerMacher = expect.objectContaining({
@@ -122,11 +99,7 @@ describe('DeletePod task unit tests', () => {
deletePod: spy,
};
const taskDef = getValidTaskDef();
- const task = new DeletePodTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePodTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.exec(taskDef)).resolves.toEqual('OK');
});
@@ -139,11 +112,7 @@ describe('DeletePod task unit tests', () => {
};
const taskDef = getValidTaskDef();
- const task = new DeletePodTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePodTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.exec(taskDef)).resolves.toEqual('OK');
});
diff --git a/jobs/TaskPullerJob/tasks/__tests__/DeletePvc.task.spec.js b/jobs/TaskPullerJob/tasks/__tests__/DeletePvc.task.spec.js
index d882bdcd..75029909 100644
--- a/jobs/TaskPullerJob/tasks/__tests__/DeletePvc.task.spec.js
+++ b/jobs/TaskPullerJob/tasks/__tests__/DeletePvc.task.spec.js
@@ -7,9 +7,6 @@ jest.mock('./../../../../services/Logger');
const getValidTaskDef = () => {
return {
- metadata: {
- reName: 'runtime'
- },
spec: {
namespace: 'namespace',
name: 'docker-daemon-name'
@@ -27,11 +24,7 @@ describe('DeletePvc task unit tests', () => {
deletePvc: jest.fn().mockRejectedValue(new Error('Error!!!')),
};
- const task = new DeletePvcTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePvcTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.exec(getValidTaskDef())).rejects.toThrowError('Failed to run task DeletePvc: Error!!!');
});
@@ -45,11 +38,7 @@ describe('DeletePvc task unit tests', () => {
const taskDef = getValidTaskDef();
delete taskDef.spec;
- const task = new DeletePvcTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePvcTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.exec(taskDef)).rejects.toThrowError('child "spec" fails because ["spec" is required]');
});
@@ -62,11 +51,7 @@ describe('DeletePvc task unit tests', () => {
const taskDef = getValidTaskDef();
delete taskDef.spec.namespace;
- const task = new DeletePvcTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePvcTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.exec(taskDef)).rejects.toThrowError('child "spec" fails because [child "namespace" fails because ["namespace" is required]]');
});
@@ -79,11 +64,7 @@ describe('DeletePvc task unit tests', () => {
const taskDef = getValidTaskDef();
delete taskDef.spec.name;
- const task = new DeletePvcTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePvcTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.exec(taskDef)).rejects.toThrowError('child "spec" fails because [child "name" fails because ["name" is required]]');
});
});
@@ -98,11 +79,7 @@ describe('DeletePvc task unit tests', () => {
};
const taskDef = getValidTaskDef();
- const task = new DeletePvcTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePvcTask(_.noop(), kubernetesAPIMock, logger);
return task.exec(taskDef)
.then(() => {
const loggerMacher = expect.objectContaining({
@@ -122,11 +99,7 @@ describe('DeletePvc task unit tests', () => {
deletePvc: spy,
};
const taskDef = getValidTaskDef();
- const task = new DeletePvcTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePvcTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.exec(taskDef)).resolves.toEqual('OK');
});
@@ -139,11 +112,7 @@ describe('DeletePvc task unit tests', () => {
};
const taskDef = getValidTaskDef();
- const task = new DeletePvcTask(_.noop(), {
- 'runtime': {
- kubernetesAPI: kubernetesAPIMock,
- },
- }, logger);
+ const task = new DeletePvcTask(_.noop(), kubernetesAPIMock, logger);
return expect(task.exec(taskDef)).resolves.toEqual('OK');
});
diff --git a/jobs/__tests__/BaseJob.spec.js b/jobs/__tests__/BaseJob.spec.js
index ac44113c..21b5b56e 100644
--- a/jobs/__tests__/BaseJob.spec.js
+++ b/jobs/__tests__/BaseJob.spec.js
@@ -1,43 +1,20 @@
const _ = require('lodash');
-const Job = require('./../BaseJob');
+const BaseJob = require('./../BaseJob');
const { create: createLogger } = require('../../services/Logger');
jest.mock('./../../services/Logger');
describe('BaseJob unit tests', () => {
- it('Should construct', () => {
- const job = new Job(_.noop(), _.noop(), createLogger());
- expect(Object.keys(job).sort()).toEqual(['codefreshAPI', 'runtimes', 'logger'].sort());
+ describe('positive', () => {
+ it('Should construct', () => {
+ const task = new BaseJob(_.noop(), _.noop(), createLogger());
+ expect(Object.keys(task).sort()).toEqual(['codefreshAPI', 'kubernetesAPI', 'logger'].sort());
+ });
});
- it('Should return the requested runtime', async () => {
- const kubernetesAPI = {};
- const runtimes = {
- 'runtime': {
- name: 'runtime',
- kubernetesAPI,
- },
- };
- const job = new Job(_.noop(), runtimes, createLogger());
- await expect(job.getKubernetesService('runtime')).resolves.toEqual(kubernetesAPI);
- });
+ describe('negative', () => {
- it('Should throw an error in case the runtime was not found', async () => {
- const runtimes = {};
- const job = new Job(_.noop(), runtimes, createLogger());
- await expect(job.getKubernetesService('runtime')).rejects.toThrowError('Kubernetes client for runtime "runtime" was not found');
});
- it('Should throw an error in case the runtime\'s KubernetesAPI was not initialized', async () => {
- const runtimes = {
- 'runtime': {
- metadata: {
- error: 'failed to initialize runtime'
- }
- }
- };
- const job = new Job(_.noop(), runtimes, createLogger());
- await expect(job.getKubernetesService('runtime')).rejects.toThrowError('Kubernetes client for runtime "runtime" was not created due to error: failed to initialize runtime');
- });
});
diff --git a/package.json b/package.json
index cf32b062..84be3f9d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "venona",
- "version": "1.0.2",
+ "version": "0.30.3",
"description": "Codefresh agent to run on Codefresh's runtime environment and execute pipeline",
"main": "index.js",
"scripts": {
@@ -16,9 +16,8 @@
"chance": "^1.0.16",
"express": "^4.16.4",
"joi": "^14.3.1",
- "js-yaml": "^3.13.1",
"kubernetes-client": "6.4.0",
- "lodash": "^4.17.15",
+ "lodash": "^4.17.11",
"node-schedule": "^1.3.0",
"pino": "^5.9.0",
"pino-pretty": "^2.2.4",
diff --git a/scripts/migration.sh b/scripts/migration.sh
deleted file mode 100755
index c32354c3..00000000
--- a/scripts/migration.sh
+++ /dev/null
@@ -1,90 +0,0 @@
-# This script comes to migrate old versions of Venona installation ( version < 1.x.x ) to new version (version >= 1.0.0 )
-# Please read carefully what the script does.
-# There will be a "downtime" in terms of your builds targeted to this runtime environment
-# Once the script is finished, all the builds during the downtime will start
-# The script will:
-# 1. Create new agent entity in Codefresh using Codefresh CLI - give it a name $CODEFRESH_AGENT_NAME, default is "codefresh"
-# 2. Install the agent on you cluster pass variables:
-# a. $VENONA_KUBE_NAMESPACE - required
-# b. $VENONA_KUBE_CONTEXT - default is current-context
-# c. $VENONA_KUBECONFIG_PATH - default is $HOME/.kube/config
-# 3. Attach runtime to the new agent (downtime ends) - pass $CODEFRESH_RUNTIME_NAME - required
-
-set -e
-
-echoAndRun() {
- info "Running command: $1"
- eval $1
-}
-
-info() { echo "INFO [$(date)] ---> $1"; }
-fatal() { echo "ERROR [$(date)] ---> $1" ; exit 1; }
-
-
-DEFAULT_KUBECONFIG="$HOME/.kube/config"
-
-
-if [ -z "$CODEFRESH_AGENT_NAME" ]
-then
- info "CODEFRESH_AGENT_NAME is not set, using default name: codefresh"
- CODEFRESH_AGENT_NAME="codefresh"
-else
- info "CODEFRESH_AGENT_NAME is set to $CODEFRESH_AGENT_NAME"
-fi
-
-if [ -z "$CODEFRESH_RUNTIME_NAME" ]
-then
- fatal "CODEFRESH_RUNTIME_NAME is not set, exiting"
-fi
-
-if [ -z "$VENONA_KUBE_NAMESPACE" ]
-then
- fatal "VENONA_KUBE_NAMESPACE is not set, exiting"
-fi
-
-if [ -z "$VENONA_KUBECONFIG_PATH" ]
-then
- info "VENONA_KUBECONFIG_PATH is not set, using \$KUBECONFIG if exist or $DEFAULT_KUBECONFIG"
- VENONA_KUBECONFIG_PATH=${KUBECONFIG:=$DEFAULT_KUBECONFIG}
- info "VENONA_KUBECONFIG_PATH=$VENONA_KUBECONFIG_PATH"
-else
- info "VENONA_KUBECONFIG_PATH is set to $VENONA_KUBECONFIG_PATH"
-fi
-if [ -z "$VENONA_KUBE_CONTEXT" ]
-then
- info "VENONA_KUBE_CONTEXT is not set, using current-context"
- VENONA_KUBE_CONTEXT=$(kubectl --kubeconfig $VENONA_KUBECONFIG_PATH config current-context)
- info "VENONA_KUBE_CONTEXT=$VENONA_KUBE_CONTEXT"
-else
- info "VENONA_KUBE_CONTEXT is set to $VENONA_KUBE_CONTEXT"
-fi
-
-
-
-kube="kubectl --kubeconfig $VENONA_KUBECONFIG_PATH --cluster $VENONA_KUBE_CONTEXT -n $VENONA_KUBE_NAMESPACE"
-
-info "Testing connection to runtime cluster"
-runtimeTestCmd="$kube get deploy venona"
-echoAndRun "$runtimeTestCmd"
-
-info "Crating new agent in Codefresh"
-token=$(echoAndRun "codefresh create agent $CODEFRESH_AGENT_NAME" | awk 'FNR==3')
-
-info "Deleting current Venona process"
-pod=$(eval "$kube get pods -l app=venona -o go-template='{{range .items }}{{ .metadata.name }}{{end}}'")
-echoAndRun "$kube delete deploy --wait=true venona"
-echoAndRun "$kube wait --for=delete pod/$pod --timeout 60s"
-echoAndRun "$kube delete secret venona"
-
-info "Installing agent on namespace using token $token"
-echoAndRun "codefresh install agent --token $token --kube-namespace $VENONA_KUBE_NAMESPACE --kube-context-name $VENONA_KUBE_CONTEXT --kube-config-path $VENONA_KUBECONFIG_PATH --verbose"
-
-info "Attaching old runtime to new agent"
-pod=$(eval "$kube get pods -l app=venona -o go-template='{{range .items }}{{ .metadata.name }}{{end}}'")
-echoAndRun "codefresh attach runtime --runtime-name $CODEFRESH_RUNTIME_NAME --agent-name $CODEFRESH_AGENT_NAME --runtime-kube-context-name $VENONA_KUBE_CONTEXT --agent-kube-context-name $VENONA_KUBE_CONTEXT --runtime-kube-namespace $VENONA_KUBE_NAMESPACE --agent-kube-namespace $VENONA_KUBE_NAMESPACE --agent-kube-config-path $VENONA_KUBECONFIG_PATH --runtime-kube-config-path $VENONA_KUBECONFIG_PATH --restart-agent --verbose"
-echoAndRun "$kube wait --for=delete pod/$pod --timeout 60s"
-
-pod=$(eval "$kube get pods -l app=venona -o go-template='{{range .items }}{{ .metadata.name }}{{end}}'")
-echoAndRun "$kube wait --for=condition=Ready pod/$pod --timeout 60s"
-
-info "Migration finished"
diff --git a/services/Codefresh.js b/services/Codefresh.js
index d73b1141..ab3baba4 100644
--- a/services/Codefresh.js
+++ b/services/Codefresh.js
@@ -11,7 +11,6 @@ class Codefresh {
constructor(metadata, options) {
this.options = options;
this.metadata = metadata;
- this.agentId = this.metadata.id;
this.defaults = {
baseUrl: utils.getPropertyOrError(options, 'baseURL', ERROR_MESSAGES.MISSING_BASE_URL),
headers: {
@@ -34,7 +33,7 @@ class Codefresh {
pullTasks(logger) {
logger.info('Calling Codefresh API to fetch jobs');
- const url = `/api/agent/${this.agentId}/tasks`;
+ const url = '/api/agent/tasks';
return this._call({
url,
method: 'GET',
@@ -43,7 +42,7 @@ class Codefresh {
reportStatus(logger, status) {
logger.info({ status }, 'Calling Codefresh API to report status');
- const url = `/api/agent/${this.agentId}/status`;
+ const url = '/api/agent/status';
return this._call({
url,
method: 'PUT',
diff --git a/services/Kubernetes.js b/services/Kubernetes.js
index ea31ebb1..a1e56a2a 100644
--- a/services/Kubernetes.js
+++ b/services/Kubernetes.js
@@ -1,13 +1,10 @@
-const { Client } = require('kubernetes-client');
+const { Client, config } = require('kubernetes-client');
const utils = require('./../utils');
const ERROR_MESSAGES = {
MISSING_KUBERNETES_URL: 'Failed to construct Kubernetes API service, missing Kubernetes URL',
MISSING_KUBERNETES_BEARER_TOKEN: 'Failed to construct Kubernetes API service, missing Kubernetes bearer token',
MISSING_KUBERNETES_CA_CERTIFICATE: 'Failed to construct Kubernetes API service, missing Kubernetes ca certificate',
- MISSING_NAMESPACE: 'Failed to get Kubernetes namespace',
- MISSING_VENONA_CONF: 'Failed to read venona configuration',
-
FAILED_TO_INIT: 'Failed to complete Kubernetes service initialization',
FAILED_TO_CREATE_POD: 'Failed to create Kubernetes pod',
FAILED_TO_DELETE_POD: 'Failed to delete Kubernetes pod',
@@ -15,14 +12,18 @@ const ERROR_MESSAGES = {
FAILED_TO_DELETE_PVC: 'Failed to delete Kubernetes pvc',
};
+
class Kubernetes {
- // Do not use this constructor, use Kubernetes.buildFromConfig
- // to create new instance
constructor(metadata, client) {
this.metadata = metadata;
this.client = client;
}
+ static buildFromInCluster(metadata) {
+ const client = new Client({ config: config.getInCluster() });
+ return new this(metadata, client);
+ }
+
static buildFromConfig(metadata, options) {
const url = utils.getPropertyOrError(options, 'config.url', ERROR_MESSAGES.MISSING_KUBERNETES_URL);
const bearer = utils.getPropertyOrError(options, 'config.auth.bearer', ERROR_MESSAGES.MISSING_KUBERNETES_BEARER_TOKEN);
@@ -31,9 +32,9 @@ class Kubernetes {
config: {
url,
auth: {
- bearer
+ bearer: Buffer.from(bearer, 'base64'),
},
- ca
+ ca: Buffer.from(ca, 'base64'),
},
});
return new this(metadata, client);
diff --git a/services/__mocks__/Logger.js b/services/__mocks__/Logger.js
index 527d1de4..a01c84d1 100644
--- a/services/__mocks__/Logger.js
+++ b/services/__mocks__/Logger.js
@@ -2,7 +2,6 @@
const create = jest.fn(() => ({
info: jest.fn(),
- warn: jest.fn(),
child: jest.fn(create),
error: jest.fn(),
}));
diff --git a/services/__tests__/Codefresh.spec.js b/services/__tests__/Codefresh.spec.js
index 4d2939a3..6108e832 100644
--- a/services/__tests__/Codefresh.spec.js
+++ b/services/__tests__/Codefresh.spec.js
@@ -5,7 +5,7 @@ const { create: createLogger } = require('./../../services/Logger');
jest.mock('request-promise');
jest.mock('./../../services/Logger');
-const getFakeMetadata = () => ({ name: 'unit-test', id: 'fake-agent-id' });
+const getFakeMetadata = () => ({ name: 'unit-test' });
const getFakeConfig = () => ({ baseURL: 'fake-url', token: 'fake-token' });
@@ -19,7 +19,7 @@ describe('Codefresh API unit tests', () => {
it('Should set values on this', () => {
const api = createCodefreshAPI();
- expect(Object.keys(api)).toStrictEqual(['options', 'metadata', 'agentId', 'defaults']);
+ expect(Object.keys(api)).toStrictEqual(['options', 'metadata', 'defaults']);
});
});
@@ -94,7 +94,7 @@ describe('Codefresh API unit tests', () => {
return createCodefreshAPI()
.pullTasks(createLogger(getFakeMetadata()))
.then(() => {
- expect(spy.mock.calls[0][0]).toHaveProperty('url', '/api/agent/fake-agent-id/tasks');
+ expect(spy.mock.calls[0][0]).toHaveProperty('url', '/api/agent/tasks');
});
});
});
@@ -110,7 +110,7 @@ describe('Codefresh API unit tests', () => {
},
})
.then(() => {
- expect(spy.mock.calls[0][0]).toHaveProperty('url', '/api/agent/fake-agent-id/status');
+ expect(spy.mock.calls[0][0]).toHaveProperty('url', '/api/agent/status');
expect(spy.mock.calls[0][0]).toHaveProperty('method', 'PUT');
expect(spy.mock.calls[0][0]).toHaveProperty('body');
});
diff --git a/services/__tests__/Kubernetes.spec.js b/services/__tests__/Kubernetes.spec.js
index 195456f4..4596ad4c 100644
--- a/services/__tests__/Kubernetes.spec.js
+++ b/services/__tests__/Kubernetes.spec.js
@@ -33,7 +33,14 @@ describe('Kubernetes API unit tests', () => {
expect(paramsToConstructor).toHaveProperty('config.url');
});
- it('Should throw error when url is not given', () => expect(() => Kubernetes.buildFromConfig(getFakeMetadata(), { config: {} })).toThrow('Failed to construct Kubernetes API service, missing Kubernetes URL'));
+ it('Should construct form in-cluster', () => {
+ Kubernetes.buildFromInCluster();
+ const callToClientConstructor = kube.Client.prototype.constructor.mock.calls;
+ expect(callToClientConstructor).toHaveLength(1);
+ expect(callToClientConstructor[0][0]).toHaveProperty('config');
+ });
+
+ it('Should throw error when url is not given', () => expect(() => Kubernetes.buildFromConfig(getFakeMetadata(), { config: {} })).toThrow('Failed to construct Kubernetes API service, '));
it('Should throw error when bearer token is not given', () => expect(() => Kubernetes.buildFromConfig(getFakeMetadata(), { config: { url: 'ok' } })).toThrow('Failed to construct Kubernetes API service, missing Kubernetes bearer token'));
diff --git a/venonactl/VERSION b/venonactl/VERSION
index 6d7de6e6..e8262eb5 100644
--- a/venonactl/VERSION
+++ b/venonactl/VERSION
@@ -1 +1 @@
-1.0.2
+0.30.3
diff --git a/venonactl/cmd/attach.go b/venonactl/cmd/attach.go
deleted file mode 100644
index 6ad912bb..00000000
--- a/venonactl/cmd/attach.go
+++ /dev/null
@@ -1,125 +0,0 @@
-package cmd
-
-/*
-Copyright 2019 The Codefresh Authors.
-
-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.
-*/
-
-import (
- "github.com/codefresh-io/venona/venonactl/pkg/plugins"
- "github.com/codefresh-io/venona/venonactl/pkg/store"
- "github.com/spf13/cobra"
- "github.com/spf13/viper"
-)
-
-var attachRuntimeCmdOptions struct {
- runtimeEnvironmentName string
- kube struct {
- namespace string
- inCluster bool
- context string
- kubePath string
- serviceAccount string
- }
- kubeVenona struct {
- namespace string
- kubePath string
- context string
- }
- restartAgent bool
-}
-
-var attachRuntimeCmd = &cobra.Command{
- Use: "attach",
- Short: "Attach Codefresh runtime to agent",
- Run: func(cmd *cobra.Command, args []string) {
-
- s := store.GetStore()
- lgr := createLogger("Attach-runtime", verbose)
- buildBasicStore(lgr)
- extendStoreWithKubeClient(lgr)
-
- s.CodefreshAPI = &store.CodefreshAPI{}
- s.AgentAPI = &store.AgentAPI{}
-
- if attachRuntimeCmdOptions.kubeVenona.kubePath == "" {
- attachRuntimeCmdOptions.kubeVenona.kubePath = kubeConfigPath
- }
- if attachRuntimeCmdOptions.kubeVenona.namespace == "" {
- attachRuntimeCmdOptions.kubeVenona.namespace = attachRuntimeCmdOptions.kube.namespace
- }
- if attachRuntimeCmdOptions.kubeVenona.context == "" {
- attachRuntimeCmdOptions.kubeVenona.context = attachRuntimeCmdOptions.kube.context
- }
-
- attachRuntimeCmdOptions.kube.serviceAccount = "venona"
-
- if attachRuntimeCmdOptions.kube.kubePath == "" {
- attachRuntimeCmdOptions.kube.kubePath = kubeConfigPath
- }
-
- fillKubernetesAPI(lgr, attachRuntimeCmdOptions.kubeVenona.context, attachRuntimeCmdOptions.kubeVenona.namespace, false)
-
- builder := plugins.NewBuilder(lgr)
-
- builderInstallOpt := &plugins.InstallOptions{
- ClusterNamespace: attachRuntimeCmdOptions.kubeVenona.namespace,
- RuntimeEnvironment: attachRuntimeCmdOptions.runtimeEnvironmentName,
- RuntimeClusterName: attachRuntimeCmdOptions.kube.namespace,
- RuntimeServiceAccount: attachRuntimeCmdOptions.kube.serviceAccount,
- RestartAgent: attachRuntimeCmdOptions.restartAgent,
- }
-
- // runtime
- builderInstallOpt.KubeBuilder = getKubeClientBuilder(attachRuntimeCmdOptions.kube.context, attachRuntimeCmdOptions.kube.namespace, attachRuntimeCmdOptions.kube.kubePath, false)
-
- // agent
- builderInstallOpt.AgentKubeBuilder = getKubeClientBuilder(attachRuntimeCmdOptions.kubeVenona.context,
- attachRuntimeCmdOptions.kubeVenona.namespace,
- attachRuntimeCmdOptions.kubeVenona.kubePath,
- false)
-
- builder.Add(plugins.RuntimeAttachType)
-
- var err error
- values := s.BuildValues()
- for _, p := range builder.Get() {
- values, err = p.Install(builderInstallOpt, values)
- if err != nil {
- dieOnError(err)
- }
- }
- lgr.Info("Attach to runtime completed Successfully")
-
- },
-}
-
-func init() {
- rootCmd.AddCommand(attachRuntimeCmd)
- viper.BindEnv("kube-namespace", "KUBE_NAMESPACE")
- viper.BindEnv("kube-context", "KUBE_CONTEXT")
-
- attachRuntimeCmd.Flags().StringVar(&attachRuntimeCmdOptions.kube.namespace, "kube-namespace", viper.GetString("kube-namespace"), "Name of the namespace on which venona should be installed [$KUBE_NAMESPACE]")
- attachRuntimeCmd.Flags().StringVar(&attachRuntimeCmdOptions.kube.context, "kube-context-name", viper.GetString("kube-context"), "Name of the kubernetes context on which venona should be installed (default is current-context) [$KUBE_CONTEXT]")
- attachRuntimeCmd.Flags().StringVar(&attachRuntimeCmdOptions.kube.kubePath, "kube-config-path", viper.GetString("kubeconfig"), "Path to kubeconfig file (default is $HOME/.kube/config) [$KUBECONFIG]")
-
- attachRuntimeCmd.Flags().StringVar(&attachRuntimeCmdOptions.runtimeEnvironmentName, "runtime-name", viper.GetString("runtime-name"), "Name of the runtime as in codefresh")
-
- attachRuntimeCmd.Flags().StringVar(&attachRuntimeCmdOptions.kubeVenona.namespace, "kube-namespace-agent", viper.GetString("kube-namespace-agent"), "Name of the namespace where venona is installed [$KUBE_NAMESPACE]")
- attachRuntimeCmd.Flags().StringVar(&attachRuntimeCmdOptions.kubeVenona.context, "kube-context-name-agent", viper.GetString("kube-context-agent"), "Name of the kubernetes context on which venona is installed (default is current-context) [$KUBE_CONTEXT]")
- attachRuntimeCmd.Flags().StringVar(&attachRuntimeCmdOptions.kubeVenona.kubePath, "kube-config-path-agent", viper.GetString("kubeconfig-agent"), "Path to kubeconfig file (default is $HOME/.kube/config) for agent [$KUBECONFIG]")
- attachRuntimeCmd.Flags().BoolVar(&attachRuntimeCmdOptions.restartAgent, "restart-agent", viper.GetBool("restart-agent"), "Restart agent after attach operation")
-
-
-}
diff --git a/venonactl/cmd/cmdutils.go b/venonactl/cmd/cmdutils.go
index 17c441d5..03ac0e3b 100644
--- a/venonactl/cmd/cmdutils.go
+++ b/venonactl/cmd/cmdutils.go
@@ -1,17 +1,12 @@
package cmd
import (
- "encoding/base64"
- "errors"
"fmt"
- "io/ioutil"
"os"
"os/user"
"path"
"strings"
- "encoding/json"
-
"github.com/codefresh-io/go-sdk/pkg/codefresh"
sdkUtils "github.com/codefresh-io/go-sdk/pkg/utils"
"github.com/codefresh-io/venona/venonactl/pkg/certs"
@@ -20,9 +15,6 @@ import (
"github.com/codefresh-io/venona/venonactl/pkg/plugins"
"github.com/codefresh-io/venona/venonactl/pkg/store"
"github.com/olekukonko/tablewriter"
- "gopkg.in/yaml.v2"
- k8sApi "k8s.io/api/core/v1"
- "k8s.io/client-go/tools/clientcmd"
)
var (
@@ -187,78 +179,3 @@ func createLogger(command string, verbose bool) logger.Logger {
LogToFile: logFile,
})
}
-
-type nodeSelector map[string]string
-
-func parseNodeSelector(s string) (nodeSelector, error) {
- if s == "" {
- return nodeSelector{}, nil
- }
- v := strings.Split(s, "=")
- if len(v) != 2 {
- return nil, errors.New("node selector must be in form \"key=value\"")
- }
- return nodeSelector{v[0]: v[1]}, nil
-}
-
-func loadTolerationsFromFile(filename string) string {
- data, err := ioutil.ReadFile(filename)
- if err != nil {
- dieOnError(err)
- }
-
- return string(data)
-}
-
-func parseTolerations(s string) (string, error) {
- if s == "" {
- return "", nil
- }
- var data []k8sApi.Toleration
- err := json.Unmarshal([]byte(s), &data)
- if err != nil {
- return "", fmt.Errorf("can not parse tolerations: %s", err)
- }
- y, err := yaml.Marshal(&data)
- if err != nil {
- return "", fmt.Errorf("can not marshel tolerations to yaml: %s", err)
- }
- d := fmt.Sprintf("\n%s", string(y))
- return d, nil
-}
-
-func fillKubernetesAPI(lgr logger.Logger, context string, namespace string, inCluster bool) {
-
- s := store.GetStore()
- if context == "" {
- config := clientcmd.GetConfigFromFileOrDie(s.KubernetesAPI.ConfigPath)
- context = config.CurrentContext
- lgr.Debug("Kube Context is not set, using current context", "Kube-Context-Name", context)
- }
- if namespace == "" {
- namespace = "default"
- }
-
- s.KubernetesAPI.InCluster = inCluster
- s.KubernetesAPI.ContextName = context
- s.KubernetesAPI.Namespace = namespace
-
-}
-
-func extendStoreWithAgentAPI(logger logger.Logger, token string, agentID string) {
- s := store.GetStore()
- logger.Debug("Using agent's token", "Token", token)
- s.AgentAPI = &store.AgentAPI{
- Token: base64.StdEncoding.EncodeToString([]byte(token)),
- Id: agentID,
- }
-}
-
-// String returns a k8s compliant string representation of the nodeSelector. Only a single value is supported.
-func (ns nodeSelector) String() string {
- var s string
- for k, v := range ns {
- s = fmt.Sprintf("%s: %s", k, v)
- }
- return s
-}
diff --git a/venonactl/cmd/delete.go b/venonactl/cmd/delete.go
new file mode 100644
index 00000000..3a708087
--- /dev/null
+++ b/venonactl/cmd/delete.go
@@ -0,0 +1,129 @@
+package cmd
+
+/*
+Copyright 2019 The Codefresh Authors.
+
+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.
+*/
+
+import (
+ "errors"
+ "fmt"
+ "os"
+
+ "github.com/codefresh-io/venona/venonactl/pkg/store"
+
+ "github.com/codefresh-io/venona/venonactl/pkg/plugins"
+ "github.com/spf13/cobra"
+)
+
+type DeletionError struct {
+ err error
+ operation string
+ name string
+}
+
+var deleteCmdOptions struct {
+ kube struct {
+ inCluster bool
+ context string
+ }
+ revertTo string
+}
+
+// deleteCmd represents the status command
+var deleteCmd = &cobra.Command{
+ Use: "delete [names]",
+ Short: "Delete a Codefresh's runtime-environment",
+ Args: func(cmd *cobra.Command, args []string) error {
+ if len(args) < 1 {
+ return errors.New("requires name of the runtime-environment")
+ }
+ return nil
+ },
+ Run: func(cmd *cobra.Command, args []string) {
+ s := store.GetStore()
+ lgr := createLogger("Delete", verbose)
+ buildBasicStore(lgr)
+ extendStoreWithCodefershClient(lgr)
+ extendStoreWithKubeClient(lgr)
+ var errors []DeletionError
+ s.KubernetesAPI.InCluster = deleteCmdOptions.kube.inCluster
+ for _, name := range args {
+ builder := plugins.NewBuilder(lgr)
+
+ re, err := s.CodefreshAPI.Client.RuntimeEnvironments().Get(name)
+ errors = collectError(errors, err, name)
+
+ if deleteCmdOptions.revertTo != "" {
+ _, err := s.CodefreshAPI.Client.RuntimeEnvironments().Default(deleteCmdOptions.revertTo)
+ errors = collectError(errors, err, name)
+ }
+ deleted, err := s.CodefreshAPI.Client.RuntimeEnvironments().Delete(name)
+ errors = collectError(errors, err, name)
+ deleteOptions := &plugins.DeleteOptions{}
+ if deleted {
+ contextName := re.RuntimeScheduler.Cluster.ClusterProvider.Selector
+ if contextName != "" {
+ contextName = deleteCmdOptions.kube.context
+ }
+ s.KubernetesAPI.ContextName = contextName
+ s.KubernetesAPI.Namespace = re.RuntimeScheduler.Cluster.Namespace
+
+ builder.Add(plugins.RuntimeEnvironmentPluginType)
+ if isUsingDefaultStorageClass(re.RuntimeScheduler.Pvcs.Dind.StorageClassName) {
+ builder.Add(plugins.VolumeProvisionerPluginType)
+ }
+
+ if re.Metadata.Agent {
+ builder.Add(plugins.VenonaPluginType)
+ }
+
+ deleteOptions.KubeBuilder = getKubeClientBuilder(contextName, s.KubernetesAPI.Namespace, s.KubernetesAPI.ConfigPath, s.KubernetesAPI.InCluster)
+ deleteOptions.ClusterNamespace = re.RuntimeScheduler.Cluster.Namespace
+ for _, p := range builder.Get() {
+ err := p.Delete(deleteOptions, s.BuildValues())
+ collectError(errors, err, name)
+ }
+
+ lgr.Info("Deletion completed", "Name", name)
+ }
+
+ }
+
+ if len(errors) > 0 {
+ for _, e := range errors {
+ lgr.Error(fmt.Sprintf("Error %s", e.err.Error()), "Name", e.name, "Operation", e.operation)
+ }
+ os.Exit(1)
+ }
+ lgr.Info("Deletion completed")
+ },
+}
+
+func init() {
+ rootCmd.AddCommand(deleteCmd)
+ deleteCmd.Flags().StringVar(&deleteCmdOptions.kube.context, "kube-context-name", "", "Set name to overwrite the context name saved in Codefresh")
+ deleteCmd.Flags().StringVar(&deleteCmdOptions.revertTo, "revert-to", "", "Set to the name of the runtime-environment to set as default")
+ deleteCmd.Flags().BoolVar(&deleteCmdOptions.kube.inCluster, "in-cluster", false, "Set flag if venona is been installed from inside a cluster")
+}
+
+func collectError(errors []DeletionError, err error, reName string) []DeletionError {
+ if err == nil {
+ return errors
+ }
+ return append(errors, DeletionError{
+ err: err,
+ name: reName,
+ })
+}
diff --git a/venonactl/cmd/install-agent.go b/venonactl/cmd/install-agent.go
deleted file mode 100644
index 0a311a28..00000000
--- a/venonactl/cmd/install-agent.go
+++ /dev/null
@@ -1,152 +0,0 @@
-package cmd
-
-/*
-Copyright 2019 The Codefresh Authors.
-
-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.
-*/
-
-import (
- "fmt"
-
- "github.com/codefresh-io/venona/venonactl/pkg/store"
- "github.com/codefresh-io/venona/venonactl/pkg/plugins"
- "github.com/codefresh-io/venona/venonactl/pkg/logger"
- "github.com/spf13/cobra"
- "github.com/spf13/viper"
-)
-
-var installAgentCmdOptions struct {
- dryRun bool
- kube struct {
- namespace string
- inCluster bool
- context string
- nodeSelector string
- }
- venona struct {
- version string
- }
- agentToken string
- agentID string
- kubernetesRunnerType bool
- tolerations string
-}
-
-var installAgentCmd = &cobra.Command{
- Use: "agent",
- Short: "Install Codefresh's agent ",
- Run: func(cmd *cobra.Command, args []string) {
- s := store.GetStore()
- lgr := createLogger("Install-agent", verbose)
- buildBasicStore(lgr)
- extendStoreWithAgentAPI(lgr, installAgentCmdOptions.agentToken, installAgentCmdOptions.agentID)
- extendStoreWithKubeClient(lgr)
- fillCodefreshAPI(lgr)
- builder := plugins.NewBuilder(lgr)
-
- if cfAPIHost == "" {
- cfAPIHost = "https://g.codefresh.io"
- }
- builderInstallOpt := &plugins.InstallOptions{
- CodefreshHost: cfAPIHost,
- }
-
- if installAgentCmdOptions.agentToken == "" {
- dieOnError(fmt.Errorf("Agent token is required in order to install agent"))
- }
-
- if installAgentCmdOptions.agentID == "" {
- dieOnError(fmt.Errorf("Agent id is required in order to install agent"))
- }
-
- fillKubernetesAPI(lgr, installAgentCmdOptions.kube.context, installAgentCmdOptions.kube.namespace, false)
-
- if installAgentCmdOptions.tolerations != "" {
- var tolerationsString string
-
- if installAgentCmdOptions.tolerations[0] == '@' {
- tolerationsString = loadTolerationsFromFile(installAgentCmdOptions.tolerations[1:])
- } else {
- tolerationsString = installAgentCmdOptions.tolerations
- }
-
- tolerations, err := parseTolerations(tolerationsString)
- if err != nil {
- dieOnError(err)
- }
-
- s.KubernetesAPI.Tolerations = tolerations
- }
-
- if installAgentCmdOptions.venona.version != "" {
- version := installAgentCmdOptions.venona.version
- lgr.Info("Version set manually", "version", version)
- s.Image.Tag = version
- s.Version.Latest.Version = version
- }
-
-
- kns, err := parseNodeSelector(installAgentCmdOptions.kube.nodeSelector)
- if err != nil {
- dieOnError(err)
- }
- s.KubernetesAPI.NodeSelector = kns.String()
-
- builderInstallOpt.ClusterName = s.KubernetesAPI.ContextName
- builderInstallOpt.KubeBuilder = getKubeClientBuilder(builderInstallOpt.ClusterName, s.KubernetesAPI.Namespace, s.KubernetesAPI.ConfigPath, s.KubernetesAPI.InCluster)
- builderInstallOpt.ClusterNamespace = s.KubernetesAPI.Namespace
-
-
- builder.Add(plugins.VenonaPluginType)
-
- values := s.BuildValues()
- for _, p := range builder.Get() {
- values, err = p.Install(builderInstallOpt, values)
- if err != nil {
- dieOnError(err)
- }
- }
- lgr.Info("Agent installation completed Successfully")
-
- },
-
-}
-
-func init() {
- installCommand.AddCommand(installAgentCmd)
-
- viper.BindEnv("kube-namespace", "KUBE_NAMESPACE")
- viper.BindEnv("kube-context", "KUBE_CONTEXT")
- installAgentCmd.Flags().StringVar(&installAgentCmdOptions.agentToken, "agentToken", "", "Agent token created by codefresh")
- installAgentCmd.Flags().StringVar(&installAgentCmdOptions.agentID, "agentId", "", "Agent id created by codefresh")
- installAgentCmd.Flags().StringVar(&installAgentCmdOptions.venona.version, "venona-version", "", "Version of venona to install (default is the latest)")
- installAgentCmd.Flags().StringVar(&installAgentCmdOptions.kube.namespace, "kube-namespace", viper.GetString("kube-namespace"), "Name of the namespace on which venona should be installed [$KUBE_NAMESPACE]")
- installAgentCmd.Flags().StringVar(&installAgentCmdOptions.kube.context, "kube-context-name", viper.GetString("kube-context"), "Name of the kubernetes context on which venona should be installed (default is current-context) [$KUBE_CONTEXT]")
- installAgentCmd.Flags().StringVar(&installAgentCmdOptions.kube.nodeSelector, "kube-node-selector", "", "The kubernetes node selector \"key=value\" to be used by venona resources (default is no node selector)")
- installAgentCmd.Flags().StringVar(&installAgentCmdOptions.tolerations, "tolerations", "", "The kubernetes tolerations as JSON string to be used by venona resources (default is no tolerations)")
-
- installAgentCmd.Flags().BoolVar(&installAgentCmdOptions.kube.inCluster, "in-cluster", false, "Set flag if venona is been installed from inside a cluster")
- installAgentCmd.Flags().BoolVar(&installAgentCmdOptions.dryRun, "dry-run", false, "Set to true to simulate installation")
- installAgentCmd.Flags().BoolVar(&installAgentCmdOptions.kubernetesRunnerType, "kubernetes-runner-type", false, "Set the runner type to kubernetes (alpha feature)")
-}
-
-
-
-func fillCodefreshAPI(logger logger.Logger) {
- s := store.GetStore()
- s.CodefreshAPI = &store.CodefreshAPI{
- Host: cfAPIHost,
- }
-
-}
\ No newline at end of file
diff --git a/venonactl/cmd/install-runtime.go b/venonactl/cmd/install-runtime.go
deleted file mode 100644
index 1a53c07a..00000000
--- a/venonactl/cmd/install-runtime.go
+++ /dev/null
@@ -1,151 +0,0 @@
-package cmd
-
-/*
-Copyright 2019 The Codefresh Authors.
-
-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.
-*/
-
-import (
- "fmt"
-
- "github.com/codefresh-io/venona/venonactl/pkg/plugins"
- "github.com/codefresh-io/venona/venonactl/pkg/store"
- "github.com/spf13/cobra"
- "github.com/spf13/viper"
-)
-
-var installRuntimeCmdOptions struct {
- codefreshToken string
- dryRun bool
- kube struct {
- namespace string
- inCluster bool
- context string
- }
- storageClass string
- runtimeEnvironmentName string
- kubernetesRunnerType bool
- tolerations string
-}
-
-var installRuntimeCmd = &cobra.Command{
- Use: "runtime",
- Short: "Install Codefresh's runtime",
- Run: func(cmd *cobra.Command, args []string) {
-
- s := store.GetStore()
- lgr := createLogger("Install-runtime", verbose)
- buildBasicStore(lgr)
- extendStoreWithAgentAPI(lgr, installRuntimeCmdOptions.codefreshToken, "")
- extendStoreWithKubeClient(lgr)
-
- if installRuntimeCmdOptions.runtimeEnvironmentName == "" {
- dieOnError(fmt.Errorf("Codefresh envrionment name is required"))
- }
- if cfAPIHost == "" {
- cfAPIHost = "https://g.codefresh.io"
- }
- // This is temporarily and used for signing
- s.CodefreshAPI = &store.CodefreshAPI{
- Host: cfAPIHost,
- }
-
- if installRuntimeCmdOptions.tolerations != "" {
- var tolerationsString string
-
- if installRuntimeCmdOptions.tolerations[0] == '@' {
- tolerationsString = loadTolerationsFromFile(installRuntimeCmdOptions.tolerations[1:])
- } else {
- tolerationsString = installRuntimeCmdOptions.tolerations
- }
-
- tolerations, err := parseTolerations(tolerationsString)
- if err != nil {
- dieOnError(err)
- }
-
- s.KubernetesAPI.Tolerations = tolerations
- }
-
- builder := plugins.NewBuilder(lgr)
- isDefault := isUsingDefaultStorageClass(installRuntimeCmdOptions.storageClass)
-
- builderInstallOpt := &plugins.InstallOptions{
- StorageClass: installRuntimeCmdOptions.storageClass,
- IsDefaultStorageClass: isDefault,
- DryRun: installRuntimeCmdOptions.dryRun,
- KubernetesRunnerType: installRuntimeCmdOptions.kubernetesRunnerType,
- CodefreshHost: cfAPIHost,
- CodefreshToken: installRuntimeCmdOptions.codefreshToken,
- RuntimeEnvironment: installRuntimeCmdOptions.runtimeEnvironmentName,
- ClusterNamespace: installRuntimeCmdOptions.kube.namespace,
- }
-
- if installRuntimeCmdOptions.kubernetesRunnerType {
- builder.Add(plugins.EnginePluginType)
- }
-
- if isDefault {
- builderInstallOpt.StorageClass = plugins.DefaultStorageClassNamePrefix
- }
-
- fillKubernetesAPI(lgr, installRuntimeCmdOptions.kube.context, installRuntimeCmdOptions.kube.namespace, installRuntimeCmdOptions.kube.inCluster)
-
- if installRuntimeCmdOptions.dryRun {
- s.DryRun = installRuntimeCmdOptions.dryRun
- lgr.Info("Running in dry-run mode")
- }
-
- // s.ClusterInCodefresh = installRuntimeCmdOptions.clusterNameInCodefresh
-
- builder.Add(plugins.RuntimeEnvironmentPluginType)
-
- if isDefault {
- builder.Add(plugins.VolumeProvisionerPluginType)
- } else {
- lgr.Info("Custom StorageClass is set, skipping installation of default volume provisioner")
- }
-
- builderInstallOpt.KubeBuilder = getKubeClientBuilder(s.KubernetesAPI.ContextName, s.KubernetesAPI.Namespace, s.KubernetesAPI.ConfigPath, s.KubernetesAPI.InCluster)
- var err error
- values := s.BuildValues()
- for _, p := range builder.Get() {
- values, err = p.Install(builderInstallOpt, values)
- if err != nil {
- dieOnError(err)
- }
- }
- lgr.Info("Runtime installation completed Successfully")
-
- },
-}
-
-func init() {
- installCommand.AddCommand(installRuntimeCmd)
-
- viper.BindEnv("kube-namespace", "KUBE_NAMESPACE")
- viper.BindEnv("kube-context", "KUBE_CONTEXT")
-
- installRuntimeCmd.Flags().StringVar(&installRuntimeCmdOptions.codefreshToken, "codefreshToken", "", "Codefresh token")
- installRuntimeCmd.Flags().StringVar(&installRuntimeCmdOptions.runtimeEnvironmentName, "runtimeName", viper.GetString("runtimeName"), "Name of the runtime as in codefresh")
- installRuntimeCmd.Flags().StringVar(&installRuntimeCmdOptions.kube.namespace, "kube-namespace", viper.GetString("kube-namespace"), "Name of the namespace on which venona should be installed [$KUBE_NAMESPACE]")
- installRuntimeCmd.Flags().StringVar(&installRuntimeCmdOptions.kube.context, "kube-context-name", viper.GetString("kube-context"), "Name of the kubernetes context on which venona should be installed (default is current-context) [$KUBE_CONTEXT]")
- installRuntimeCmd.Flags().StringVar(&installRuntimeCmdOptions.storageClass, "storage-class", "", "Set a name of your custom storage class, note: this will not install volume provisioning components")
-
- installRuntimeCmd.Flags().BoolVar(&installRuntimeCmdOptions.kube.inCluster, "in-cluster", false, "Set flag if venona is been installed from inside a cluster")
- installRuntimeCmd.Flags().BoolVar(&installRuntimeCmdOptions.dryRun, "dry-run", false, "Set to true to simulate installation")
- installRuntimeCmd.Flags().BoolVar(&installRuntimeCmdOptions.kubernetesRunnerType, "kubernetes-runner-type", false, "Set the runner type to kubernetes (alpha feature)")
- installRuntimeCmd.Flags().StringVar(&installRuntimeCmdOptions.tolerations, "tolerations", "", "The kubernetes tolerations as JSON string to be used by venona resources (default is no tolerations)")
-
-}
diff --git a/venonactl/cmd/install-venona.go b/venonactl/cmd/install-venona.go
deleted file mode 100644
index 1010dca0..00000000
--- a/venonactl/cmd/install-venona.go
+++ /dev/null
@@ -1,59 +0,0 @@
-package cmd
-
-/*
-Copyright 2019 The Codefresh Authors.
-
-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.
-*/
-
-import (
- "github.com/spf13/cobra"
-)
-
-const (
- clusterNameMaxLength = 20
- namespaceMaxLength = 20
-)
-
-var installCmdOptions struct {
- dryRun bool
- clusterNameInCodefresh string
- kube struct {
- namespace string
- inCluster bool
- context string
- nodeSelector string
- }
- storageClass string
- venona struct {
- version string
- }
- setDefaultRuntime bool
- installOnlyRuntimeEnvironment bool
- skipRuntimeInstallation bool
- runtimeEnvironmentName string
- kubernetesRunnerType bool
- buildNodeSelector string
- buildAnnotations []string
- tolerationJSONString string
-}
-
-// installVenonaCmd represents the install command
-var installVenonaCmd = &cobra.Command{
- Use: "all",
- Short: "Install Codefresh's resource on cluster",
-}
-
-func init() {
- installCommand.AddCommand(installVenonaCmd)
-}
diff --git a/venonactl/cmd/install.go b/venonactl/cmd/install.go
index 933b1be6..0eac949c 100644
--- a/venonactl/cmd/install.go
+++ b/venonactl/cmd/install.go
@@ -2,6 +2,7 @@ package cmd
/*
Copyright 2019 The Codefresh Authors.
+
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
@@ -16,15 +17,276 @@ limitations under the License.
*/
import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "gopkg.in/yaml.v2"
+ "io/ioutil"
+ "strings"
+
+ "k8s.io/client-go/tools/clientcmd"
+
+ "github.com/codefresh-io/venona/venonactl/pkg/store"
+ "github.com/codefresh-io/venona/venonactl/pkg/plugins"
"github.com/spf13/cobra"
+ "github.com/spf13/viper"
+ k8sApi "k8s.io/api/core/v1"
)
-var installCommand = &cobra.Command{
+const (
+ clusterNameMaxLength = 20
+ namespaceMaxLength = 20
+)
+
+var installCmdOptions struct {
+ dryRun bool
+ clusterNameInCodefresh string
+ kube struct {
+ namespace string
+ inCluster bool
+ context string
+ nodeSelector string
+ }
+ storageClass string
+ venona struct {
+ version string
+ }
+ setDefaultRuntime bool
+ installOnlyRuntimeEnvironment bool
+ skipRuntimeInstallation bool
+ runtimeEnvironmentName string
+ kubernetesRunnerType bool
+ buildNodeSelector string
+ buildAnnotations []string
+ tolerations string
+}
+
+// installCmd represents the install command
+var installCmd = &cobra.Command{
Use: "install",
- Short: "Install agent and runtime components",
+ Short: "Install Codefresh's runtime-environment",
+ Run: func(cmd *cobra.Command, args []string) {
+ s := store.GetStore()
+ lgr := createLogger("Install", verbose)
+ buildBasicStore(lgr)
+ extendStoreWithCodefershClient(lgr)
+ extendStoreWithKubeClient(lgr)
+
+ builder := plugins.NewBuilder(lgr)
+ isDefault := isUsingDefaultStorageClass(installCmdOptions.storageClass)
+
+ builderInstallOpt := &plugins.InstallOptions{
+ CodefreshHost: s.CodefreshAPI.Host,
+ CodefreshToken: s.CodefreshAPI.Token,
+ MarkAsDefault: installCmdOptions.setDefaultRuntime,
+ StorageClass: installCmdOptions.storageClass,
+ IsDefaultStorageClass: isDefault,
+ DryRun: installCmdOptions.dryRun,
+ KubernetesRunnerType: installCmdOptions.kubernetesRunnerType,
+ }
+
+ if installCmdOptions.kubernetesRunnerType {
+ builder.Add(plugins.EnginePluginType)
+ }
+
+ if isDefault {
+ builderInstallOpt.StorageClass = plugins.DefaultStorageClassNamePrefix
+ }
+
+ if installCmdOptions.kube.context == "" {
+ config := clientcmd.GetConfigFromFileOrDie(s.KubernetesAPI.ConfigPath)
+ installCmdOptions.kube.context = config.CurrentContext
+ lgr.Debug("Kube Context is not set, using current context", "Kube-Context-Name", installCmdOptions.kube.context)
+ }
+ if installCmdOptions.kube.namespace == "" {
+ installCmdOptions.kube.namespace = "default"
+ }
+
+ s.KubernetesAPI.InCluster = installCmdOptions.kube.inCluster
+ s.KubernetesAPI.ContextName = installCmdOptions.kube.context
+ s.KubernetesAPI.Namespace = installCmdOptions.kube.namespace
+
+ kns, err := parseNodeSelector(installCmdOptions.kube.nodeSelector)
+ if err != nil {
+ dieOnError(err)
+ }
+ s.KubernetesAPI.NodeSelector = kns.String()
+
+ if installCmdOptions.tolerations != "" {
+ var tolerationsString string
+
+ if installCmdOptions.tolerations[0] == '@' {
+ tolerationsString = loadTolerationsFromFile(installCmdOptions.tolerations[1:])
+ } else {
+ tolerationsString = installCmdOptions.tolerations
+ }
+
+ tolerations, err := parseTolerations(tolerationsString)
+ if err != nil {
+ dieOnError(err)
+ }
+
+ s.KubernetesAPI.Tolerations = tolerations
+ }
+
+ if installCmdOptions.dryRun {
+ s.DryRun = installCmdOptions.dryRun
+ lgr.Info("Running in dry-run mode")
+ }
+ if installCmdOptions.venona.version != "" {
+ version := installCmdOptions.venona.version
+ lgr.Info("Version set manually", "version", version)
+ s.Image.Tag = version
+ s.Version.Latest.Version = version
+ }
+ s.ClusterInCodefresh = installCmdOptions.clusterNameInCodefresh
+ if installCmdOptions.installOnlyRuntimeEnvironment == true && installCmdOptions.skipRuntimeInstallation == true {
+ dieOnError(fmt.Errorf("Cannot use both flags skip-runtime-installation and only-runtime-environment"))
+ }
+ if installCmdOptions.installOnlyRuntimeEnvironment == true {
+ builder.Add(plugins.RuntimeEnvironmentPluginType)
+ } else if installCmdOptions.skipRuntimeInstallation == true {
+ if installCmdOptions.runtimeEnvironmentName == "" {
+ dieOnError(fmt.Errorf("runtime-environment flag is required when using flag skip-runtime-installation"))
+ }
+ s.RuntimeEnvironment = installCmdOptions.runtimeEnvironmentName
+ lgr.Info("Skipping installation of runtime environment, installing venona only")
+ builder.Add(plugins.VenonaPluginType)
+ } else {
+ builder.
+ Add(plugins.RuntimeEnvironmentPluginType).
+ Add(plugins.VenonaPluginType)
+ }
+ if isDefault {
+ builder.Add(plugins.VolumeProvisionerPluginType)
+ } else {
+ lgr.Info("Custom StorageClass is set, skipping installation of default volume provisioner")
+ }
+
+ builderInstallOpt.ClusterName = s.KubernetesAPI.ContextName
+ builderInstallOpt.RegisterWithAgent = true
+ if s.ClusterInCodefresh != "" {
+ builderInstallOpt.ClusterName = s.ClusterInCodefresh
+ builderInstallOpt.RegisterWithAgent = false
+ }
+ builderInstallOpt.KubeBuilder = getKubeClientBuilder(builderInstallOpt.ClusterName, s.KubernetesAPI.Namespace, s.KubernetesAPI.ConfigPath, s.KubernetesAPI.InCluster)
+ builderInstallOpt.ClusterNamespace = s.KubernetesAPI.Namespace
+
+ annotations := make(map[string]string)
+ for _, annotation := range installCmdOptions.buildAnnotations {
+ v := strings.Split(annotation, "=")
+ if len(v) != 2 {
+ dieOnError(errors.New("annotations must be in form \"key=value\""))
+ }
+ annotations[v[0]] = v[1]
+ }
+
+ builderInstallOpt.Annotations = annotations
+
+ bns, err := parseNodeSelector(installCmdOptions.buildNodeSelector)
+ if err != nil {
+ dieOnError(err)
+ }
+ s.CodefreshAPI.BuildNodeSelector = bns
+ builderInstallOpt.BuildNodeSelector = bns
+
+ err = validateInstallOptions(builderInstallOpt)
+ if err != nil {
+ dieOnError(err)
+ }
+
+ values := s.BuildValues()
+ for _, p := range builder.Get() {
+ values, err = p.Install(builderInstallOpt, values)
+ if err != nil {
+ dieOnError(err)
+ }
+ }
+ lgr.Info("Installation completed Successfully")
+ },
}
func init() {
- rootCmd.AddCommand(installCommand)
+ rootCmd.AddCommand(installCmd)
+
+ viper.BindEnv("kube-namespace", "KUBE_NAMESPACE")
+ viper.BindEnv("kube-context", "KUBE_CONTEXT")
+
+ installCmd.Flags().StringVar(&installCmdOptions.clusterNameInCodefresh, "cluster-name", "", "cluster name (if not passed runtime-environment will be created cluster-less); this is a friendly name used for metadata does not need to match the literal cluster name. Limited to 20 Characters.")
+ installCmd.Flags().StringVar(&installCmdOptions.venona.version, "venona-version", "", "Version of venona to install (default is the latest)")
+ installCmd.Flags().StringVar(&installCmdOptions.runtimeEnvironmentName, "runtime-environment", "", "if --skip-runtime-installation set, will try to configure venona on current runtime-environment")
+ installCmd.Flags().StringVar(&installCmdOptions.kube.namespace, "kube-namespace", viper.GetString("kube-namespace"), "Name of the namespace on which venona should be installed [$KUBE_NAMESPACE]")
+ installCmd.Flags().StringVar(&installCmdOptions.kube.context, "kube-context-name", viper.GetString("kube-context"), "Name of the kubernetes context on which venona should be installed (default is current-context) [$KUBE_CONTEXT]")
+ installCmd.Flags().StringVar(&installCmdOptions.storageClass, "storage-class", "", "Set a name of your custom storage class, note: this will not install volume provisioning components")
+ installCmd.Flags().StringVar(&installCmdOptions.kube.nodeSelector, "kube-node-selector", "", "The kubernetes node selector \"key=value\" to be used by venona resources (default is no node selector)")
+ installCmd.Flags().StringVar(&installCmdOptions.buildNodeSelector, "build-node-selector", "", "The kubernetes node selector \"key=value\" to be used by venona build resources (default is no node selector)")
+ installCmd.Flags().StringArrayVar(&installCmdOptions.buildAnnotations, "build-annotations", []string{}, "The kubernetes metadata.annotations as \"key=value\" to be used by venona build resources (default is no node selector)")
+ installCmd.Flags().StringVar(&installCmdOptions.tolerations, "tolerations", "", `The kubernetes tolerations as JSON string to be used by venona resources (default is no tolerations). If prefixed with "@", loads from a file: @/tmp/tolerations.json`)
+
+ installCmd.Flags().BoolVar(&installCmdOptions.skipRuntimeInstallation, "skip-runtime-installation", false, "Set flag if you already have a configured runtime-environment, add --runtime-environment flag with name")
+ installCmd.Flags().BoolVar(&installCmdOptions.kube.inCluster, "in-cluster", false, "Set flag if venona is been installed from inside a cluster")
+ installCmd.Flags().BoolVar(&installCmdOptions.installOnlyRuntimeEnvironment, "only-runtime-environment", false, "Set to true to onlky configure namespace as runtime-environment for Codefresh")
+ installCmd.Flags().BoolVar(&installCmdOptions.dryRun, "dry-run", false, "Set to true to simulate installation")
+ installCmd.Flags().BoolVar(&installCmdOptions.setDefaultRuntime, "set-default", false, "Mark the install runtime-environment as default one after installation")
+ installCmd.Flags().BoolVar(&installCmdOptions.kubernetesRunnerType, "kubernetes-runner-type", false, "Set the runner type to kubernetes (alpha feature)")
+
+}
+
+type nodeSelector map[string]string
+
+func parseNodeSelector(s string) (nodeSelector, error) {
+ if s == "" {
+ return nodeSelector{}, nil
+ }
+ v := strings.Split(s, "=")
+ if len(v) != 2 {
+ return nil, errors.New("node selector must be in form \"key=value\"")
+ }
+ return nodeSelector{v[0]: v[1]}, nil
+}
+
+func loadTolerationsFromFile(filename string) string {
+ data, err := ioutil.ReadFile(filename)
+ if err != nil {
+ dieOnError(err)
+ }
+
+ return string(data)
+}
+
+func parseTolerations(s string) (string, error) {
+ if s == "" {
+ return "", nil
+ }
+ var data []k8sApi.Toleration
+ err := json.Unmarshal([]byte(s), &data)
+ if err != nil {
+ return "", fmt.Errorf("can not parse tolerations: %s", err)
+ }
+ y, err := yaml.Marshal(&data)
+ if err != nil {
+ return "", fmt.Errorf("can not marshel tolerations to yaml: %s", err)
+ }
+ d := fmt.Sprintf("\n%s", string(y))
+ return d, nil
+}
+
+func validateInstallOptions(opts *plugins.InstallOptions) error {
+ if len(opts.ClusterName) > clusterNameMaxLength {
+ return errors.New(fmt.Sprintf("cluster name length is limited to %d", clusterNameMaxLength))
+ }
+ if len(opts.ClusterNamespace) > namespaceMaxLength {
+ return errors.New(fmt.Sprintf("cluster namespace length is limited to %d", namespaceMaxLength))
+ }
+ return nil
+}
+
+// String returns a k8s compliant string representation of the nodeSelector. Only a single value is supported.
+func (ns nodeSelector) String() string {
+ var s string
+ for k, v := range ns {
+ s = fmt.Sprintf("%s: %s", k, v)
+ }
+ return s
}
diff --git a/venonactl/cmd/uninstall-agent.go b/venonactl/cmd/uninstall-agent.go
deleted file mode 100644
index 20526a7c..00000000
--- a/venonactl/cmd/uninstall-agent.go
+++ /dev/null
@@ -1,69 +0,0 @@
-package cmd
-
-
-import (
- "fmt"
-
- "github.com/codefresh-io/venona/venonactl/pkg/store"
-
- "github.com/codefresh-io/venona/venonactl/pkg/plugins"
- "github.com/spf13/cobra"
- "github.com/spf13/viper"
-)
-
-var uninstallAgentCmdOptions struct {
- kube struct {
- context string
- namespace string
- kubePath string
- }
-}
-
-var uninstallAgentCmd = &cobra.Command{
- Use: "agent",
- Short: "Uninstall Codefresh's agent",
- Run: func(cmd *cobra.Command, args []string) {
- s := store.GetStore()
- lgr := createLogger("UninstallAgent", verbose)
- buildBasicStore(lgr)
- extendStoreWithKubeClient(lgr)
-
- s.CodefreshAPI = &store.CodefreshAPI{}
- s.AgentAPI = &store.AgentAPI{}
-
-
- builder := plugins.NewBuilder(lgr)
- if uninstallAgentCmdOptions.kube.context == "" {
- dieOnError(fmt.Errorf("Context name is required in order to uninstall agent"))
- }
- if uninstallAgentCmdOptions.kube.namespace == "" {
- dieOnError(fmt.Errorf("Namespace name is required to in order to uninstall agent"))
- }
-
-
- deleteOptions := &plugins.DeleteOptions{}
- s.KubernetesAPI.ContextName = uninstallAgentCmdOptions.kube.context
- s.KubernetesAPI.Namespace = uninstallAgentCmdOptions.kube.namespace
-
- builder.Add(plugins.VenonaPluginType)
- deleteOptions.KubeBuilder = getKubeClientBuilder(s.KubernetesAPI.ContextName, s.KubernetesAPI.Namespace, s.KubernetesAPI.ConfigPath, false)
- deleteOptions.ClusterNamespace = uninstallAgentCmdOptions.kube.namespace
- for _, p := range builder.Get() {
- err := p.Delete(deleteOptions, s.BuildValues())
- if err != nil {
- dieOnError(err)
- }
- }
-
- lgr.Info("Deletion of agent is completed")
- },
-}
-
-func init() {
- uninstallCommand.AddCommand(uninstallAgentCmd)
- viper.BindEnv("kube-namespace", "KUBE_NAMESPACE")
- viper.BindEnv("kube-context", "KUBE_CONTEXT")
- uninstallAgentCmd.Flags().StringVar(&uninstallAgentCmdOptions.kube.context, "kube-context-name", "", "Name of the kubernetes context on which venona should be uninstalled (default is current-context) [$KUBE_CONTEXT]")
- uninstallAgentCmd.Flags().StringVar(&uninstallAgentCmdOptions.kube.namespace, "kube-namespace", "", "Name of the namespace on which venona should be uninstalled [$KUBE_NAMESPACE]")
-
-}
\ No newline at end of file
diff --git a/venonactl/cmd/uninstall-runtime.go b/venonactl/cmd/uninstall-runtime.go
deleted file mode 100644
index d5df776f..00000000
--- a/venonactl/cmd/uninstall-runtime.go
+++ /dev/null
@@ -1,115 +0,0 @@
-package cmd
-
-
-import (
- "fmt"
-
- "github.com/codefresh-io/venona/venonactl/pkg/store"
-
- "github.com/codefresh-io/venona/venonactl/pkg/plugins"
- "github.com/spf13/cobra"
- "github.com/spf13/viper"
-)
-
-var uninstallRunimeCmdOptions struct {
- kube struct {
- context string
- namespace string
- kubePath string
- }
- kubeVenona struct {
- namespace string
- kubePath string
- context string
- }
- runtimeEnvironmentName string
- storageClassName string
- restartAgent bool
-}
-
-var uninstallRuntimeCmd = &cobra.Command{
- Use: "runtime",
- Short: "Uninstall Codefresh's runtime",
- Run: func(cmd *cobra.Command, args []string) {
- s := store.GetStore()
- lgr := createLogger("UninstallRuntime", verbose)
- buildBasicStore(lgr)
- extendStoreWithKubeClient(lgr)
-
- s.CodefreshAPI = &store.CodefreshAPI{}
- s.AgentAPI = &store.AgentAPI{}
-
-
- builder := plugins.NewBuilder(lgr)
- if uninstallRunimeCmdOptions.kube.context == "" {
- dieOnError(fmt.Errorf("Context name is required in order to uninstall agent"))
- }
- if uninstallRunimeCmdOptions.kube.namespace == "" {
- dieOnError(fmt.Errorf("Namespace name is required to in order to uninstall agent"))
- }
-
-
- if uninstallRunimeCmdOptions.kubeVenona.kubePath == "" {
- uninstallRunimeCmdOptions.kubeVenona.kubePath = kubeConfigPath
- }
- if uninstallRunimeCmdOptions.kubeVenona.namespace == "" {
- uninstallRunimeCmdOptions.kubeVenona.namespace = uninstallRunimeCmdOptions.kube.namespace
- }
- if uninstallRunimeCmdOptions.kubeVenona.context == "" {
- uninstallRunimeCmdOptions.kubeVenona.context = uninstallRunimeCmdOptions.kube.context
- }
-
- if uninstallRunimeCmdOptions.kube.kubePath == "" {
- uninstallRunimeCmdOptions.kube.kubePath = kubeConfigPath
- }
-
- deleteOptions := &plugins.DeleteOptions{}
- // runtime
- deleteOptions.KubeBuilder = getKubeClientBuilder(uninstallRunimeCmdOptions.kube.context,
- uninstallRunimeCmdOptions.kube.namespace,
- uninstallRunimeCmdOptions.kube.kubePath,
- false)
-
- // agent
- deleteOptions.AgentKubeBuilder = getKubeClientBuilder(uninstallRunimeCmdOptions.kubeVenona.context,
- uninstallRunimeCmdOptions.kubeVenona.namespace,
- uninstallRunimeCmdOptions.kubeVenona.kubePath,
- false)
-
- builder.Add(plugins.RuntimeEnvironmentPluginType)
- if isUsingDefaultStorageClass(uninstallRunimeCmdOptions.storageClassName) {
- builder.Add(plugins.VolumeProvisionerPluginType)
- }
- builder.Add(plugins.RuntimeAttachType)
- deleteOptions.ClusterNamespace = uninstallRunimeCmdOptions.kube.namespace
- deleteOptions.AgentNamespace = uninstallRunimeCmdOptions.kubeVenona.namespace
- deleteOptions.RuntimeEnvironment = uninstallRunimeCmdOptions.runtimeEnvironmentName
- for _, p := range builder.Get() {
- err := p.Delete(deleteOptions, s.BuildValues())
- if err != nil {
- dieOnError(err)
- }
- }
-
- lgr.Info("Deletion of runtime is completed")
- },
-}
-
-func init() {
- uninstallCommand.AddCommand(uninstallRuntimeCmd)
- viper.BindEnv("kube-namespace", "KUBE_NAMESPACE")
- viper.BindEnv("kube-context", "KUBE_CONTEXT")
- uninstallRuntimeCmd.Flags().StringVar(&uninstallRunimeCmdOptions.kube.namespace, "kube-namespace", viper.GetString("kube-namespace"), "Name of the namespace on which venona should be installed [$KUBE_NAMESPACE]")
- uninstallRuntimeCmd.Flags().StringVar(&uninstallRunimeCmdOptions.kube.context, "kube-context-name", viper.GetString("kube-context"), "Name of the kubernetes context on which venona should be installed (default is current-context) [$KUBE_CONTEXT]")
- uninstallRuntimeCmd.Flags().StringVar(&uninstallRunimeCmdOptions.kube.kubePath, "kube-config-path", viper.GetString("kubeconfig"), "Path to kubeconfig file (default is $HOME/.kube/config) [$KUBECONFIG]")
-
- uninstallRuntimeCmd.Flags().StringVar(&uninstallRunimeCmdOptions.runtimeEnvironmentName, "runtime-name", viper.GetString("runtime-name"), "Name of the runtime as in codefresh")
-
- uninstallRuntimeCmd.Flags().StringVar(&uninstallRunimeCmdOptions.kubeVenona.namespace, "kube-namespace-agent", viper.GetString("kube-namespace-agent"), "Name of the namespace where venona is installed [$KUBE_NAMESPACE]")
- uninstallRuntimeCmd.Flags().StringVar(&uninstallRunimeCmdOptions.kubeVenona.context, "kube-context-name-agent", viper.GetString("kube-context-agent"), "Name of the kubernetes context on which venona is installed (default is current-context) [$KUBE_CONTEXT]")
- uninstallRuntimeCmd.Flags().StringVar(&uninstallRunimeCmdOptions.kubeVenona.kubePath, "kube-config-path-agent", viper.GetString("kubeconfig-agent"), "Path to kubeconfig file (default is $HOME/.kube/config) for agent [$KUBECONFIG]")
- uninstallRuntimeCmd.Flags().BoolVar(&uninstallRunimeCmdOptions.restartAgent, "restart-agent", viper.GetBool("restart-agent"), "Restart agent after attach operation")
-
- uninstallRuntimeCmd.Flags().StringVar(&uninstallRunimeCmdOptions.storageClassName, "storage-class-name", viper.GetString("storage-class-name"), "Storage class name of the runtime to be uninstalled")
-
-}
\ No newline at end of file
diff --git a/venonactl/cmd/uninstall.go b/venonactl/cmd/uninstall.go
deleted file mode 100644
index d598b4ce..00000000
--- a/venonactl/cmd/uninstall.go
+++ /dev/null
@@ -1,30 +0,0 @@
-package cmd
-
-/*
-Copyright 2019 The Codefresh Authors.
-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.
-*/
-
-import (
-
- "github.com/spf13/cobra"
-)
-
-var uninstallCommand = &cobra.Command{
- Use: "uninstall",
- Short: "Uninstall agent and runtime components",
-}
-
-func init() {
- rootCmd.AddCommand(uninstallCommand)
-}
diff --git a/venonactl/cmd/upgrade.go b/venonactl/cmd/upgrade.go
index 4a2f625d..0d522ccb 100644
--- a/venonactl/cmd/upgrade.go
+++ b/venonactl/cmd/upgrade.go
@@ -17,8 +17,10 @@ limitations under the License.
*/
import (
- "os"
+ "errors"
+ "github.com/codefresh-io/venona/venonactl/pkg/plugins"
+ "github.com/codefresh-io/venona/venonactl/pkg/store"
"github.com/spf13/cobra"
)
@@ -33,10 +35,60 @@ var upgradeCmdOpt struct {
var upgradeCmd = &cobra.Command{
Use: "upgrade [name]",
Short: "Upgrade existing runtime-environment",
+ Args: func(cmd *cobra.Command, args []string) error {
+ if len(args) < 1 {
+ return errors.New("requires name of the runtime-environment")
+ }
+
+ if len(args) > 1 {
+ return errors.New("Cannot upgrade multiple runtimes once")
+ }
+ return nil
+ },
Run: func(cmd *cobra.Command, args []string) {
- lgr := createLogger("Upgrade", true)
- lgr.Warn("Upgrade is not supported from version < 1.0.0 to version >= 1.x.x, please run the migration script: https://github.com/codefresh-io/venona/blob/master/scripts/migration.sh to upgrade to the latest version")
- os.Exit(0)
+ s := store.GetStore()
+ lgr := createLogger("Upgrade", verbose)
+ buildBasicStore(lgr)
+ extendStoreWithCodefershClient(lgr)
+ extendStoreWithKubeClient(lgr)
+ builder := plugins.NewBuilder(lgr)
+ builderUpgradeOpt := &plugins.UpgradeOptions{
+ CodefreshHost: s.CodefreshAPI.Host,
+ CodefreshToken: s.CodefreshAPI.Token,
+ DryRun: upgradeCmdOpt.dryRun,
+ Name: s.AppName,
+ }
+
+ re, _ := s.CodefreshAPI.Client.RuntimeEnvironments().Get(args[0])
+ contextName := re.RuntimeScheduler.Cluster.ClusterProvider.Selector
+ if upgradeCmdOpt.kube.context != "" {
+ contextName = upgradeCmdOpt.kube.context
+ }
+ s.KubernetesAPI.ContextName = contextName
+ s.KubernetesAPI.Namespace = re.RuntimeScheduler.Cluster.Namespace
+
+ builderUpgradeOpt.ClusterNamespace = s.KubernetesAPI.Namespace
+
+ if upgradeCmdOpt.dryRun {
+ lgr.Info("Running in dry-run mode")
+ } else {
+ builder.Add(plugins.VenonaPluginType)
+ if isUsingDefaultStorageClass(re.RuntimeScheduler.Pvcs.Dind.StorageClassName) {
+ builder.Add(plugins.VolumeProvisionerPluginType)
+ }
+ builder.Add(plugins.RuntimeEnvironmentPluginType)
+ }
+
+ builderUpgradeOpt.KubeBuilder = getKubeClientBuilder(upgradeCmdOpt.kube.context, s.KubernetesAPI.Namespace, s.KubernetesAPI.ConfigPath, s.KubernetesAPI.InCluster)
+
+ var err error
+ values := s.BuildValues()
+ for _, p := range builder.Get() {
+ values, err = p.Upgrade(builderUpgradeOpt, values)
+ if err != nil {
+ dieOnError(err)
+ }
+ }
},
}
diff --git a/venonactl/go.mod b/venonactl/go.mod
index 892b865a..5af5c712 100644
--- a/venonactl/go.mod
+++ b/venonactl/go.mod
@@ -41,6 +41,4 @@ require (
replace git.apache.org/thrift.git => github.com/apache/thrift v0.0.0-20181218151757-9b75e4fe745a
-replace github.com/census-instrumentation/opencensus-proto => github.com/census-instrumentation/opencensus-proto v0.0.3-0.20181214143942-ba49f56771b8
-
go 1.13
diff --git a/venonactl/go.sum b/venonactl/go.sum
index fac40908..58b36833 100644
--- a/venonactl/go.sum
+++ b/venonactl/go.sum
@@ -20,14 +20,12 @@ github.com/apache/thrift v0.0.0-20181218151757-9b75e4fe745a/go.mod h1:cp2SuWMxlE
github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
-github.com/census-instrumentation/opencensus-proto v0.0.3-0.20181214143942-ba49f56771b8 h1:vvX9PxDdQSEmcYSMjZpKbCRRTyHrvfr08Ue9/zk7HV4=
-github.com/census-instrumentation/opencensus-proto v0.0.3-0.20181214143942-ba49f56771b8/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
+github.com/census-instrumentation/opencensus-proto v0.1.0-0.20181214143942-ba49f56771b8 h1:gUqsFVdUKoRHNg8fkFd8gB5OOEa/g5EwlAHznb4zjbI=
+github.com/census-instrumentation/opencensus-proto v0.1.0-0.20181214143942-ba49f56771b8/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/codefresh-io/go-sdk v0.17.0 h1:0fwE4K0QeqM2VfyjiALzkH2se4HbLh9BiQCuzQnJH/U=
github.com/codefresh-io/go-sdk v0.17.0/go.mod h1:b6hK9euSW+MDXUDHU1+YgP8vzcij749I31ZIZSXed+I=
-github.com/codefresh-io/venona v0.30.2 h1:FgLNURnChYvamwBVdfQDthIRdfaOb0Zyvc2EdnajaPQ=
-github.com/codefresh-io/venona v1.0.0 h1:w8fxc2+kKiTPYpHH5AFAyyDtefcnNKtlW8sHAP9Gvvo=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk=
@@ -80,7 +78,6 @@ github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
github.com/gophercloud/gophercloud v0.0.0-20190206021053-df38e1611dbe h1:wFrfOm62oPv9R8kEABWXx63s2Akmt68WF1ngahljxFU=
github.com/gophercloud/gophercloud v0.0.0-20190206021053-df38e1611dbe/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4=
-github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/gregjones/httpcache v0.0.0-20170728041850-787624de3eb7 h1:6TSoaYExHper8PYsJu23GWVNOyYRCSnIFyxKgLSZ54w=
@@ -106,7 +103,6 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be h1:AHimNtVIpiBjPUhEF5KNCkrUyqTSA5zWUl8sQ2bfGBE=
github.com/json-iterator/go v0.0.0-20180701071628-ab8a2e0c74be/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
-github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
@@ -153,6 +149,10 @@ github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTm
github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
github.com/pelletier/go-toml v1.2.0 h1:T5zMGML61Wp+FlcbWjRDT7yAxhJNAiPPLOFECq181zc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
+github.com/pelletier/go-toml v1.4.0 h1:u3Z1r+oOXJIkxqw34zVhyPgjBsm6X2wn21NWs/HfSeg=
+github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo=
+github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4=
+github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys=
github.com/peterbourgon/diskv v2.0.1+incompatible h1:UBdAOUP5p4RWqPBg048CAvpKN+vxiaj6gdUUzhl4XmI=
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
@@ -177,26 +177,34 @@ github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40T
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
-github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
-github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ=
github.com/spf13/afero v1.2.0 h1:O9FblXGxoTc51M+cqr74Bm2Tmt4PvkA5iu/j8HrkNuY=
github.com/spf13/afero v1.2.0/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
+github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
+github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk=
github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8=
github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
+github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng=
+github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
+github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
+github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
+github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
+github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/viper v1.3.1/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s=
+github.com/spf13/viper v1.4.0 h1:yXHLWeravcrgGyFSyCgdYpXQ9dR9c/WED3pg1RhxqEU=
+github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
github.com/spf13/viper v1.6.1 h1:VPZzIkznI1YhVMRi6vNFLHSwhnhReBfgTxIPccpfdZk=
github.com/spf13/viper v1.6.1/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@@ -254,12 +262,21 @@ golang.org/x/sys v0.0.0-20181218192612-074acd46bca6/go.mod h1:STP8DvDyc/dI5b8T5h
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
+golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8 h1:41hwlulw1prEMBxLQSlMSux1zxJf07B3WPsdjJlKZxE=
+golang.org/x/sys v0.0.0-20190912141932-bc967efca4b8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed h1:5TJcLJn2a55mJjzYk0yOoqN8X1OdvBDUnaZaKKyQtkY=
+golang.org/x/sys v0.0.0-20191002091554-b397fe3ad8ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20191218084908-4a24b4065292 h1:Y8q0zsdcgAd+JU8VUA8p8Qv2YhuY9zevDG2ORt5qBUI=
+golang.org/x/sys v0.0.0-20191218084908-4a24b4065292/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
+golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
+golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20181219222714-6e267b5cc78e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
@@ -295,6 +312,8 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
+gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.7 h1:VUgggvou5XRW9mHwD/yXxIYSMtY0zoKQf/v226p2nyo=
gopkg.in/yaml.v2 v2.2.7/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
diff --git a/venonactl/pkg/kube/kube.go b/venonactl/pkg/kube/kube.go
index 903d0600..a9051be0 100644
--- a/venonactl/pkg/kube/kube.go
+++ b/venonactl/pkg/kube/kube.go
@@ -10,7 +10,6 @@ import (
type (
Kube interface {
BuildClient() (*kubernetes.Clientset, error)
- BuildConfig() (clientcmd.ClientConfig)
}
kube struct {
@@ -43,23 +42,17 @@ func (k *kube) BuildClient() (*kubernetes.Clientset, error) {
if k.inCluster {
config, err = rest.InClusterConfig()
} else {
- config, err = k.BuildConfig().ClientConfig()
+ config, err = clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
+ &clientcmd.ClientConfigLoadingRules{ExplicitPath: k.pathToKubeConfig},
+ &clientcmd.ConfigOverrides{
+ CurrentContext: k.contextName,
+ Context: clientcmdapi.Context{
+ Namespace: k.namespace,
+ },
+ }).ClientConfig()
}
if err != nil {
return nil, err
}
return kubernetes.NewForConfig(config)
}
-
-func (k *kube) BuildConfig() (clientcmd.ClientConfig) {
- config := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
- &clientcmd.ClientConfigLoadingRules{ExplicitPath: k.pathToKubeConfig},
- &clientcmd.ConfigOverrides{
- CurrentContext: k.contextName,
- Context: clientcmdapi.Context{
- Namespace: k.namespace,
- },
- })
- return config
-
-}
diff --git a/venonactl/pkg/plugins/engine.go b/venonactl/pkg/plugins/engine.go
index 71b9c677..1eb6acd0 100644
--- a/venonactl/pkg/plugins/engine.go
+++ b/venonactl/pkg/plugins/engine.go
@@ -87,7 +87,7 @@ func (u *enginePlugin) Delete(deleteOpt *DeleteOptions, v Values) error {
matchPattern: engineFilesPattern,
operatorType: EnginePluginType,
}
- return uninstall(opt)
+ return delete(opt)
}
func (u *enginePlugin) Upgrade(opt *UpgradeOptions, v Values) (Values, error) {
diff --git a/venonactl/pkg/plugins/plugin.go b/venonactl/pkg/plugins/plugin.go
index c1c07aca..2c694c40 100644
--- a/venonactl/pkg/plugins/plugin.go
+++ b/venonactl/pkg/plugins/plugin.go
@@ -8,7 +8,6 @@ import (
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
- "k8s.io/client-go/tools/clientcmd"
)
const (
@@ -17,7 +16,6 @@ const (
VolumeProvisionerPluginType = "volume-provisioner"
EnginePluginType = "engine"
DefaultStorageClassNamePrefix = "dind-local-volumes-venona"
- RuntimeAttachType = "runtime-attach"
)
type (
@@ -33,10 +31,6 @@ type (
Get() []Plugin
}
- KubeClientBuilder interface {
- BuildClient() (*kubernetes.Clientset, error)
- }
-
pb struct {
logger logger.Logger
plugins []Plugin
@@ -55,34 +49,18 @@ type (
IsDefaultStorageClass bool
KubeBuilder interface {
BuildClient() (*kubernetes.Clientset, error)
- BuildConfig() clientcmd.ClientConfig
-
- }
- AgentKubeBuilder interface {
- BuildClient() (*kubernetes.Clientset, error)
}
DryRun bool
KubernetesRunnerType bool
BuildNodeSelector map[string]string
Annotations map[string]string
- RuntimeEnvironment string
- RuntimeClusterName string
- RuntimeServiceAccount string
- RestartAgent bool
}
DeleteOptions struct {
KubeBuilder interface {
BuildClient() (*kubernetes.Clientset, error)
}
- AgentKubeBuilder interface {
- BuildClient() (*kubernetes.Clientset, error)
- }
- ClusterNamespace string // runtime
- AgentNamespace string // agent
- RuntimeEnvironment string
- RestartAgent bool
-
+ ClusterNamespace string
}
UpgradeOptions struct {
@@ -180,11 +158,6 @@ func build(t string, logger logger.Logger) Plugin {
}
}
- if t == RuntimeAttachType {
- return &runtimeAttachPlugin{
- logger: logger.New("Plugin", RuntimeAttachType),
- }
- }
return nil
}
@@ -244,7 +217,7 @@ func status(opt *statusOptions) ([][]string, error) {
return rows, nil
}
-func uninstall(opt *deleteOptions) error {
+func delete(opt *deleteOptions) error {
kubeObjects, err := KubeObjectsFromTemplates(opt.templates, opt.templateValues, opt.matchPattern, opt.logger)
if err != nil {
diff --git a/venonactl/pkg/plugins/runtime-attach.go b/venonactl/pkg/plugins/runtime-attach.go
deleted file mode 100644
index 6cee25e7..00000000
--- a/venonactl/pkg/plugins/runtime-attach.go
+++ /dev/null
@@ -1,263 +0,0 @@
-package plugins
-
-import (
- "encoding/base64"
- "fmt"
- "strings"
-
- "github.com/codefresh-io/venona/venonactl/pkg/logger"
- templates "github.com/codefresh-io/venona/venonactl/pkg/templates/kubernetes"
- "gopkg.in/yaml.v2"
- metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
-)
-
-type runtimeAttachPlugin struct {
- logger logger.Logger
-}
-
-type RuntimeConfiguration struct {
- Crt string `yaml:"crt"`
- Token string `yaml:"token"`
- Host string `yaml:"host"`
- Name string `yaml:"name"`
- Type string `yaml:"type"`
-}
-
-type venonaConf struct {
- Runtimes map[string]RuntimeConfiguration `yaml:"runtimes,omitempty"`
-}
-
-const (
- runtimeAttachFilesPattern = ".*.runtime-attach.yaml"
- runtimeSecretName = "venonaconf"
-)
-
-func buildRuntimeConfig(opt *InstallOptions, v Values) (RuntimeConfiguration, error) {
-
- config, err := opt.KubeBuilder.BuildConfig().ClientConfig()
- if err != nil {
- return RuntimeConfiguration{}, fmt.Errorf("Failed to get client config on runtime cluster: %v", err)
- }
-
- cs, err := opt.KubeBuilder.BuildClient()
- if err != nil {
- return RuntimeConfiguration{}, fmt.Errorf("Failed to create client on runtime cluster: %v", err)
- }
-
- // get default service account for the namespace
- var getOpt metav1.GetOptions
- sa, err := cs.CoreV1().ServiceAccounts(opt.RuntimeClusterName).Get(opt.RuntimeServiceAccount, getOpt)
- if err != nil {
- return RuntimeConfiguration{}, fmt.Errorf("Failed to read service account runtime cluster: %v", err)
- }
-
- secretRef := sa.Secrets[0]
- secret, err := cs.CoreV1().Secrets(opt.RuntimeClusterName).Get(secretRef.Name, getOpt)
- if err != nil {
- return RuntimeConfiguration{}, fmt.Errorf("Failed to get secret from service account on runtime cluster: %v", err)
- }
-
- crt := secret.Data["ca.crt"]
- token := secret.Data["token"]
-
- rc := RuntimeConfiguration{
- Crt: string(crt),
- Token: string(token),
- Host: config.Host,
- Name: opt.RuntimeEnvironment,
- Type: "runtime",
- }
-
- return rc, nil
-}
-
-func readCurrentVenonaConf(agentKubeBuilder KubeClientBuilder, clusterNamespace string) (venonaConf, error) {
-
- cs, err := agentKubeBuilder.BuildClient()
- if err != nil {
- return venonaConf{}, fmt.Errorf("Failed to create client on venona cluster: %v", err)
- }
- secret, err := cs.CoreV1().Secrets(clusterNamespace).Get(runtimeSecretName, metav1.GetOptions{})
-
- conf := &venonaConf{
- Runtimes: make(map[string]RuntimeConfiguration),
- }
- for k, v := range secret.Data {
- cnf := RuntimeConfiguration{}
- if err := yaml.Unmarshal(v, &cnf); err != nil {
- return venonaConf{}, fmt.Errorf("Failed to unmarshal yaml with error: %s", err.Error())
- }
- conf.Runtimes[k] = cnf
- }
- return *conf, nil
-
-}
-
-func (u *runtimeAttachPlugin) Install(opt *InstallOptions, v Values) (Values, error) {
- cs, err := opt.AgentKubeBuilder.BuildClient() // on the agent cluster
- if err != nil {
- u.logger.Error(fmt.Sprintf("Cannot create kubernetes clientset: %v ", err))
- return nil, err
- }
-
- // read current venona conf
- currentVenonaConf, err := readCurrentVenonaConf(opt.AgentKubeBuilder, opt.ClusterNamespace)
- if err != nil {
- u.logger.Error(fmt.Sprintf("Cannot read venonaconf: %v ", err))
- return nil, err
- }
-
- // new runtime configuration
- rc, err := buildRuntimeConfig(opt, v)
- if err != nil {
- return nil, err
- }
- if currentVenonaConf.Runtimes == nil {
- currentVenonaConf.Runtimes = make(map[string]RuntimeConfiguration)
- }
- // normalize the key in the secret to make sure we are not violating kube naming conventions
- name := strings.ReplaceAll(opt.RuntimeEnvironment, "/", ".")
- name = strings.ReplaceAll(name, "@", ".")
- currentVenonaConf.Runtimes[fmt.Sprintf("%s.runtime.yaml", name)] = rc
- runtimes := map[string]string{}
- for name, runtime := range currentVenonaConf.Runtimes {
- // marshel prior persist
- d, err := yaml.Marshal(runtime)
- if err != nil {
- u.logger.Error(fmt.Sprintf("Cannot marshal merged venonaconf: %v ", err))
- return nil, err
- }
-
- runtimes[name] = base64.StdEncoding.EncodeToString([]byte(d))
- }
- v["venonaConf"] = runtimes
-
- cs.CoreV1().Secrets(opt.ClusterNamespace).Delete(runtimeSecretName, &metav1.DeleteOptions{})
-
- err = install(&installOptions{
- logger: u.logger,
- templates: templates.TemplatesMap(),
- templateValues: v,
- kubeClientSet: cs,
- namespace: opt.ClusterNamespace,
- matchPattern: runtimeAttachFilesPattern,
- operatorType: RuntimeAttachType,
- dryRun: opt.DryRun,
- })
-
- if err != nil {
- return nil, err
- }
-
- if opt.RestartAgent {
- list, err := cs.CoreV1().Pods(opt.ClusterNamespace).List(metav1.ListOptions{LabelSelector: fmt.Sprintf("app=%v", v["AppName"])})
- if err != nil {
- u.logger.Error(fmt.Sprintf("Cannot find agent pod: %v ", err))
- return nil, err
- }
- podName := list.Items[0].ObjectMeta.Name
- err = cs.CoreV1().Pods(opt.ClusterNamespace).Delete(podName, &metav1.DeleteOptions{})
- if err != nil {
- u.logger.Error(fmt.Sprintf("Cannot delete agent pod: %v ", err))
- return nil, err
- }
-
- }
-
- return v, nil
-
-}
-
-func (u *runtimeAttachPlugin) Status(statusOpt *StatusOptions, v Values) ([][]string, error) {
-
- cs, err := statusOpt.KubeBuilder.BuildClient()
- if err != nil {
- u.logger.Error(fmt.Sprintf("Cannot create kubernetes clientset: %v ", err))
- return nil, err
- }
- opt := &statusOptions{
- templates: templates.TemplatesMap(),
- templateValues: v,
- kubeClientSet: cs,
- namespace: statusOpt.ClusterNamespace,
- matchPattern: runtimeAttachFilesPattern,
- operatorType: RuntimeAttachType,
- logger: u.logger,
- }
- return status(opt)
-
-}
-
-func (u *runtimeAttachPlugin) Delete(deleteOpt *DeleteOptions, v Values) error {
- cs, err := deleteOpt.AgentKubeBuilder.BuildClient()
- if err != nil {
- u.logger.Error(fmt.Sprintf("Cannot create kubernetes clientset: %v ", err))
- return err
- }
- // Delete the entry from venonaconf - if this is the only , delete the secret
-
- // read current venona conf
- currentVenonaConf, err := readCurrentVenonaConf(deleteOpt.AgentKubeBuilder, deleteOpt.AgentNamespace)
- if err != nil {
- u.logger.Error(fmt.Sprintf("Cannot read venonaconf: %v ", err))
- return err
- }
- name := strings.ReplaceAll(deleteOpt.RuntimeEnvironment, "/", ".")
- name = fmt.Sprintf("%s.runtime.yaml", name)
- if _, ok := currentVenonaConf.Runtimes[name]; ok {
- delete(currentVenonaConf.Runtimes, name)
- }
-
- // If only one runtime is defined, remove the secret , otherwise remove the entry and persist
- shouldDelete := true
- if len(currentVenonaConf.Runtimes) > 0 {
-
- runtimes := map[string]string{}
- for name, runtime := range currentVenonaConf.Runtimes {
- // marshel prior persist
- d, err := yaml.Marshal(runtime)
- if err != nil {
- u.logger.Error(fmt.Sprintf("Cannot marshal merged venonaconf: %v ", err))
- return err
- }
-
- runtimes[name] = base64.StdEncoding.EncodeToString([]byte(d))
- }
-
- shouldDelete = false
- v["venonaConf"] = runtimes
-
- cs.CoreV1().Secrets(deleteOpt.AgentNamespace).Delete(runtimeSecretName, &metav1.DeleteOptions{})
-
- err = install(&installOptions{
- logger: u.logger,
- templates: templates.TemplatesMap(),
- templateValues: v,
- kubeClientSet: cs,
- namespace: deleteOpt.AgentNamespace,
- matchPattern: runtimeAttachFilesPattern,
- operatorType: RuntimeAttachType,
- })
- return err
-
- }
-
- if shouldDelete {
- opt := &deleteOptions{
- templates: templates.TemplatesMap(),
- templateValues: v,
- kubeClientSet: cs,
- namespace: deleteOpt.AgentNamespace,
- matchPattern: runtimeAttachFilesPattern,
- operatorType: RuntimeAttachType,
- logger: u.logger,
- }
- return uninstall(opt)
- }
- return nil
-
-}
-
-func (u *runtimeAttachPlugin) Upgrade(_ *UpgradeOptions, v Values) (Values, error) {
- return v, nil
-}
diff --git a/venonactl/pkg/plugins/runtime-environment.go b/venonactl/pkg/plugins/runtime-environment.go
index fd6c727f..06764da0 100644
--- a/venonactl/pkg/plugins/runtime-environment.go
+++ b/venonactl/pkg/plugins/runtime-environment.go
@@ -71,7 +71,6 @@ func (u *runtimeEnvironmentPlugin) Install(opt *InstallOptions, v Values) (Value
return nil, err
}
- v["RuntimeEnvironment"] = opt.RuntimeEnvironment
err = install(&installOptions{
logger: u.logger,
templates: templates.TemplatesMap(),
@@ -86,6 +85,12 @@ func (u *runtimeEnvironmentPlugin) Install(opt *InstallOptions, v Values) (Value
return nil, err
}
+ re, err := cf.Register()
+ if err != nil {
+ return nil, err
+ }
+ v["RuntimeEnvironment"] = re.Metadata.Name
+
return v, nil
}
@@ -111,7 +116,7 @@ func (u *runtimeEnvironmentPlugin) Delete(deleteOpt *DeleteOptions, v Values) er
cs, err := deleteOpt.KubeBuilder.BuildClient()
if err != nil {
u.logger.Error(fmt.Sprintf("Cannot create kubernetes clientset: %v ", err))
- return err
+ return nil
}
opt := &deleteOptions{
templates: templates.TemplatesMap(),
@@ -122,7 +127,7 @@ func (u *runtimeEnvironmentPlugin) Delete(deleteOpt *DeleteOptions, v Values) er
operatorType: RuntimeEnvironmentPluginType,
logger: u.logger,
}
- return uninstall(opt)
+ return delete(opt)
}
func (u *runtimeEnvironmentPlugin) Upgrade(_ *UpgradeOptions, v Values) (Values, error) {
diff --git a/venonactl/pkg/plugins/venona.go b/venonactl/pkg/plugins/venona.go
index f8666ca6..273c57e1 100644
--- a/venonactl/pkg/plugins/venona.go
+++ b/venonactl/pkg/plugins/venona.go
@@ -39,27 +39,25 @@ const (
// Install venona agent
func (u *venonaPlugin) Install(opt *InstallOptions, v Values) (Values, error) {
- if v["AgentToken"] == "" {
- u.logger.Debug("Generating token for agent")
- tokenName := fmt.Sprintf("generated-%s", time.Now().Format("20060102150405"))
- u.logger.Debug(fmt.Sprintf("Token candidate name: %s", tokenName))
-
- client := codefresh.New(&codefresh.ClientOptions{
- Auth: codefresh.AuthOptions{
- Token: opt.CodefreshToken,
- },
- Host: opt.CodefreshHost,
- })
-
- token, err := client.Tokens().Create(tokenName, v["RuntimeEnvironment"].(string))
- if err != nil {
- return nil, err
- }
- u.logger.Debug("Token created")
- v["AgentToken"] = base64.StdEncoding.EncodeToString([]byte(token.Value))
- if err != nil {
- return nil, err
- }
+ u.logger.Debug("Generating token for agent")
+ tokenName := fmt.Sprintf("generated-%s", time.Now().Format("20060102150405"))
+ u.logger.Debug(fmt.Sprintf("Token candidate name: %s", tokenName))
+
+ client := codefresh.New(&codefresh.ClientOptions{
+ Auth: codefresh.AuthOptions{
+ Token: opt.CodefreshToken,
+ },
+ Host: opt.CodefreshHost,
+ })
+
+ token, err := client.Tokens().Create(tokenName, v["RuntimeEnvironment"].(string))
+ if err != nil {
+ return nil, err
+ }
+ u.logger.Debug("Token created")
+ v["AgentToken"] = base64.StdEncoding.EncodeToString([]byte(token.Value))
+ if err != nil {
+ return nil, err
}
cs, err := opt.KubeBuilder.BuildClient()
@@ -113,7 +111,7 @@ func (u *venonaPlugin) Delete(deleteOpt *DeleteOptions, v Values) error {
matchPattern: venonaFilesPattern,
operatorType: VenonaPluginType,
}
- return uninstall(opt)
+ return delete(opt)
}
func (u *venonaPlugin) Upgrade(opt *UpgradeOptions, v Values) (Values, error) {
@@ -165,7 +163,7 @@ func (u *venonaPlugin) Upgrade(opt *UpgradeOptions, v Values) (Values, error) {
matchPattern: fileName,
operatorType: VenonaPluginType,
}
- err := uninstall(delOpt)
+ err := delete(delOpt)
if err != nil {
return nil, err
}
diff --git a/venonactl/pkg/plugins/volume-provisioner.go b/venonactl/pkg/plugins/volume-provisioner.go
index c0af5164..e670ea00 100644
--- a/venonactl/pkg/plugins/volume-provisioner.go
+++ b/venonactl/pkg/plugins/volume-provisioner.go
@@ -73,7 +73,7 @@ func (u *volumeProvisionerPlugin) Delete(deleteOpt *DeleteOptions, v Values) err
cs, err := deleteOpt.KubeBuilder.BuildClient()
if err != nil {
u.logger.Error(fmt.Sprintf("Cannot create kubernetes clientset: %v ", err))
- return err
+ return nil
}
opt := &deleteOptions{
templates: templates.TemplatesMap(),
@@ -84,7 +84,7 @@ func (u *volumeProvisionerPlugin) Delete(deleteOpt *DeleteOptions, v Values) err
matchPattern: volumeProvisionerFilesPattern,
operatorType: VolumeProvisionerPluginType,
}
- return uninstall(opt)
+ return delete(opt)
}
func (u *volumeProvisionerPlugin) Upgrade(opt *UpgradeOptions, v Values) (Values, error) {
diff --git a/venonactl/pkg/store/store.go b/venonactl/pkg/store/store.go
index b501cc83..f29ffa36 100644
--- a/venonactl/pkg/store/store.go
+++ b/venonactl/pkg/store/store.go
@@ -28,8 +28,6 @@ type (
KubernetesAPI *KubernetesAPI
- AgentAPI *AgentAPI
-
ClusterInCodefresh string
DryRun bool
@@ -55,11 +53,6 @@ type (
BuildNodeSelector map[string]string
}
- AgentAPI struct {
- Token string
- Id string
- }
-
Image struct {
Name string
Tag string
@@ -106,12 +99,9 @@ func (s *Values) BuildValues() map[string]interface{} {
"Tag": "v18",
},
"Namespace": s.KubernetesAPI.Namespace,
- "ConfigPath": s.KubernetesAPI.ConfigPath,
- "Context": s.KubernetesAPI.ContextName,
"NodeSelector": s.KubernetesAPI.NodeSelector,
- "Tolerations": s.KubernetesAPI.Tolerations,
- "AgentToken": s.AgentAPI.Token,
- "AgentId": s.AgentAPI.Id,
+ "Tolerations": s.KubernetesAPI.Tolerations,
+ "AgentToken": "",
"ServerCert": map[string]string{
"Cert": "",
"Key": "",
diff --git a/venonactl/pkg/templates/kubernetes/deployment.venona.yaml b/venonactl/pkg/templates/kubernetes/deployment.venona.yaml
index 19efb02b..4a156937 100644
--- a/venonactl/pkg/templates/kubernetes/deployment.venona.yaml
+++ b/venonactl/pkg/templates/kubernetes/deployment.venona.yaml
@@ -3,7 +3,7 @@ kind: Deployment
metadata:
labels:
app: {{ .AppName }}
- version: {{ .Version }}
+ version: {{ .Version }}
name: {{ .AppName }}
namespace: {{ .Namespace }}
spec:
@@ -24,10 +24,7 @@ spec:
app: {{ .AppName }}
version: {{ .Version }}
spec:
- volumes:
- - name: venonaconf
- secret:
- secretName: venonaconf
+ serviceAccountName: {{ .AppName }}
{{ if ne .NodeSelector "" }}
nodeSelector:
{{ .NodeSelector }}
@@ -53,15 +50,7 @@ spec:
value: {{ .Mode }}
- name: AGENT_NAME
value: {{ .AppName }}
- - name: AGENT_ID
- value: {{ .AgentId }}
- - name: VENONA_CONFIG_DIR
- value: "/etc/secrets"
image: {{ .Image.Name }}:{{ .Image.Tag }}
- volumeMounts:
- - name: venonaconf
- mountPath: "/etc/secrets"
- readOnly: true
imagePullPolicy: Always
name: {{ .AppName }}
restartPolicy: Always
diff --git a/venonactl/pkg/templates/kubernetes/role-binding.re.yaml b/venonactl/pkg/templates/kubernetes/role-binding.venona.yaml
similarity index 89%
rename from venonactl/pkg/templates/kubernetes/role-binding.re.yaml
rename to venonactl/pkg/templates/kubernetes/role-binding.venona.yaml
index 2fec7de1..9ab2db99 100644
--- a/venonactl/pkg/templates/kubernetes/role-binding.re.yaml
+++ b/venonactl/pkg/templates/kubernetes/role-binding.venona.yaml
@@ -6,7 +6,6 @@ metadata:
subjects:
- kind: ServiceAccount
name: {{ .AppName }}
- namespace: {{ .Namespace }}
roleRef:
kind: Role
name: {{ .AppName }}
diff --git a/venonactl/pkg/templates/kubernetes/role.re.yaml b/venonactl/pkg/templates/kubernetes/role.venona.yaml
similarity index 100%
rename from venonactl/pkg/templates/kubernetes/role.re.yaml
rename to venonactl/pkg/templates/kubernetes/role.venona.yaml
diff --git a/venonactl/pkg/templates/kubernetes/secret.runtime-attach.yaml b/venonactl/pkg/templates/kubernetes/secret.runtime-attach.yaml
deleted file mode 100644
index 2861f979..00000000
--- a/venonactl/pkg/templates/kubernetes/secret.runtime-attach.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-apiVersion: v1
-kind: Secret
-type: Opaque
-metadata:
- name: {{ .AppName }}conf
- namespace: {{ .Namespace }}
-data:
-{{ range $key, $value := .venonaConf }}
- {{ $key }}: {{ $value }}
-{{ end }}
\ No newline at end of file
diff --git a/venonactl/pkg/templates/kubernetes/service-account.re.yaml b/venonactl/pkg/templates/kubernetes/service-account.venona.yaml
similarity index 100%
rename from venonactl/pkg/templates/kubernetes/service-account.re.yaml
rename to venonactl/pkg/templates/kubernetes/service-account.venona.yaml
diff --git a/venonactl/pkg/templates/kubernetes/templates.go b/venonactl/pkg/templates/kubernetes/templates.go
index ff756228..29faab5d 100644
--- a/venonactl/pkg/templates/kubernetes/templates.go
+++ b/venonactl/pkg/templates/kubernetes/templates.go
@@ -232,7 +232,7 @@ kind: Deployment
metadata:
labels:
app: {{ .AppName }}
- version: {{ .Version }}
+ version: {{ .Version }}
name: {{ .AppName }}
namespace: {{ .Namespace }}
spec:
@@ -253,10 +253,7 @@ spec:
app: {{ .AppName }}
version: {{ .Version }}
spec:
- volumes:
- - name: venonaconf
- secret:
- secretName: venonaconf
+ serviceAccountName: {{ .AppName }}
{{ if ne .NodeSelector "" }}
nodeSelector:
{{ .NodeSelector }}
@@ -264,7 +261,7 @@ spec:
{{ if ne .Tolerations "" }}
tolerations:
{{ .Tolerations | indent 8 }}
- {{ end }}
+ {{ end }}
containers:
- env:
- name: SELF_DEPLOYMENT_NAME
@@ -282,15 +279,7 @@ spec:
value: {{ .Mode }}
- name: AGENT_NAME
value: {{ .AppName }}
- - name: AGENT_ID
- value: {{ .AgentId }}
- - name: VENONA_CONFIG_DIR
- value: "/etc/secrets"
image: {{ .Image.Name }}:{{ .Image.Tag }}
- volumeMounts:
- - name: venonaconf
- mountPath: "/etc/secrets"
- readOnly: true
imagePullPolicy: Always
name: {{ .AppName }}
restartPolicy: Always
@@ -341,7 +330,7 @@ spec:
`
- templatesMap["role-binding.re.yaml"] = `kind: RoleBinding
+ templatesMap["role-binding.venona.yaml"] = `kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: {{ .AppName }}
@@ -349,13 +338,12 @@ metadata:
subjects:
- kind: ServiceAccount
name: {{ .AppName }}
- namespace: {{ .Namespace }}
roleRef:
kind: Role
name: {{ .AppName }}
apiGroup: rbac.authorization.k8s.io`
- templatesMap["role.re.yaml"] = `kind: Role
+ templatesMap["role.venona.yaml"] = `kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: {{ .AppName }}
@@ -366,17 +354,6 @@ rules:
verbs: ["get", "create", "delete"]
`
- templatesMap["secret.runtime-attach.yaml"] = `apiVersion: v1
-kind: Secret
-type: Opaque
-metadata:
- name: {{ .AppName }}conf
- namespace: {{ .Namespace }}
-data:
-{{ range $key, $value := .venonaConf }}
- {{ $key }}: {{ $value }}
-{{ end }}`
-
templatesMap["secret.venona.yaml"] = `apiVersion: v1
kind: Secret
type: Opaque
@@ -402,7 +379,7 @@ metadata:
name: engine
namespace: {{ .Namespace }}`
- templatesMap["service-account.re.yaml"] = `apiVersion: v1
+ templatesMap["service-account.venona.yaml"] = `apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .AppName }}
@@ -420,16 +397,5 @@ parameters:
volumeBackend: local
`
- templatesMap["venonaconf.secret.venona.yaml"] = `apiVersion: v1
-kind: Secret
-type: Opaque
-metadata:
- name: {{ .AppName }}conf
- namespace: {{ .Namespace }}
-data:
-{{ range $key, $value := .venonaConf }}
- {{ $key }}: {{ $value }}
-{{ end }}`
-
return templatesMap
}
diff --git a/venonactl/pkg/templates/kubernetes/venonaconf.secret.venona.yaml b/venonactl/pkg/templates/kubernetes/venonaconf.secret.venona.yaml
deleted file mode 100644
index 2861f979..00000000
--- a/venonactl/pkg/templates/kubernetes/venonaconf.secret.venona.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-apiVersion: v1
-kind: Secret
-type: Opaque
-metadata:
- name: {{ .AppName }}conf
- namespace: {{ .Namespace }}
-data:
-{{ range $key, $value := .venonaConf }}
- {{ $key }}: {{ $value }}
-{{ end }}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 4282fdc6..337a5c6d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2339,14 +2339,6 @@ js-yaml@^3.10.0, js-yaml@^3.12.0, js-yaml@^3.7.0:
argparse "^1.0.7"
esprima "^4.0.0"
-js-yaml@^3.13.1:
- version "3.13.1"
- resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847"
- integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==
- dependencies:
- argparse "^1.0.7"
- esprima "^4.0.0"
-
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
@@ -2557,11 +2549,6 @@ lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.4, lodash@^4.17.5
version "4.17.11"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.11.tgz#b39ea6229ef607ecd89e2c8df12536891cac9b8d"
-lodash@^4.17.15:
- version "4.17.15"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
- integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
-
long-timeout@0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/long-timeout/-/long-timeout-0.1.1.tgz#9721d788b47e0bcb5a24c2e2bee1a0da55dab514"