def extract_crypto(opts, node_type, verbose=False): # Get chart type chart = NODE_MAPPER[node_type] node_namespace = get_namespace(opts, opts[node_type + 's']['msp']) for release in opts[node_type + 's']['names']: pod_ex = get_pod(node_namespace, release, chart) # Secrets crypto_info = [ CryptoInfo('idcert', 'signcerts', 'cert.pem', True), CryptoInfo('idkey', 'keystore', 'key.pem', True), CryptoInfo('cacert', 'cacerts', 'cacert.pem', True), CryptoInfo('caintcert', 'intermediatecerts', 'intermediatecacert.pem', False) ] for item in crypto_info: secret_name = 'hlf--{}-{}'.format(release, item.secret_type) try: secret_read(secret_name, node_namespace) if verbose: print('{} secret already exists'.format(secret_name)) except ApiException: command = "bash -c 'ls /var/hyperledger/msp/{}' | wc -l".format(item.subfolder) file_num = pod_ex.execute(command) if file_num.strip() != '1': if item.required: raise ValueError('We should only have 1 file in each of these folders') else: print('Wrong number of files in {} directory'.format(item.subfolder)) else: command = "bash -c 'cat /var/hyperledger/msp/{}/*'".format(item.subfolder) content = pod_ex.execute(command) secret_data = { item.key: content } secret_create(secret_data, secret_name, node_namespace, verbose=verbose)
def test_secret_read_unicode(self, mock_api, mock_pretty_print): mock_api.read_namespaced_secret.side_effect = [ Secret({"a_key": b"YV92YWx1ZYE="}) ] secret_read("a_secret", "a-namespace") mock_api.read_namespaced_secret.assert_called_once_with( name="a_secret", namespace="a-namespace") mock_pretty_print.assert_called_once_with('{"a_key": "a_value"}')
def test_secret_read_unicode(self, mock_api, mock_pretty_print): mock_api.read_namespaced_secret.side_effect = [ Secret({'a_key': b'YV92YWx1ZYE='}) ] secret_read('a_secret', 'a-namespace', verbose=True) mock_api.read_namespaced_secret.assert_called_once_with( name='a_secret', namespace='a-namespace') mock_pretty_print.assert_called_once_with('{"a_key": "a_value"}')
def test_secret_read(self, mock_api, mock_pretty_print): mock_api.read_namespaced_secret.side_effect = [ Secret({'a_key': b'YV92YWx1ZQ=='}) ] secret_read('a_secret', 'a-namespace') mock_api.read_namespaced_secret.assert_called_once_with( name='a_secret', namespace='a-namespace') mock_pretty_print.assert_not_called()
def test_secret_read(self, mock_api, mock_pretty_print): mock_api.read_namespaced_secret.side_effect = [ Secret({"a_key": b"YV92YWx1ZQ=="}) ] secret_read("a_secret", "a-namespace") mock_api.read_namespaced_secret.assert_called_once_with( name="a_secret", namespace="a-namespace") mock_pretty_print.assert_not_called()
def credentials_secret(secret_name, namespace, username, password=None, verbose=False): """Create a CA credentials secret. Args: secret_name (str): Name of secret. namespace (str): Namespace for secret to be located. username (str): Username for credentials secret. password (str): Password for credentials secret. verbose (bool): Verbosity. False by default. Returns: dict: Secret data including "CA_USERNAME" and "CA_PASSWORD" """ try: secret_data = secret_read(secret_name, namespace, verbose=verbose) # Check that the ID stored is the same as Orderer name assert username == secret_data["CA_USERNAME"] if password: assert password == secret_data["CA_PASSWORD"] except ApiException: # Get relevant variables if not password: password = rand_string(24) secret_data = {"CA_USERNAME": username, "CA_PASSWORD": password} secret_create(secret_data, secret_name, namespace) return secret_data
def helm_env_vars(namespace, env_vars, preserve=None, verbose=False): if not env_vars: env_vars = [] else: env_vars = list(env_vars) for i, item in enumerate(env_vars): if isinstance(item, tuple): item = HelmSet(*item) elif not isinstance(item, HelmSet): raise TypeError( 'Items in env_vars array must be HelmSet named tuples') env_vars[i] = item # Any data we need to preserve during upgrade? if preserve: for item in preserve: if isinstance(item, tuple): item = HelmPreserve(*item) elif not isinstance(item, HelmPreserve): raise TypeError( 'Items in preserve array must be HelmPerserve named tuples' ) secret_data = secret_read(item.secret_name, namespace, verbose=verbose) env_vars.append( HelmSet(item.values_path, secret_data[item.data_item])) # Environmental variables env_vars_string = ''.join([ ' --set{} {}={}'.format('-string' if item.set_string else '', item.key, item.value) for item in env_vars ]) return env_vars_string
def helm_preserve(namespace, preserve, verbose=False): """Convert secret data to a "--set" string for Helm deployments. Args: namespace (str): Namespace where preserved secrets are located. preserve (tuple): Set of secrets we wish to get data from to assign to the Helm Chart. verbose (bool): Verbosity. False by default. Returns: str: String containing variables to be set with Helm release. """ # Any data we need to preserve during upgrade? if not preserve: return "" env_vars = [] for item in preserve: if isinstance(item, tuple): item = HelmPreserve(*item) elif not isinstance(item, HelmPreserve): raise TypeError( "Items in preserve array must be HelmPerserve named tuples") secret_data = secret_read(item.secret_name, namespace, verbose=verbose) env_vars.append(HelmSet(item.values_path, secret_data[item.data_item])) # Environmental variables # TODO: This may well be its own subfunction env_vars_string = "".join([ " --set{} {}={}".format("-string" if item.set_string else "", item.key, item.value) for item in env_vars ]) return env_vars_string
def helm_preserve(preserve): """Convert secret data to a "--set" string for Helm deployments. Args: preserve (Iterable): Set of secrets we wish to get data from to assign to the Helm Chart. Returns: str: String containing variables to be set with Helm release. """ env_vars = [] for item in preserve: if isinstance(item, tuple): item = HelmPreserve(*item) elif not isinstance(item, HelmPreserve): raise TypeError( "Items in preserve array must be HelmPerserve named tuples") secret_data = secret_read(item.secret_name, item.secret_namespace) env_vars.append(HelmSet(item.values_path, secret_data[item.data_item])) # Environmental variables # TODO: This may well be its own subfunction env_vars_string = "".join([ " --set{} {}={}".format("-string" if item.set_string else "", item.key, item.value) for item in env_vars ]) return env_vars_string
def ca_chart(opts, release, upgrade=False, verbose=False): values_dir = opts['core']['dir_values'] repository = opts['core']['chart_repo'] ca_namespace = get_namespace(opts, ca=release) # PostgreSQL (Upgrades here are dangerous, deactivated by default) helm_install('stable', 'postgresql', '{}-pg'.format(release), ca_namespace, config_yaml='{dir}/postgres-ca/{name}-pg.yaml'.format( dir=values_dir, name=release), verbose=verbose) psql_secret = secret_read('{}-pg-postgresql'.format(release), ca_namespace, verbose=verbose) # Different key depending of PostgreSQL version psql_password = psql_secret.get( 'postgres-password') or psql_secret['postgresql-password'] env_vars = [('externalDatabase.password', psql_password)] # Fabric CA if not upgrade: helm_install(repository, 'hlf-ca', release, ca_namespace, config_yaml='{dir}/hlf-ca/{name}.yaml'.format( dir=values_dir, name=release), env_vars=env_vars, verbose=verbose) else: # TODO: Remove this try/catch once all CAs are updated try: preserve = (HelmPreserve('{}-hlf-ca'.format(release), 'CA_ADMIN', 'adminUsername'), HelmPreserve('{}-hlf-ca'.format(release), 'CA_PASSWORD', 'adminPassword')) helm_upgrade(repository, 'hlf-ca', release, ca_namespace, config_yaml='{dir}/hlf-ca/{name}.yaml'.format( dir=values_dir, name=release), env_vars=env_vars, preserve=preserve, verbose=verbose) except: preserve = (HelmPreserve('{}-hlf-ca--ca'.format(release), 'CA_ADMIN', 'adminUsername'), HelmPreserve('{}-hlf-ca--ca'.format(release), 'CA_PASSWORD', 'adminPassword')) helm_upgrade(repository, 'hlf-ca', release, ca_namespace, config_yaml='{dir}/hlf-ca/{name}.yaml'.format( dir=values_dir, name=release), env_vars=env_vars, preserve=preserve, verbose=verbose)
def ca_chart(opts, release, upgrade=False): """Deploy CA Helm chart to K8S. Args: opts (dict): Nephos options dict. release (str): Name of the Helm Chart release. upgrade (bool): Do we upgrade the deployment? False by default. """ values_dir = opts["core"]["dir_values"] repository = opts["core"]["chart_repo"] ca_namespace = get_namespace(opts, ca=release) # PostgreSQL (Upgrades here are dangerous, deactivated by default) # Upgrading database is risky, so we disallow it by default if not upgrade: version = get_version(opts, "postgresql") config_yaml = f"{values_dir}/postgres-ca/{release}-pg.yaml" extra_vars = helm_extra_vars(version=version, config_yaml=config_yaml) helm_install("stable", "postgresql", f"{release}-pg", ca_namespace, extra_vars=extra_vars) helm_check("postgresql", f"{release}-pg", ca_namespace) psql_secret = secret_read(f"{release}-pg-postgresql", ca_namespace) # Different key depending of PostgreSQL version psql_password = (psql_secret.get("postgres-password") or psql_secret["postgresql-password"]) # Fabric CA version = get_version(opts, "hlf-ca") env_vars = [("externalDatabase.password", psql_password)] config_yaml = f"{values_dir}/hlf-ca/{release}.yaml" if not upgrade: extra_vars = helm_extra_vars(version=version, config_yaml=config_yaml, env_vars=env_vars) helm_install(repository, "hlf-ca", release, ca_namespace, extra_vars=extra_vars) else: preserve = ( HelmPreserve(ca_namespace, f"{release}-hlf-ca--ca", "CA_ADMIN", "adminUsername"), HelmPreserve(ca_namespace, f"{release}-hlf-ca--ca", "CA_PASSWORD", "adminPassword"), ) extra_vars = helm_extra_vars( version=version, config_yaml=config_yaml, env_vars=env_vars, preserve=preserve, ) helm_upgrade(repository, "hlf-ca", release, extra_vars=extra_vars) helm_check("hlf-ca", release, ca_namespace)
def extract_credentials(opts, node_type, verbose=False): chart = NODE_MAPPER[node_type] node_namespace = get_namespace(opts, opts[node_type + 's']['msp']) # Loop over the nodes for release in opts[node_type + 's']['names']: secret_name = 'hlf--{}-cred'.format(release) try: secret_read(secret_name, node_namespace) if verbose: print('{} secret already exists'.format(secret_name)) except ApiException: # Obtain secret data from original chart secret original_data = secret_read('{}-{}'.format(release, chart), node_namespace) # Create secret with Orderer credentials secret_data = { 'CA_USERNAME': original_data['CA_USERNAME'], 'CA_PASSWORD': original_data['CA_PASSWORD'] } secret_create(secret_data, secret_name, node_namespace, verbose=verbose)
def credentials_secret(secret_name, namespace, username, password=None, verbose=False): try: secret_data = secret_read(secret_name, namespace, verbose=verbose) # Check that the ID stored is the same as Orderer name assert username == secret_data['CA_USERNAME'] if password: assert password == secret_data['CA_PASSWORD'] except ApiException: # Get relevant variables if not password: password = rand_string(24) secret_data = {'CA_USERNAME': username, 'CA_PASSWORD': password} secret_create(secret_data, secret_name, namespace) return secret_data
def ca_chart(opts, release, upgrade=False, verbose=False): """Deploy CA Helm chart to K8S. Args: opts (dict): Nephos options dict. release (str): Name of the Helm Chart release. upgrade (bool): Do we upgrade the deployment? False by default. verbose (bool): Verbosity. False by default. """ values_dir = opts["core"]["dir_values"] repository = opts["core"]["chart_repo"] ca_namespace = get_namespace(opts, ca=release) # PostgreSQL (Upgrades here are dangerous, deactivated by default) helm_install( "stable", "postgresql", "{}-pg".format(release), ca_namespace, config_yaml="{dir}/postgres-ca/{name}-pg.yaml".format(dir=values_dir, name=release), verbose=verbose, ) psql_secret = secret_read("{}-pg-postgresql".format(release), ca_namespace, verbose=verbose) # Different key depending of PostgreSQL version psql_password = (psql_secret.get("postgres-password") or psql_secret["postgresql-password"]) env_vars = [("externalDatabase.password", psql_password)] # Fabric CA if not upgrade: helm_install( repository, "hlf-ca", release, ca_namespace, config_yaml="{dir}/hlf-ca/{name}.yaml".format(dir=values_dir, name=release), env_vars=env_vars, verbose=verbose, ) else: # TODO: Remove this try/catch once all CAs are updated try: preserve = ( HelmPreserve("{}-hlf-ca".format(release), "CA_ADMIN", "adminUsername"), HelmPreserve("{}-hlf-ca".format(release), "CA_PASSWORD", "adminPassword"), ) helm_upgrade( repository, "hlf-ca", release, ca_namespace, config_yaml="{dir}/hlf-ca/{name}.yaml".format(dir=values_dir, name=release), env_vars=env_vars, preserve=preserve, verbose=verbose, ) except: preserve = ( HelmPreserve("{}-hlf-ca--ca".format(release), "CA_ADMIN", "adminUsername"), HelmPreserve("{}-hlf-ca--ca".format(release), "CA_PASSWORD", "adminPassword"), ) helm_upgrade( repository, "hlf-ca", release, ca_namespace, config_yaml="{dir}/hlf-ca/{name}.yaml".format(dir=values_dir, name=release), env_vars=env_vars, preserve=preserve, verbose=verbose, )