def create_service_account(service_account, private_key_filename='private-key.pem', public_key_filename='public-key.pem', account_description='SI test account'): """Create new private and public key pair and use them to add a new service with a give name. Public key file is then removed, however private key file is left since it might be used to create a secret. If you don't plan on creating a secret afterwards, please remove it manually. This method uses `dcos security org` command and assumes that `dcos-enterprise-cli` package is installed. :param service_account: service account name :type service_account: str :param private_key_filename: optional private key file name :type private_key_filename: str :param public_key_filename: optional public key file name :type public_key_filename: str :param account_description: service account description :type account_description: str """ print('Creating a key pair for the service account') shakedown.run_dcos_command('security org service-accounts keypair {} {}'.format( private_key_filename, public_key_filename)) assert os.path.isfile(private_key_filename), "Private key of the service account key pair not found" assert os.path.isfile(public_key_filename), "Public key of the service account key pair not found" print('Creating {} service account'.format(service_account)) stdout, stderr, return_code = shakedown.run_dcos_command( 'security org service-accounts create -p {} -d "{}" {}'.format( public_key_filename, account_description, service_account)) os.remove(public_key_filename) assert return_code == 0
def delete_service_account(service_account_name: str, service_account_secret: str) -> None: """ Deletes service account and secret with private key that belongs to the service account. """ # ignore any failures: shakedown.run_dcos_command("security org service-accounts delete {name}".format(name=service_account_name)) shakedown.run_dcos_command("security secrets delete {secret}".format(secret=service_account_secret)) # Files generated by service-accounts keypair command should get removed for keypair_file in ['private-key.pem', 'public-key.pem']: try: os.unlink(keypair_file) except OSError: pass
def install_enterprise_cli_package(): """Install `dcos-enterprise-cli` package. It is required by the `dcos security` command to create secrets, manage service accounts etc. """ print('Installing dcos-enterprise-cli package') cmd = 'package install dcos-enterprise-cli --cli --yes' stdout, stderr, return_code = shakedown.run_dcos_command(cmd, raise_on_error=True)
def install_enterprise_cli_package(): """Install `dcos-enterprise-cli` package. It is required by the `dcos security` command to create secrets, manage service accounts etc. """ print('Installing dcos-enterprise-cli package') stdout, stderr, return_code = shakedown.run_dcos_command('package install dcos-enterprise-cli --cli --yes') assert return_code == 0, "Failed to install dcos-enterprise-cli package"
def get_cassandra_plans_on_failure(request): yield if sdk_utils.is_test_failure(request): plans, err, rc = shakedown.run_dcos_command('cassandra plan list') if rc: log.error('Unable to fetch cassandra plan list: {}'.format(err)) return planlist = json.loads(plans) for plan_name in planlist: plan, err, rc = shakedown.run_dcos_command('cassandra plan show {}'.format(plan_name)) if rc: log.error('Unable to fetch cassandra plan for {}: {}'.format(plan_name, err)) continue plan_filename = '{}_{}_plan.log'.format(request.node.name, plan_name) with open(plan_filename, 'w') as f: f.write(plan)
def uninstall(service_name, package_name=None): start = time.time() if package_name is None: package_name = service_name print('Uninstalling/janitoring {}'.format(service_name)) try: shakedown.uninstall_package_and_wait(package_name, service_name=service_name) except (dcos.errors.DCOSException, ValueError) as e: print('Got exception when uninstalling package, ' + 'continuing with janitor anyway: {}'.format(e)) janitor_start = time.time() janitor_cmd = ( 'docker run mesosphere/janitor /janitor.py ' '-r {svc}-role -p {svc}-principal -z dcos-service-{svc} --auth_token={auth}') shakedown.run_command_on_master(janitor_cmd.format( svc=service_name, auth=shakedown.run_dcos_command('config show core.dcos_acs_token')[0].strip())) finish = time.time() print('Uninstall done after pkg({}) + janitor({}) = total({})'.format( sdk_spin.pretty_time(janitor_start - start), sdk_spin.pretty_time(finish - janitor_start), sdk_spin.pretty_time(finish - start)))
def create_sa_secret(secret_name, service_account, strict=False, private_key_filename='private-key.pem'): """Create an sa-secret with a given private key file for passed service account in the vault. Both (service account and secret) should share the same key pair. `{strict}` parameter should be `True` when creating a secret in a `strict` secure cluster. Private key file will be removed after secret is successfully created. This method uses `dcos security org` command and assumes that `dcos-enterprise-cli` package is installed. :param secret_name: secret name :type secret_name: str :param service_account: service account name :type service_account: str :param strict: `True` is this a `strict` secure cluster :type strict: bool :param private_key_filename: private key file name :type private_key_filename: str """ assert os.path.isfile(private_key_filename), "Failed to create secret: private key not found" print('Creating new sa-secret {} for service-account: {}'.format(secret_name, service_account)) strict_opt = '--strict' if strict else '' stdout, stderr, return_code = shakedown.run_dcos_command('security secrets create-sa-secret {} {} {} {}'.format( strict_opt, private_key_filename, service_account, secret_name)) os.remove(private_key_filename) assert return_code == 0, "Failed to create a secret"
def run_cli(cmd): (stdout, stderr, ret) = shakedown.run_dcos_command(cmd) if ret != 0: err = 'Got error code {} when running command "dcos {}":\nstdout: "{}"\nstderr: "{}"'.format( ret, cmd, stdout, stderr) print(err) raise Exception(err) return stdout
def get_dcos_command(command): result, error = shakedown.run_dcos_command(command) if error: raise RuntimeError( 'command dcos {} {} failed'.format(command, PACKAGE_NAME) ) return result
def is_enterprise_cli_package_installed(): """Returns `True` if `dcos-enterprise-cli` package is installed.""" stdout, stderr, return_code = shakedown.run_dcos_command('package list --json') print('package list command returned code:{}, stderr:{}, stdout: {}'.format(return_code, stderr, stdout)) try: result_json = json.loads(stdout) except JSONDecodeError as error: raise DCOSException('Could not parse: "{}"'.format(stdout))(error) return any(cmd['name'] == 'dcos-enterprise-cli' for cmd in result_json)
def delete_secret(secret_name): """Delete a secret with a given name from the vault. This method uses `dcos security org` command and assumes that `dcos-enterprise-cli` package is installed. :param secret_name: secret name :type secret_name: str """ print('Removing existing secret {}'.format(secret_name)) stdout, stderr, return_code = shakedown.run_dcos_command('security secrets delete {}'.format(secret_name)) assert return_code == 0, "Failed to remove existing secret"
def has_service_account(service_account): """Returns `True` if a service account with a given name already exists. This method uses `dcos security org` command and assumes that `dcos-enterprise-cli` package is installed. :param service_account: service account name :type service_account: str """ stdout, stderr, return_code = shakedown.run_dcos_command('security org service-accounts show --json') result_json = json.loads(stdout) return service_account in result_json
def delete_service_account(service_account): """Removes an existing service account. This method uses `dcos security org` command and assumes that `dcos-enterprise-cli` package is installed. :param service_account: service account name :type service_account: str """ print('Removing existing service account {}'.format(service_account)) stdout, stderr, return_code = \ shakedown.run_dcos_command('security org service-accounts delete {}'.format(service_account)) assert return_code == 0, "Failed to create a service account"
def run_cli(cmd, print_output=True, return_stderr_in_stdout=False): (stdout, stderr, ret) = shakedown.run_dcos_command( cmd, print_output=print_output) if ret != 0: err = 'Got error code {} when running command "dcos {}":\nstdout: "{}"\nstderr: "{}"'.format( ret, cmd, stdout, stderr) log.error(err) raise dcos.errors.DCOSException(err) if return_stderr_in_stdout: stdout = stdout + "\n" + stderr return stdout
def uninstall(): print("Uninstalling/janitoring {}".format(PACKAGE_NAME)) try: shakedown.uninstall_package_and_wait(PACKAGE_NAME, service_name=PACKAGE_NAME) except (dcos.errors.DCOSException, ValueError) as e: print("Got exception when uninstalling package, continuing with janitor anyway: {}".format(e)) shakedown.run_command_on_master( "docker run mesosphere/janitor /janitor.py " "-r cassandra-role -p {} -z dcos-service-cassandra " "--auth_token={}".format(PRINCIPAL, shakedown.run_dcos_command("config show core.dcos_acs_token")[0].strip()) )
def has_secret(secret_name): """Returns `True` if the secret with given name exists in the vault. This method uses `dcos security secrets` command and assumes that `dcos-enterprise-cli` package is installed. :param secret_name: secret name :type secret_name: str """ stdout, stderr, return_code = shakedown.run_dcos_command('security secrets list / --json') if stdout: result_json = json.loads(stdout) return secret_name in result_json return False
def remove_universe_repos(stub_urls): log.info('Removing universe repos') # clear out the added universe repositores at testing end for name, url in stub_urls.items(): log.info('Removing stub URL: {}'.format(url)) out, err, rc = shakedown.run_dcos_command('package repo remove {}'.format(name)) if err: if err.endswith('is not present in the list'): # tried to remove something that wasn't there, move on. pass else: raise 'Failed to remove stub repo: stdout=[{}], stderr=[{}]'.format(out, err) log.info('Finished removing universe repos')
def uninstall(): print('Uninstalling/janitoring {}'.format(PACKAGE_NAME)) try: shakedown.uninstall_package_and_wait(PACKAGE_NAME, app_id=PACKAGE_NAME) except (dcos.errors.DCOSException, ValueError) as e: print('Got exception when uninstalling package, continuing with janitor anyway: {}'.format(e)) shakedown.run_command_on_master( 'docker run mesosphere/janitor /janitor.py ' '-r cassandra-role -p cassandra-principal -z dcos-service-cassandra ' '--auth_token={}'.format( shakedown.run_dcos_command( 'config show core.dcos_acs_token' )[0].strip() ) )
def create_secret(name, value=None, description=None): """Create a secret with a passed `{name}` and optional `{value}`. This method uses `dcos security secrets` command and assumes that `dcos-enterprise-cli` package is installed. :param name: secret name :type name: str :param value: optional secret value :type value: str :param description: option secret description :type description: str """ print('Creating new secret {}:{}'.format(name, value)) value_opt = '-v {}'.format(shlex.quote(value)) if value else '' description_opt = '-d "{}"'.format(description) if description else '' stdout, stderr, return_code = shakedown.run_dcos_command('security secrets create {} {} "{}"'.format( value_opt, description_opt, name), print_output=True) assert return_code == 0, "Failed to create a secret"
import os import shakedown DEFAULT_NODE_COUNT = 3 PACKAGE_NAME = 'mds-cassandra' TASK_RUNNING_STATE = 'TASK_RUNNING' DCOS_URL = shakedown.run_dcos_command('config show core.dcos_url')[0].strip() # expected SECURITY values: 'permissive', 'strict', 'disabled' if os.environ.get('SECURITY', '') == 'strict': print('Using strict mode test configuration') PRINCIPAL = 'service-acct' DEFAULT_OPTIONS_DICT = { "service": { "user": "******", "principal": PRINCIPAL, "secret_name": "secret" } } else: print('Using default test configuration') PRINCIPAL = 'cassandra-principal' DEFAULT_OPTIONS_DICT = {}
import json from functools import wraps import shakedown PACKAGE_NAME = 'elastic' MASTER_VIP = "http://master.{}.l4lb.thisdcos.directory:9200".format(PACKAGE_NAME) DEFAULT_TASK_COUNT = 9 WAIT_TIME_IN_SECONDS = 6 * 60 KIBANA_WAIT_TIME_IN_SECONDS = 15 * 60 DEFAULT_NODE_COUNT = 7 DEFAULT_INDEX_NAME = 'customer' DEFAULT_INDEX_TYPE = 'entry' DCOS_URL = shakedown.run_dcos_command('config show core.dcos_url')[0].strip() DCOS_TOKEN = shakedown.run_dcos_command('config show core.dcos_acs_token')[0].strip() TASK_RUNNING_STATE = 'TASK_RUNNING' def as_json(fn): @wraps(fn) def wrapper(*args, **kwargs): try: return json.loads(fn(*args, **kwargs)) except ValueError: return None return wrapper
import shakedown DEFAULT_NODE_COUNT = 3 PACKAGE_NAME = 'cassandra' TASK_RUNNING_STATE = 'TASK_RUNNING' DCOS_URL = shakedown.run_dcos_command('config show core.dcos_url')[0].strip()
import sdk_cmd import sdk_hosts as hosts import sdk_marathon as marathon import sdk_plan import sdk_tasks as tasks import sdk_utils PACKAGE_NAME = 'elastic' DEFAULT_TASK_COUNT = 7 WAIT_TIME_IN_SECONDS = 10 * 60 KIBANA_WAIT_TIME_IN_SECONDS = 30 * 60 DEFAULT_INDEX_NAME = 'customer' DEFAULT_INDEX_TYPE = 'entry' DCOS_TOKEN = shakedown.run_dcos_command( 'config show core.dcos_acs_token')[0].strip() DEFAULT_NUMBER_OF_SHARDS = 1 DEFAULT_NUMBER_OF_REPLICAS = 1 DEFAULT_SETTINGS_MAPPINGS = { "settings": { "index.unassigned.node_left.delayed_timeout": "0", "number_of_shards": DEFAULT_NUMBER_OF_SHARDS, "number_of_replicas": DEFAULT_NUMBER_OF_REPLICAS }, "mappings": { DEFAULT_INDEX_TYPE: { "properties": { "name": { "type": "keyword" },
def unset_ssl_verification(): shakedown.run_dcos_command("config set core.ssl_verify false")
def get_cassandra_command(command): stdout, stderr, rc = shakedown.run_dcos_command("{} {}".format(PACKAGE_NAME, command)) if rc: raise RuntimeError("command dcos {} {} failed: {} {}".format(command, PACKAGE_NAME, stdout, stderr)) return stdout
def test_driver_executor_tls(): ''' Put keystore and truststore as secrets in DC/OS secret store. Run SparkPi job with TLS enabled, referencing those secrets. Make sure other secrets still show up. ''' python_script_path = os.path.join(THIS_DIR, 'jobs', 'python', 'pi_with_secret.py') python_script_url = utils.upload_file(python_script_path) resources_folder = os.path.join( os.path.dirname(os.path.realpath(__file__)), 'resources') keystore_file = 'server.jks' truststore_file = 'trust.jks' keystore_path = os.path.join(resources_folder, '{}.base64'.format(keystore_file)) truststore_path = os.path.join(resources_folder, '{}.base64'.format(truststore_file)) keystore_secret = '__dcos_base64__keystore' truststore_secret = '__dcos_base64__truststore' my_secret = 'mysecret' my_secret_content = 'secretcontent' shakedown.run_dcos_command( 'security secrets create /{} --value-file {}'.format( keystore_secret, keystore_path)) shakedown.run_dcos_command( 'security secrets create /{} --value-file {}'.format( truststore_secret, truststore_path)) shakedown.run_dcos_command('security secrets create /{} --value {}'.format( my_secret, my_secret_content)) password = '******' try: utils.run_tests( app_url=python_script_url, app_args="30 {} {}".format(my_secret, my_secret_content), expected_output="Pi is roughly 3", args=[ "--keystore-secret-path", keystore_secret, "--truststore-secret-path", truststore_secret, "--private-key-password", format(password), "--keystore-password", format(password), "--truststore-password", format(password), "--conf", "spark.mesos.driver.secret.names={}".format(my_secret), "--conf", "spark.mesos.driver.secret.filenames={}".format(my_secret), "--conf", "spark.mesos.driver.secret.envkeys={}".format(my_secret), ]) finally: shakedown.run_dcos_command( 'security secrets delete /{}'.format(keystore_secret)) shakedown.run_dcos_command( 'security secrets delete /{}'.format(truststore_secret)) shakedown.run_dcos_command( 'security secrets delete /{}'.format(my_secret))
def fn(): return shakedown.run_dcos_command('kafka connection')
def test_overlay_network(): """Verify that the current deploy plan matches the expected plan from the spec.""" deployment_plan = sdk_plan.wait_for_completed_deployment(PACKAGE_NAME) log.info("deployment_plan: " + str(deployment_plan)) # test that the deployment plan is correct assert (len(deployment_plan['phases']) == 5) assert (deployment_plan['phases'][0]['name'] == 'hello-overlay-vip-deploy') assert (deployment_plan['phases'][1]['name'] == 'hello-overlay-deploy') assert (deployment_plan['phases'][2]['name'] == 'hello-host-vip-deploy') assert (deployment_plan['phases'][3]['name'] == 'hello-host-deploy') assert (deployment_plan["phases"][4]["name"] == "getter-deploy") assert (len(deployment_plan['phases'][0]['steps']) == 1) assert (len(deployment_plan["phases"][1]["steps"]) == 1) assert (len(deployment_plan["phases"][2]["steps"]) == 1) assert (len(deployment_plan["phases"][3]["steps"]) == 1) assert (len(deployment_plan["phases"][4]["steps"]) == 4) # Due to DNS resolution flakiness, some of the deployed tasks can fail. If so, # we wait for them to redeploy, but if they don't fail we still want to proceed. try: sdk_plan.wait_for_in_progress_recovery(PACKAGE_NAME, timeout_seconds=60) sdk_plan.wait_for_completed_recovery(PACKAGE_NAME, timeout_seconds=60) except TimeoutExpired: pass # test that the tasks are all up, which tests the overlay DNS framework_tasks = [ task for task in shakedown.get_service_tasks(PACKAGE_NAME, completed=False) ] framework_task_names = [t["name"] for t in framework_tasks] for expected_task in EXPECTED_TASKS: assert (expected_task in framework_task_names), "Missing {expected}".format( expected=expected_task) for task in framework_tasks: name = task["name"] if "getter" in name: # don't check the "getter" tasks because they don't use ports continue resources = task["resources"] if "host" in name: assert "ports" in resources.keys( ), "Task {} should have port resources".format(name) if "overlay" in name: assert "ports" not in resources.keys( ), "Task {} should NOT have port resources".format(name) sdk_networks.check_task_network("hello-overlay-0-server") sdk_networks.check_task_network("hello-overlay-vip-0-server") sdk_networks.check_task_network("hello-host-0-server", expected_network_name=None) sdk_networks.check_task_network("hello-host-vip-0-server", expected_network_name=None) endpoints_result, _, rc = shakedown.run_dcos_command( "{pkg} endpoints".format(pkg=PACKAGE_NAME)) endpoints_result = json.loads(endpoints_result) assert rc == 0, "Getting endpoints failed" assert len(endpoints_result ) == 2, "Wrong number of endpoints got {} should be 2".format( len(endpoints_result)) overlay_endpoints_result, _, rc = shakedown.run_dcos_command( "{pkg} endpoints overlay-vip".format(pkg=PACKAGE_NAME)) assert rc == 0, "Getting overlay endpoints failed" overlay_endpoints_result = json.loads(overlay_endpoints_result) assert "address" in overlay_endpoints_result.keys(), "overlay endpoints missing 'address'"\ "{}".format(overlay_endpoints_result) assert len(overlay_endpoints_result["address"]) == 1 assert overlay_endpoints_result["address"][0].startswith("9") overlay_port = overlay_endpoints_result["address"][0].split(":")[-1] assert overlay_port == "4044" assert "dns" in overlay_endpoints_result.keys() assert len(overlay_endpoints_result["dns"]) == 1 assert overlay_endpoints_result["dns"][0] == sdk_hosts.autoip_host( PACKAGE_NAME, "hello-overlay-vip-0-server", 4044) host_endpoints_result, _, rc = shakedown.run_dcos_command( "{pkg} endpoints host-vip".format(pkg=PACKAGE_NAME)) assert rc == 0, "Getting host endpoints failed" host_endpoints_result = json.loads(host_endpoints_result) assert "address" in host_endpoints_result.keys(), "overlay endpoints missing 'address'"\ "{}".format(host_endpoints_result) assert len(host_endpoints_result["address"]) == 1 assert host_endpoints_result["address"][0].startswith("10") host_port = host_endpoints_result["address"][0].split(":")[-1] assert host_port == "4044" assert "dns" in host_endpoints_result.keys() assert len(host_endpoints_result["dns"]) == 1 assert host_endpoints_result["dns"][0] == sdk_hosts.autoip_host( PACKAGE_NAME, "hello-host-vip-0-server", 4044)
def job_run_has_secret(): stdout, stderr, return_code = shakedown.run_dcos_command("task log --all {} fbs-secret".format(run_id)) logged_secret = stdout.rstrip() assert secret_value == logged_secret, ("secret value in stdout log incorrect or missing. " "'{}' should be '{}'").format(logged_secret, secret_value)
def is_enterprise_cli_package_installed(): """Returns `True` if `dcos-enterprise-cli` package is installed.""" stdout, stderr, return_code = shakedown.run_dcos_command('package list --json') result_json = json.loads(stdout) return any(cmd['name'] == 'dcos-enterprise-cli' for cmd in result_json)
def default_topic(): shakedown.run_dcos_command( '{} topic create {}'.format(PACKAGE_NAME, DEFAULT_TOPIC_NAME) )
def default_topic(): shakedown.run_dcos_command('{} topic create {}'.format( PACKAGE_NAME, DEFAULT_TOPIC_NAME))