Skip to main content
Version: v1.6.0

v0.7.x to v0.8.0

Guide to migrate operator resources built using nifi.orange.com/v1alpha1 to nifi.konpyutaika/v1alpha1.

Getting started

The goal is to migrate your NiFiKop resources from the old CRDs to the new ones without any service interruption.

To do this, it is necessary to have both versions of CRDs available on Kubernetes and to have the old operator stopped (to prevent any manipulation on the resources). Then launch the script developed in nodejs presented in the following. The script will copy the resources in the old CRDs to the new CRDs keeping only the relevant fields (labels, annotations, name and spec) and then copy the status.

Prerequisites

Initial setup

Create a nodejs project and download the required dependencies:

npm init -y
npm install @kubernetes/client-node@0.16.3 minimist@1.2.6

In package.json add the following script:

"start": "node --no-warnings index.js"

Your package.json should look like that:

{
"name": "nifikop_crd_migration",
"version": "1.0.0",
"description": "Script to migrate from the old CRDs to the new CRDs.",
"main": "index.js",
"scripts": {
"start": "node --no-warnings index.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [
"K8S",
"NiFiKop",
"CRDs"
],
"license": "ISC",
"dependencies": {
"@kubernetes/client-node": "^0.16.3",
"minimist": "^1.2.6"
}
}

Script setup

Create the file index.js with the following content:

process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = 0;
const k8s = require('@kubernetes/client-node');

const kc = new k8s.KubeConfig();
kc.loadFromDefault();

const k8sApi = kc.makeApiClient(k8s.CustomObjectsApi);

const KONPYUTAIKA_GROUP = 'nifi.konpyutaika.com';
const KONPYUTAIKA_GROUP_VERSION = 'v1alpha1';
const ORANGE_GROUP = 'nifi.orange.com';
const ORANGE_GROUP_VERSION = 'v1alpha1';

const call = async (SRC_GRP, SRC_GRP_VER, DST_GRP, DST_GRP_VER, KIND_PLURAL, NAMESPACE) => {
console.log(`Listing ${KIND_PLURAL} of ${SRC_GRP}/${SRC_GRP_VER} in ${NAMESPACE}...`);
const listResources = (await k8sApi.listNamespacedCustomObject(SRC_GRP, SRC_GRP_VER, NAMESPACE, KIND_PLURAL)).body.items;
return Promise.all(listResources.map(async (resource) => {
try {
console.log(`Found ${resource.kind} "${resource.metadata.name}" of ${resource.apiVersion} in ${NAMESPACE}`);

if (resource.metadata.ownerReferences) {
console.log(`${resource.kind} ${resource.metadata.name} mananged by something else (ownerRefereces is set).`);
return;
}

const bodyResource = {
apiVersion: `${DST_GRP}/${DST_GRP_VER}`,
kind: resource.kind,
metadata: {
name: resource.metadata.name,
annotations: resource.metadata.annotations,
labels: resource.metadata.labels
},
spec: resource.spec
};

console.log(`Creating ${bodyResource.kind} "${bodyResource.metadata.name}" of ${bodyResource.apiVersion} in ${NAMESPACE}...`);
const newResource = (await k8sApi.createNamespacedCustomObject(DST_GRP, DST_GRP_VER, NAMESPACE, KIND_PLURAL, bodyResource)).body;
console.log('...done creating.');

const bodyStatus = {
apiVersion: newResource.apiVersion,
kind: newResource.kind,
metadata: {
name: newResource.metadata.name,
resourceVersion: newResource.metadata.resourceVersion
},
status: resource.status
};

console.log(`Copying status from ${resource.kind} "${resource.metadata.name}" of ${newResource.apiVersion} to ${newResource.kind} "${newResource.metadata.name}" of ${newResource.apiVersion} in ${NAMESPACE}...`);
const newResourceWithStatus = (await k8sApi.replaceNamespacedCustomObjectStatus(DST_GRP, DST_GRP_VER, NAMESPACE, KIND_PLURAL, bodyStatus.metadata.name, bodyStatus)).body;
console.log('...done copying.');
return newResourceWithStatus;
}
catch (e) {
console.error(e.body ? e.body.message ? e.body.message : e.body : e);
}
}));
};

const argv = require('minimist')(process.argv.slice(2));

let NAMESPACE = argv.namespace ? argv.namespace.length > 0 ? argv.namespace : 'default' : 'default';
let KIND_PLURAL = {
cluster: 'nificlusters',
dataflow: 'nifidataflows',
parametercontext: 'nifiparametercontexts',
registryclient: 'nifiregistryclients',
user: 'nifiusers',
usergroup: 'nifiusergroups',
};

if (!argv.type) {
console.error('Type not provided');
process.exit(1);
}

if (!KIND_PLURAL[argv.type]) {
console.error(`Type ${argv.type} is not one of the following types: ${Object.keys(KIND_PLURAL)}`);
process.exit(1);
}

console.log(`########### START: ${KIND_PLURAL[argv.type]} ###########`);
call( ORANGE_GROUP, ORANGE_GROUP_VERSION, KONPYUTAIKA_GROUP, KONPYUTAIKA_GROUP_VERSION, KIND_PLURAL[argv.type], NAMESPACE)
.then(r => console.log('############ END ############'))
.catch(e => console.error(e));

Run script

To migrate the resources, run the following command:

npm start -- --type=<NIFIKOP_RESOURCE> --namespace=<K8S_NAMESPACE>

with

  • <NIFIKOP_RESOURCE>: NiFiKop resource type (cluster, dataflow, user, usergroup, parametercontext or registryclient)
  • <K8S_NAMESPACE>: Kubernetes namespace where the resources will be migrated