def test_ingress_read_fail(self, mock_api_ext, mock_pretty_print): mock_api_ext.read_namespaced_ingress.side_effect = [ApiException] with pytest.raises(ApiException): ingress_read("an_ingress", "a-namespace") mock_api_ext.read_namespaced_ingress.assert_called_once_with( name="an_ingress", namespace="a-namespace") mock_pretty_print.assert_not_called()
def ingress_read_fail(self, mock_api_ext, mock_pretty_print): mock_api_ext.read_namespaced_ingress.side_effect = [ApiException] with pytest.raises(ApiException): ingress_read('an_ingress', 'a-namespace', verbose=True) mock_api_ext.read_namespaced_ingress.assert_called_once_with( name='an_ingress', namespace='a-namespace', verbose=True) mock_pretty_print.assert_not_called()
def test_ingress_read(self, mock_api_ext, mock_pretty_print): mock_ingress = MagicMock() mock_ingress.spec.rules.__iter__.return_value = [ IngressHost("a-url"), IngressHost("another-url"), ] mock_api_ext.read_namespaced_ingress.side_effect = [mock_ingress] ingress_read("an_ingress", "a-namespace") mock_api_ext.read_namespaced_ingress.assert_called_once_with( name="an_ingress", namespace="a-namespace") mock_pretty_print.assert_called_once_with('["a-url", "another-url"]')
def ingress_read(self, mock_api_ext, mock_pretty_print): mock_ingress = mock.Mock() mock_ingress.spec.rules.side_effect = [ IngressHost('a-url'), IngressHost('another-url') ] mock_api_ext.read_namespaced_ingress.side_effect = [mock_ingress] ingress_read('an_ingress', 'a-namespace') mock_api_ext.read_namespaced_ingress.assert_called_once_with( name='an_ingress', namespace='a-namespace', verbose=False) mock_pretty_print.assert_called_once_with('["a-url", "another-url"]')
def setup_ca(opts, upgrade=False): """Setup CA. Setup involves enrolling the CA admin, checking the Ingress is responsive. Args: opts (dict): Nephos options dict. upgrade (bool): Do we upgrade the deployment? False by default. """ for ca_name, ca_values in opts["cas"].items(): ca_namespace = get_namespace(opts, ca=ca_name) # Install Charts ca_chart(opts=opts, release=ca_name, upgrade=upgrade) # Obtain CA pod and Enroll pod_exec = get_helm_pod(namespace=ca_namespace, release=ca_name, app="hlf-ca") ca_enroll(pod_exec) # Get CA Ingress and check it is running try: # Get ingress of CA ingress_urls = ingress_read(ca_name + "-hlf-ca", namespace=ca_namespace) except ApiException: logging.warning("No ingress found for CA") continue # Check the CA is running check_ca(ingress_host=ingress_urls[0], cacert=ca_values.get("tls_cert"))
def enroll_id(opts, ca, username, password, verbose=False): """Enroll an ID with a Fabric Certificate Authority Args: opts (dict): Nephos options dict. ca (str): K8S release name of CA. username (str): Username for identity. password (str): Password for identity. verbose (bool) Verbosity. False by default. Returns: str: Path of the MSP directory where cryptographic data is saved. """ dir_crypto = opts["core"]["dir_crypto"] ca_namespace = get_namespace(opts, ca=ca) ingress_urls = ingress_read(ca + "-hlf-ca", namespace=ca_namespace, verbose=verbose) msp_dir = "{}_MSP".format(username) msp_path = join(dir_crypto, msp_dir) if not isdir(msp_path): # Enroll command = ("FABRIC_CA_CLIENT_HOME={dir} fabric-ca-client enroll " + "-u https://{username}:{password}@{ingress} -M {msp_dir} " + "--tls.certfiles {ca_server_tls}").format( dir=dir_crypto, username=username, password=password, ingress=ingress_urls[0], msp_dir=join(dir_crypto, msp_dir), ca_server_tls=abspath(opts["cas"][ca]["tls_cert"]), ) execute_until_success(command) return msp_path
def enroll_id(opts, ca, username, password): """Enroll an ID with a Fabric Certificate Authority Args: opts (dict): Nephos options dict. ca (str): K8S release name of CA. username (str): Username for identity. password (str): Password for identity. Returns: str: Path of the MSP directory where cryptographic data is saved. """ dir_crypto = opts["core"]["dir_crypto"] ca_namespace = get_namespace(opts, ca=ca) ingress_urls = ingress_read(ca + "-hlf-ca", namespace=ca_namespace) msp_dir = f"{username}_MSP" msp_path = join(dir_crypto, msp_dir) if not isdir(msp_path): # Enroll command = ( f'FABRIC_CA_CLIENT_HOME={dir_crypto} fabric-ca-client enroll ' + f'-u https://{username}:{password}@{ingress_urls[0]} -M {join(dir_crypto, msp_dir)} ' + f'--tls.certfiles {abspath(opts["cas"][ca]["tls_cert"])}') execute_until_success(command) return msp_path
def composer_connection(opts, verbose=False): peer_namespace = get_namespace(opts, opts['peers']['msp']) ord_namespace = get_namespace(opts, opts['orderers']['msp']) # TODO: This could be a single function peer_ca = opts['peers']['ca'] peer_ca_msp = opts['cas'][peer_ca]['msp'] ingress_urls = ingress_read(peer_ca + '-hlf-ca', namespace=peer_namespace, verbose=verbose) peer_ca_url = ingress_urls[0] try: cm_read(opts['composer']['secret_connection'], peer_namespace, verbose=verbose) except ApiException: # Set up connection.json # TODO: Improve json_ct to work directly with opts structure cm_data = { 'connection.json': json_ct(opts['peers']['names'], opts['orderers']['names'], [ peer + '-hlf-peer.{ns}.svc.cluster.local'.format(ns=peer_namespace) for peer in opts['peers']['names'] ], [ orderer + '-hlf-ord.{ns}.svc.cluster.local'.format(ns=ord_namespace) for orderer in opts['orderers']['names'] ], peer_ca, peer_ca_url, 'AidTech', None, peer_ca_msp, opts['peers']['channel_name']) } cm_create(peer_namespace, opts['composer']['secret_connection'], cm_data)
def composer_connection(opts, verbose=False): """Composer connection setup. This creates a ConfigMap on K8S with the Hyperledger Composer connection. Args: opts (dict): Nephos options dict. verbose (bool): Verbosity. False by default. """ peer_namespace = get_namespace(opts, opts["peers"]["msp"]) # TODO: This could be a single function peer_msp = opts["peers"]["msp"] peer_ca = opts["msps"][peer_msp]["ca"] ca_namespace = opts["cas"][peer_ca]["namespace"] ingress_urls = ingress_read(peer_ca + "-hlf-ca", namespace=ca_namespace) peer_ca_url = ingress_urls[0] try: cm_read(opts["composer"]["secret_connection"], peer_namespace) except ApiException: # Set up connection.json # TODO: Improve json_ct to work entirely with opts structure cm_data = { "connection.json": json_ct( opts, peer_ca, peer_ca_url, "AidTech", None, peer_msp, opts["peers"]["channel_name"], ) } cm_create(cm_data, opts["composer"]["secret_connection"], peer_namespace)
def setup_ca(opts, upgrade=False, verbose=False): for ca_name, ca_values in opts['cas'].items(): ca_namespace = get_namespace(opts, ca=ca_name) # Install Charts ca_chart(opts=opts, release=ca_name, upgrade=upgrade, verbose=verbose) # Obtain CA pod and Enroll pod_exec = get_pod(namespace=ca_namespace, release=ca_name, app='hlf-ca', verbose=verbose) ca_enroll(pod_exec) # Get CA Ingress and check it is running try: # Get ingress of CA ingress_urls = ingress_read(ca_name + '-hlf-ca', namespace=ca_namespace, verbose=verbose) except ApiException: print('No ingress found for CA') continue # Check the CA is running check_ca(ingress_host=ingress_urls[0], verbose=verbose)
def create_admin(opts, msp_name, verbose=False): """Create an admin identity. Args: opts (dict): Nephos options dict. msp_name (str): Name of Membership Service Provider. verbose (bool) Verbosity. False by default. """ dir_config = opts["core"]["dir_config"] dir_crypto = opts["core"]["dir_crypto"] msp_values = opts["msps"][msp_name] ca_values = opts["cas"][msp_values["ca"]] # TODO: Refactor this into its own function ca_name = msp_values["ca"] ca_namespace = get_namespace(opts, ca=ca_name) # Get CA ingress ingress_urls = ingress_read( ca_name + "-hlf-ca", namespace=ca_namespace, verbose=verbose ) ca_ingress = ingress_urls[0] # Register the Organisation with the CAs register_id( ca_namespace, msp_values["ca"], msp_values["org_admin"], msp_values["org_adminpw"], admin=True, verbose=verbose, ) # TODO: Can we reuse the Enroll function above? # If our keystore does not exist or is empty, we need to enroll the identity... keystore = join(dir_crypto, msp_name, "keystore") if not isdir(keystore) or not listdir(keystore): execute( ( "FABRIC_CA_CLIENT_HOME={dir} fabric-ca-client enroll " + "-u https://{id}:{pw}@{ingress} -M {msp_dir} --tls.certfiles {ca_server_tls}" ).format( dir=dir_config, id=msp_values["org_admin"], pw=msp_values["org_adminpw"], ingress=ca_ingress, msp_dir=join(dir_crypto, msp_name), ca_server_tls=abspath(ca_values["tls_cert"]), ), verbose=verbose, )
def create_admin(opts, msp_name, verbose=False): dir_config = opts['core']['dir_config'] msp_values = opts['msps'][msp_name] ca_values = opts['cas'][msp_values['ca']] # TODO: Refactor this into its own function ca_name = msp_values['ca'] ca_namespace = get_namespace(opts, ca=ca_name) # Obtain CA pod pod_exec = get_pod(namespace=ca_namespace, release=ca_name, app='hlf-ca', verbose=verbose) # Get CA ingress ingress_urls = ingress_read(ca_name + '-hlf-ca', namespace=ca_namespace, verbose=verbose) ca_ingress = ingress_urls[0] # Register the Organisation with the CAs admin_id = pod_exec.execute( ('fabric-ca-client identity list --id {id}').format( id=msp_values['org_admin'])) # If we cannot find the identity, we must create it if not admin_id: pod_exec.execute(( "fabric-ca-client register --id.name {id} --id.secret {pw} --id.attrs 'admin=true:ecert'" ).format(id=msp_values['org_admin'], pw=msp_values['org_adminpw'])) # If our keystore does not exist or is empty, we need to enroll the identity... keystore = path.join(dir_config, msp_name, 'keystore') if not path.isdir(keystore) or not listdir(keystore): execute(( 'FABRIC_CA_CLIENT_HOME={dir} fabric-ca-client enroll ' + '-u https://{id}:{pw}@{ingress} -M {msp_dir} --tls.certfiles {ca_server_tls}' ).format(dir=dir_config, id=msp_values['org_admin'], pw=msp_values['org_adminpw'], ingress=ca_ingress, msp_dir=msp_name, ca_server_tls=ca_values['tls_cert']), verbose=verbose)
def enroll_node(opts, ca, username, password, verbose=False): dir_config = opts['core']['dir_config'] ca_namespace = get_namespace(opts, ca=ca) ingress_urls = ingress_read(ca + '-hlf-ca', namespace=ca_namespace, verbose=verbose) msp_dir = '{}_MSP'.format(username) msp_path = path.join(dir_config, msp_dir) if not path.isdir(msp_path): # Enroll command = ('FABRIC_CA_CLIENT_HOME={dir} fabric-ca-client enroll ' + '-u https://{username}:{password}@{ingress} -M {msp_dir} ' + '--tls.certfiles {ca_server_tls}').format( dir=dir_config, username=username, password=password, ingress=ingress_urls[0], msp_dir=msp_dir, ca_server_tls=path.abspath(opts['cas'][ca]['tls_cert'])) execute_until_success(command) return msp_path
def create_admin(opts, msp_name): """Create an admin identity. Args: opts (dict): Nephos options dict. msp_name (str): Name of Membership Service Provider. """ dir_config = opts["core"]["dir_config"] dir_crypto = opts["core"]["dir_crypto"] msp_values = opts["msps"][msp_name] ca_values = opts["cas"][msp_values["ca"]] # TODO: Refactor this into its own function ca_name = msp_values["ca"] ca_namespace = get_namespace(opts, ca=ca_name) # Get CA ingress ingress_urls = ingress_read(ca_name + "-hlf-ca", namespace=ca_namespace) ca_ingress = ingress_urls[0] # Register the Organisation with the CAs register_id( ca_namespace, msp_values["ca"], msp_values["org_admin"], msp_values["org_adminpw"], admin=True, ) # TODO: Can we reuse the Enroll function above? # If our keystore does not exist or is empty, we need to enroll the identity... keystore = join(dir_crypto, msp_name, "keystore") if not isdir(keystore) or not listdir(keystore): execute(( f"FABRIC_CA_CLIENT_HOME={dir_config} fabric-ca-client enroll " + f"-u https://{msp_values['org_admin']}:{msp_values['org_adminpw']}@{ca_ingress} " + f"-M {join(dir_crypto, msp_name)} --tls.certfiles {abspath(ca_values['tls_cert'])}" ), )