packages/constructs/L3/dataops/dataops-nifi-l3-construct/lib/cdk8s/nifi-cluster-chart.ts (819 lines of code) (raw):
/*!
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0
*/
import * as cdk8s from 'cdk8s';
import { Construct } from 'constructs';
import * as fs from 'fs';
import {
NamedNifiRegistryClientProps,
NifiAuthorization,
NifiIdentityAuthorizationOptions,
NifiPolicy,
} from '../nifi-options';
import { ExternalSecretStore } from './external-secret-store';
import * as k8s from './imports/k8s';
// nosemgrep
const { XMLParser, XMLBuilder } = require('fast-xml-parser');
export interface NodeResources {
readonly memory: string;
readonly cpu: string;
}
export interface EfsPersistentVolume {
readonly efsFsId: string;
readonly efsApId: string;
}
export interface NifiClusterChartSamlProps {
readonly idpMetadataUrl: string;
readonly entityId: string;
}
export interface NifiClusterChartProps extends cdk8s.ChartProps, NifiIdentityAuthorizationOptions {
readonly nodeCount: number;
readonly nodeMemory: string;
readonly nodeCpu: string;
readonly nifiImageTag?: string;
readonly awsRegion: string;
readonly adminCredsSecretName: string;
readonly nifiSensitivePropSecretName: string;
readonly keystorePasswordSecretName: string;
readonly externalSecretsRoleArn: string;
readonly efsPersistentVolumes: EfsPersistentVolume[];
readonly efsStorageClassName: string;
readonly saml?: NifiClusterChartSamlProps;
readonly caIssuerName: string;
readonly hostedZoneName: string;
readonly zkConnectString: string;
readonly zkRootNode: string;
readonly httpsPort: number;
readonly remotePort: number;
readonly clusterPort: number;
readonly nifiServiceRoleArn: string;
readonly nifiServiceRoleName: string;
readonly nifiCertDuration: string;
readonly nifiCertRenewBefore: string;
readonly certKeyAlg: string;
readonly certKeySize: number;
readonly nifiManagerImageUri: string;
readonly registryClients?: NamedNifiRegistryClientProps;
}
export class NifiClusterChart extends cdk8s.Chart {
private readonly props: NifiClusterChartProps;
public readonly nodeList: string[];
public readonly domain: string;
private static DEFAULT_NIFI_IMAGE_TAG = '1.25.0';
constructor(scope: Construct, id: string, props: NifiClusterChartProps) {
super(scope, id, props);
this.props = props;
const nodeIds = [...Array(this.props.nodeCount).keys()];
this.nodeList = nodeIds.map(i => {
return `nifi-${i}`;
});
this.domain = `${this.namespace}.${this.props.hostedZoneName}`;
const nifiService = this.createNifiService();
const nifiSecretName = this.createExternalSecrets(props);
const nifiSts = this.createNifiStatefulSet(nifiService, nifiSecretName);
this.createSslResources(nifiService, nifiSts, nifiSecretName);
}
public hash(): string {
const json = JSON.stringify(this.toJson(), undefined, 2);
const stableJson = json.replace(/Token\[.*?\]/g, 'Token');
// nosemgrep
const crypto = require('crypto');
// nosemgrep
const hash = crypto //NOSONAR not used in senstive context
.createHash('sha1') //NOSONAR not used in senstive context
.update(stableJson)
.digest('hex');
return hash;
}
private createExternalSecrets(props: NifiClusterChartProps): string {
const secretStoreChart = new ExternalSecretStore(this, 'secret-store', {
storeName: 'external-secret-store',
...props,
});
const targetSecretName = 'nifi-secret';
new cdk8s.ApiObject(this, 'nifi-external-secret', {
apiVersion: 'external-secrets.io/v1beta1',
kind: 'ExternalSecret',
metadata: {
name: 'nifi-external-secret',
},
spec: {
refreshInterval: '1h',
secretStoreRef: {
name: secretStoreChart.secretStoreName,
kind: 'SecretStore',
},
target: {
name: targetSecretName,
creationPolicy: 'Owner',
},
data: [
{
secretKey: 'admin-creds',
remoteRef: {
key: props.adminCredsSecretName,
},
},
{
secretKey: 'sensitive-props-key',
remoteRef: {
key: props.nifiSensitivePropSecretName,
},
},
{
secretKey: 'keystore-password',
remoteRef: {
key: props.keystorePasswordSecretName,
},
},
],
},
});
return targetSecretName;
}
private createSslResources(nifiService: k8s.KubeService, nifiSts: k8s.KubeStatefulSet, nifiSecretName: string) {
const clusterManagerCert = new cdk8s.ApiObject(this, `manager-cert`, {
apiVersion: 'cert-manager.io/v1',
kind: 'Certificate',
metadata: {
name: `manager-cert`,
},
spec: {
isCA: false,
commonName: `cluster-manager.${this.namespace}`,
secretName: `manager-ssl`,
privateKey: {
algorithm: this.props.certKeyAlg,
encoding: 'PKCS1',
size: this.props.certKeySize,
},
usages: ['server auth', 'client auth'],
issuerRef: {
name: this.props.caIssuerName,
kind: 'ClusterIssuer',
},
keystores: {
jks: {
create: true,
passwordSecretRef: {
name: nifiSecretName,
key: 'keystore-password',
},
},
},
duration: this.props.nifiCertDuration,
renewBefore: this.props.nifiCertRenewBefore,
},
});
const nodeCerts = [...Array(this.props.nodeCount).keys()].map(i => {
return new cdk8s.ApiObject(this, `${nifiSts.name}-${i}-cert`, {
apiVersion: 'cert-manager.io/v1',
kind: 'Certificate',
metadata: {
name: `${nifiSts.name}-${i}-cert`,
},
spec: {
isCA: false,
commonName: `${nifiSts.name}-${i}.${this.namespace}`,
dnsNames: [
'localhost',
`${nifiSts.name}-${i}.${nifiService.name}.${this.namespace}.svc.cluster.local`,
`${nifiSts.name}-${i}.${this.namespace}.${this.props.hostedZoneName}`,
],
secretName: `${nifiSts.name}-${i}-ssl`,
privateKey: {
algorithm: this.props.certKeyAlg,
encoding: 'PKCS1',
size: this.props.certKeySize,
},
usages: ['server auth', 'client auth'],
issuerRef: {
name: this.props.caIssuerName,
kind: 'ClusterIssuer',
},
keystores: {
jks: {
create: true,
passwordSecretRef: {
name: nifiSecretName,
key: 'keystore-password',
},
},
},
duration: this.props.nifiCertDuration,
renewBefore: this.props.nifiCertRenewBefore,
},
});
});
return [clusterManagerCert, nodeCerts];
}
private createNifiService(): k8s.KubeService {
const nifiServiceProps: k8s.KubeServiceProps = {
metadata: {
name: 'nifi-svc',
labels: {
app: 'nifi',
},
annotations: {
'external-dns.alpha.kubernetes.io/hostname': `${this.namespace}.${this.props.hostedZoneName}`,
'external-dns.alpha.kubernetes.io/ttl': '60',
},
},
spec: {
ports: [
{
port: this.props.httpsPort,
name: 'nifi-ui',
},
],
clusterIp: 'None',
selector: {
app: 'nifi',
},
},
};
return new k8s.KubeService(this, 'nifi-svc', nifiServiceProps);
}
private createNifiStatefulSet(nifiService: k8s.KubeService, nifiSecretName: string): k8s.KubeStatefulSet {
// nosemgrep
const nifiInitScriptsConfigMapData = Object.fromEntries(
fs.readdirSync(`${__dirname}/../../scripts/nifi`).map(fileName => {
// nosemgrep
return [fileName, fs.readFileSync(`${__dirname}/../../scripts/nifi/${fileName}`, 'utf-8')];
}),
);
const nifiInitConfigMap = new k8s.KubeConfigMap(this, 'nifi-init-configmap', {
metadata: {
name: 'nifi-init-scripts',
},
data: nifiInitScriptsConfigMapData,
});
let volId = 0;
const pvs = this.props.efsPersistentVolumes.map(efsPvProps => {
const pv = new k8s.KubePersistentVolume(this, `nifi-persistent-volume-${volId}`, {
metadata: {
name: `nifi-vol-${efsPvProps.efsFsId}-${efsPvProps.efsApId}`,
labels: {
app: 'nifi',
},
},
spec: {
volumeMode: 'Filesystem',
capacity: {
storage: k8s.Quantity.fromString('60Gi'),
},
accessModes: ['ReadWriteOnce'],
persistentVolumeReclaimPolicy: 'Retain',
storageClassName: this.props.efsStorageClassName,
csi: {
driver: 'efs.csi.aws.com',
volumeHandle: `${efsPvProps.efsFsId}::${efsPvProps.efsApId}`,
},
claimRef: {
name: `nifi-data-nifi-${volId}`,
namespace: this.namespace,
},
},
});
volId = volId + 1;
return pv;
});
const sslBasePath = '/opt/nifi/ssl';
const nifiDataDir = '/opt/nifi/data';
const nifiInitBaseDir = '/opt/nifi/init';
const nifiConfigMap = this.createNifiConfigMap(sslBasePath, nifiDataDir);
const sslSecretVolumes: [k8s.Volume, k8s.VolumeMount][] = this.nodeList.map(hostname => {
const volume: k8s.Volume = {
name: `${hostname}-ssl`,
secret: {
secretName: `${hostname}-ssl`,
},
};
const mount: k8s.VolumeMount = {
mountPath: `${sslBasePath}/${hostname}`,
name: volume.name,
readOnly: true,
};
return [volume, mount];
});
const serviceAccount = new k8s.KubeServiceAccount(this, 'nifi-service-account', {
metadata: {
name: 'nifi',
annotations: {
'eks.amazonaws.com/role-arn': this.props.nifiServiceRoleArn,
},
},
});
const nifiStsProps: k8s.KubeStatefulSetProps = {
metadata: {
name: 'nifi',
},
spec: {
podManagementPolicy: 'Parallel',
serviceName: nifiService.name,
replicas: this.props.nodeCount,
selector: {
matchLabels: {
app: 'nifi',
},
},
persistentVolumeClaimRetentionPolicy: {
whenDeleted: 'Retain',
whenScaled: 'Delete',
},
volumeClaimTemplates: [
{
metadata: {
name: 'nifi-data',
},
spec: {
selector: {
matchLabels: {
app: 'nifi',
},
},
storageClassName: this.props.efsStorageClassName,
accessModes: ['ReadWriteOnce'],
resources: {
requests: {
storage: k8s.Quantity.fromString('5Gi'),
},
},
},
},
],
template: {
metadata: {
labels: {
app: 'nifi',
},
},
spec: {
serviceAccountName: serviceAccount.name,
tolerations: [
{
key: 'eks.amazonaws.com/compute-type',
value: 'fargate',
},
],
dnsConfig: {
searches: [`${nifiService.name}.${this.namespace}.svc.cluster.local`],
},
securityContext: {
runAsUser: 1000,
runAsGroup: 1000,
fsGroup: 1000,
},
volumes: [
{
name: 'nifi-init-scripts',
configMap: {
name: nifiInitConfigMap.name,
defaultMode: 0o755,
},
},
{
name: 'nifi-config',
configMap: {
name: nifiConfigMap.name,
defaultMode: 0o755,
},
},
{
name: 'aws-creds',
emptyDir: {},
},
{
name: 'pip-local',
emptyDir: {},
},
{
name: `manager-ssl`,
secret: {
secretName: `manager-ssl`,
},
},
...sslSecretVolumes.map(x => x[0]),
],
shareProcessNamespace: true,
containers: [
{
name: 'nifi-manager',
image: this.props.nifiManagerImageUri,
command: ['sh', `/opt/nifi/scripts/nifi_manager.sh`],
resources: {
requests: {
memory: k8s.Quantity.fromString('0.5Gi'),
cpu: k8s.Quantity.fromString('250m'),
},
limits: {
memory: k8s.Quantity.fromString('0.5Gi'),
cpu: k8s.Quantity.fromString('250m'),
},
},
env: [
{
name: 'NIFI_APP',
value: 'nifi',
},
{
name: 'MANAGER_CONFIG',
value: `${nifiInitBaseDir}/conf/nifi_manager.json`,
},
{
name: 'NIFI_INIT_DIR',
value: nifiInitBaseDir,
},
{
name: 'NIFI_DATA_DIR',
value: nifiDataDir,
},
{
name: 'NIFI_SENSITIVE_PROPS_KEY',
valueFrom: {
secretKeyRef: {
name: nifiSecretName,
key: 'sensitive-props-key',
optional: false,
},
},
},
{
name: 'NIFI_SSL_BASE_PATH',
value: sslBasePath,
},
{
name: 'NIFI_ZOOKEEPER_CONNECT_STRING',
value: this.props.zkConnectString,
},
{
name: 'NIFI_KEYSTORE_PASSWORD',
valueFrom: {
secretKeyRef: {
name: nifiSecretName,
key: 'keystore-password',
optional: false,
},
},
},
{
name: 'NIFI_TRUSTSTORE_PASSWORD',
valueFrom: {
secretKeyRef: {
name: nifiSecretName,
key: 'keystore-password',
optional: false,
},
},
},
{
name: 'PYTHONUNBUFFERED',
value: '1',
},
{
name: 'NIFI_NODES',
value: this.nodeList.map(x => `CN=${x}.${this.namespace}.${this.props.hostedZoneName}`).join(','),
},
],
volumeMounts: [
{
name: 'nifi-config',
mountPath: `${nifiInitBaseDir}/conf`,
},
{
name: 'aws-creds',
mountPath: `/home/nifi/.aws`,
},
{
name: 'pip-local',
mountPath: `/.local`,
},
{
name: 'nifi-init-scripts',
mountPath: `${nifiInitBaseDir}/scripts`,
},
{
name: 'nifi-data',
mountPath: `${nifiDataDir}`,
},
{
mountPath: `${sslBasePath}/manager`,
name: 'manager-ssl',
readOnly: true,
},
...sslSecretVolumes.map(x => x[1]),
],
},
{
name: 'nifi',
image: `apache/nifi:${this.props.nifiImageTag ?? NifiClusterChart.DEFAULT_NIFI_IMAGE_TAG}`,
ports: [{ containerPort: this.props.httpsPort }],
command: ['bash', '-c', `${nifiInitBaseDir}/scripts/nifi_start.sh`],
resources: {
requests: {
memory: k8s.Quantity.fromString(this.props.nodeMemory),
cpu: k8s.Quantity.fromString(this.props.nodeCpu),
},
limits: {
memory: k8s.Quantity.fromString(this.props.nodeMemory),
cpu: k8s.Quantity.fromString(this.props.nodeCpu),
},
},
env: [
{
name: 'NIFI_INIT_DIR',
value: nifiInitBaseDir,
},
{
name: 'NIFI_DATA_DIR',
value: nifiDataDir,
},
{
name: 'NIFI_HOME',
value: '/opt/nifi/nifi-current',
},
{
name: 'NIFI_SENSITIVE_PROPS_KEY',
valueFrom: {
secretKeyRef: {
name: nifiSecretName,
key: 'sensitive-props-key',
optional: false,
},
},
},
{
name: 'NIFI_SSL_BASE_PATH',
value: sslBasePath,
},
{
name: 'NIFI_ZOOKEEPER_CONNECT_STRING',
value: this.props.zkConnectString,
},
{
name: 'NIFI_KEYSTORE_PASSWORD',
valueFrom: {
secretKeyRef: {
name: nifiSecretName,
key: 'keystore-password',
optional: false,
},
},
},
{
name: 'NIFI_TRUSTSTORE_PASSWORD',
valueFrom: {
secretKeyRef: {
name: nifiSecretName,
key: 'keystore-password',
optional: false,
},
},
},
],
volumeMounts: [
{
name: 'nifi-config',
mountPath: `${nifiInitBaseDir}/conf`,
},
{
name: 'nifi-init-scripts',
mountPath: `${nifiInitBaseDir}/scripts`,
},
{
name: 'nifi-data',
mountPath: `${nifiDataDir}`,
},
{
name: 'aws-creds',
mountPath: `/home/nifi/.aws`,
},
...sslSecretVolumes.map(x => x[1]),
],
},
],
},
},
},
};
const sts = new k8s.KubeStatefulSet(this, 'nifi-sts', nifiStsProps);
pvs.forEach(pv => {
sts.addDependency(pv);
});
return sts;
}
private createNifiConfigMap(sslBasePath: string, nifiDataDir: string): k8s.KubeConfigMap {
// nosemgrep
const nifiBaseConfigMapData = Object.fromEntries(
fs.readdirSync(`${__dirname}/../../base_conf/nifi`).map(fileName => {
// nosemgrep
return [fileName, fs.readFileSync(`${__dirname}/../../base_conf/nifi/${fileName}`, 'utf-8')];
}),
);
const nifiConfigMap = new k8s.KubeConfigMap(this, 'nifi-configmap', {
metadata: {
name: 'nifi-config',
},
data: {
...nifiBaseConfigMapData,
'nifi.properties': this.updateNifiProperties(nifiBaseConfigMapData['nifi.properties'], nifiDataDir),
'authorizers.xml': this.updateAuthorizers(nifiBaseConfigMapData['authorizers.xml'], nifiDataDir),
'nifi-cli.config': NifiClusterChart.createNifiToolkitConfig(
sslBasePath,
`INIT_HOSTNAME.${this.namespace}.${this.props.hostedZoneName}`,
this.props.httpsPort,
),
'nifi_manager.json': JSON.stringify(this.createManagerConfig(), undefined, 2),
},
});
return nifiConfigMap;
}
private createManagerConfig() {
const clusterNodeIdentities = this.nodeList.map(x => `CN=${x}.${this.namespace}.${this.props.hostedZoneName}`);
return {
registry_clients: this.props.registryClients,
...this.createIdentityAuthorizationsConfig(clusterNodeIdentities),
};
}
private createIdentityAuthorizationsConfig(clusterNodeIdentities: string[]) {
const additionalGroups: { [name: string]: string[] } = {};
additionalGroups['cluster_nodes'] = clusterNodeIdentities;
const clusterNodeAuthorizations: NifiAuthorization[] = [
{
policyResourcePattern: '/data/.*',
actions: ['READ', 'WRITE'],
groups: ['cluster_nodes'],
},
];
additionalGroups['admins'] = this.props.adminIdentities;
const adminPolicies: NifiPolicy[] = [
{
resource: '/process-groups/ROOT_ID',
action: 'READ',
},
{
resource: '/process-groups/ROOT_ID',
action: 'WRITE',
},
];
const adminAuthorizations: NifiAuthorization[] = [
{
policyResourcePattern: '/.*',
actions: ['READ', 'WRITE'],
groups: ['admins'],
},
];
if (this.props.externalNodeIdentities) {
additionalGroups['external_nodes'] = this.props.externalNodeIdentities;
}
const externalNodeAuthorizations: NifiAuthorization[] = this.props.externalNodeIdentities
? [
{
policyResourcePattern: '/site-to-site',
actions: ['READ'],
groups: ['external_nodes'],
},
{
policyResourcePattern: '/data-transfer/.*',
actions: ['READ', 'WRITE'],
groups: ['external_nodes'],
},
]
: [];
const remotePolicies: NifiPolicy[] = [
{
resource: '/site-to-site',
action: 'READ',
},
];
return {
identities: [
...(this.props.identities || []),
...clusterNodeIdentities,
...this.props.adminIdentities,
...(this.props.externalNodeIdentities || []),
],
groups: { ...(this.props.groups || {}), ...additionalGroups },
policies: [...(this.props.policies || []), ...remotePolicies, ...adminPolicies],
authorizations: [
...(this.props.authorizations || []),
...clusterNodeAuthorizations,
...adminAuthorizations,
...externalNodeAuthorizations,
],
};
}
private updateAuthorizers(authorizersData: string, nifiDataDir: string): string {
const authorizersXmlObj = new XMLParser({
ignoreAttributes: false,
alwaysCreateTextNode: true,
}).parse(authorizersData);
interface XmlProp {
'@_name': string;
'#text': string;
}
const userGroupProviderProps: XmlProp[] = authorizersXmlObj['authorizers']['userGroupProvider']['property'];
userGroupProviderProps.forEach(prop => {
if (prop['@_name'] == 'Users File') {
prop['#text'] = `${nifiDataDir}/users.xml`;
} else if (prop['@_name'] == 'Initial User Identity 1') {
prop['#text'] = `CN=cluster-manager.${this.namespace}`;
}
});
const accessPolicyProviderProps: XmlProp[] = authorizersXmlObj['authorizers']['accessPolicyProvider']['property'];
accessPolicyProviderProps.forEach(prop => {
if (prop['@_name'] == 'Authorizations File') {
prop['#text'] = `${nifiDataDir}/authorizations.xml`;
} else if (prop['@_name'] == 'Initial Admin Identity') {
prop['#text'] = `CN=cluster-manager.${this.namespace}`;
}
});
this.nodeList.forEach(node => {
const fullNode = `${node}.${this.namespace}.${this.props.hostedZoneName}`;
userGroupProviderProps.push({
'@_name': `Initial User Identity ${fullNode}`,
'#text': `CN=${fullNode}`,
});
accessPolicyProviderProps.push({
'@_name': `Node Identity ${fullNode}`,
'#text': `CN=${fullNode}`,
});
});
const authorizersXml: string = new XMLBuilder({
ignoreAttributes: false,
format: true,
}).build(authorizersXmlObj);
return authorizersXml;
}
private updateNifiProperties(nifiPropertiesData: string, nifiDataDir: string): string {
const nifiPropertiesMap: { [key: string]: string } = Object.fromEntries(
nifiPropertiesData
.split('\n')
.filter(line => {
return !/^\s*#/.test(line) && !/^\s*$/.test(line);
})
.map(line => {
return [line.split(/=(.*)/s)[0], line.split(/=(.*)/s)[1]];
}),
);
//perform config-driven overrides here
nifiPropertiesMap['nifi.sensitive.props.key'] = 'INIT_SENSITIVE_PROPS_KEY';
nifiPropertiesMap['nifi.flow.configuration.file'] = `${nifiDataDir}/flow.xml.gz`;
nifiPropertiesMap['nifi.flow.configuration.json.file'] = `${nifiDataDir}/flow.json.gz`;
nifiPropertiesMap['nifi.flow.configuration.archive.dir'] = `${nifiDataDir}/flow_archive/`;
nifiPropertiesMap['nifi.templates.directory'] = `${nifiDataDir}/templates`;
nifiPropertiesMap['nifi.database.directory'] = `${nifiDataDir}/database_repository`;
nifiPropertiesMap['nifi.flowfile.repository.directory'] = `${nifiDataDir}/flowfile_repository`;
nifiPropertiesMap['nifi.content.repository.directory.default'] = `${nifiDataDir}/content_repository`;
nifiPropertiesMap['nifi.provenance.repository.directory.default'] = `${nifiDataDir}/provenance_repository`;
nifiPropertiesMap['nifi.status.repository.questdb.persist.location'] = `${nifiDataDir}/status_repository`;
nifiPropertiesMap['nifi.diagnostics.on.shutdown.directory'] = `${nifiDataDir}/diagnostics`;
nifiPropertiesMap['nifi.web.https.port'] = this.props.httpsPort.toString();
nifiPropertiesMap['nifi.web.https.host'] = `INIT_HOSTNAME.${this.namespace}.${this.props.hostedZoneName}`;
nifiPropertiesMap['nifi.web.http.port'] = '';
nifiPropertiesMap['nifi.web.http.host'] = '';
nifiPropertiesMap['nifi.remote.input.host'] = `INIT_HOSTNAME.${this.namespace}.${this.props.hostedZoneName}`;
nifiPropertiesMap['nifi.remote.input.socket.port'] = this.props.remotePort.toString();
nifiPropertiesMap['nifi.remote.input.secure'] = 'true';
nifiPropertiesMap['nifi.cluster.protocol.is.secure'] = 'true';
nifiPropertiesMap['nifi.cluster.is.node'] = 'true';
nifiPropertiesMap['nifi.cluster.node.address'] = `INIT_HOSTNAME.${this.namespace}.${this.props.hostedZoneName}`;
nifiPropertiesMap['nifi.cluster.node.protocol.port'] = this.props.clusterPort.toString();
nifiPropertiesMap['nifi.cluster.leader.election.implementation'] = 'CuratorLeaderElectionManager';
nifiPropertiesMap['nifi.cluster.flow.election.max.wait.time'] = '150 secs';
nifiPropertiesMap['nifi.state.management.provider.cluster'] = 'zk-provider';
nifiPropertiesMap['nifi.zookeeper.connect.string'] = this.props.zkConnectString;
nifiPropertiesMap['nifi.zookeeper.root.node'] = this.props.zkRootNode;
nifiPropertiesMap['nifi.zookeeper.client.secure'] = 'true';
nifiPropertiesMap['nifi.security.keystore'] = `${nifiDataDir}/ssl/keystore/keystore.jks`;
nifiPropertiesMap['nifi.security.keystoreType'] = 'JKS';
nifiPropertiesMap['nifi.security.keystorePasswd'] = 'INIT_KEYSTORE_PASSWORD'; //NOSONAR placeholder value replaced at runtime
nifiPropertiesMap['nifi.security.keyPasswd'] = 'INIT_KEYSTORE_PASSWORD'; //NOSONAR placeholder value replaced at runtime
nifiPropertiesMap['nifi.security.truststore'] = `${nifiDataDir}/ssl/truststore/truststore.jks`;
nifiPropertiesMap['nifi.security.truststoreType'] = 'JKS';
nifiPropertiesMap['nifi.security.truststorePasswd'] = 'INIT_TRUSTSTORE_PASSWORD'; //NOSONAR placeholder value replaced at runtime
nifiPropertiesMap['nifi.security.user.authorizer'] = 'managed-authorizer';
nifiPropertiesMap['nifi.security.autoreload.enabled'] = 'true';
nifiPropertiesMap['nifi.security.autoreload.interval'] = '10 secs';
if (this.props.saml) {
nifiPropertiesMap['nifi.security.user.saml.idp.metadata.url'] = this.props.saml?.idpMetadataUrl;
nifiPropertiesMap['nifi.security.user.saml.sp.entity.id'] = this.props.saml?.entityId;
nifiPropertiesMap['nifi.security.user.login.identity.provider'] = '';
} else {
nifiPropertiesMap['nifi.security.user.login.identity.provider'] = 'single-user-provider';
}
const nifiProperties = Object.entries(nifiPropertiesMap)
.map(entry => {
return `${entry[0]}=${entry[1]}`;
})
.join('\n');
return nifiProperties;
}
public static createNifiToolkitConfig(sslBasePath: string, hostname: string, httpsPort: number): string {
const toolkitConfigMap: { [key: string]: string } = {
baseUrl: `https://${hostname}:${httpsPort.toString()}`,
keystore: `${sslBasePath}/manager/keystore.jks`,
keystoreType: 'JKS',
keystorePasswd: 'INIT_KEYSTORE_PASSWORD', //NOSONAR placeholder value replaced at runtime
keyPasswd: 'INIT_KEYSTORE_PASSWORD', //NOSONAR placeholder value replaced at runtime
truststore: `${sslBasePath}/manager/truststore.jks`,
truststoreType: 'JKS',
truststorePasswd: 'INIT_KEYSTORE_PASSWORD', //NOSONAR placeholder value replaced at runtime
};
const toolkitConfig = Object.entries(toolkitConfigMap)
.map(entry => {
return `${entry[0]}=${entry[1]}`;
})
.join('\n');
return toolkitConfig;
}
}