def _get_hosts_with_container(self, context, cluster): marathon_client = MarathonClient( 'http://' + cluster.api_address + '/marathon/') hosts = set() for task in marathon_client.list_tasks(): hosts.add(task.host) return hosts
def dcos_login(): # Defaults servers for both DCOS 1.10+ CE and EE. servers = os.getenv( 'MARATHON_SERVERS', 'http://marathon.mesos:8080,https://marathon.mesos:8443').split(',') if SERVICE_SECRET: print('Attempting token auth to Marathon...') client = MarathonClient(servers, auth_token=DCOSServiceAuth( json.loads(SERVICE_SECRET)).token, verify=False) else: print('Attempting unauthenticated access to Marathon...') client = MarathonClient(servers, verify=False) return client
def get_marathon_client(): try: MARATHON_HOST = get_setting("marathon_host", "10.10.10.51") MARATHON_PORT = int(get_setting("marathon_port", 8080)) marathon_client = MarathonClient('http://{}:{}'.format( MARATHON_HOST, MARATHON_PORT)) return marathon_client except Exception as e: raise Exception("unconnect to marathon")
def list_app(request): mc = MarathonClient('http://{}:{}'.format(settings.MARATHON['host'], settings.MARATHON['port'])) apps = mc.list_apps() apps = sorted(apps, key=lambda app: app.id) for app in apps: app.tag_id = app.id.replace("/", "__") data = {'apps': apps} return render(request, 'marathon_mgmt/list_app.html', data)
def get_marathon_client(url, user, passwd): """Get a new marathon client connection in the form of a MarathonClient object. :param url: The url to connect to marathon at :param user: The username to connect with :param passwd: The password to connect with :returns: A new marathon.MarathonClient object""" log.info("Connecting to Marathon server at: %s", url) return MarathonClient(url, user, passwd, timeout=30)
def dcos_login(): # Defaults servers for both DCOS 1.7 and 1.8. 1.8 added HTTPS within DCOS EE clusters. servers = os.getenv('MARATHON_SERVERS', 'http://marathon.mesos:8080,https://marathon.mesos:8443').split(',') oauth_token = os.getenv('DCOS_OAUTH_TOKEN', '').strip() username = os.getenv('DCOS_USER', '').strip() password = os.getenv('DCOS_PASS', '').strip() if len(oauth_token): print('Attempting token auth to Marathon...') client = MarathonClient(servers, auth_token=oauth_token) elif len(username) and len(password): print('Attempting basic auth to Marathon...') client = MarathonClient(servers, username=username, password=password) else: print('Attempting unauthenticated access to Marathon...') client = MarathonClient(servers) return client
def test_list_tasks_without_app_id(): fake_response = '{ "tasks": [ { "appId": "/anapp", "healthCheckResults": ' \ '[ { "alive": true, "consecutiveFailures": 0, "firstSuccess": "2014-10-03T22:57:02.246Z", "lastFailure": null, ' \ '"lastSuccess": "2014-10-03T22:57:41.643Z", "taskId": "bridged-webapp.eb76c51f-4b4a-11e4-ae49-56847afe9799" } ],' \ ' "host": "10.141.141.10", "id": "bridged-webapp.eb76c51f-4b4a-11e4-ae49-56847afe9799", "ports": [ 31000 ], ' \ '"servicePorts": [ 9000 ], "stagedAt": "2014-10-03T22:16:27.811Z", "startedAt": "2014-10-03T22:57:41.587Z", ' \ '"version": "2014-10-03T22:16:23.634Z" }, { "appId": "/anotherapp", ' \ '"healthCheckResults": [ { "alive": true, "consecutiveFailures": 0, "firstSuccess": "2014-10-03T22:57:02.246Z", ' \ '"lastFailure": null, "lastSuccess": "2014-10-03T22:57:41.649Z", "taskId": "bridged-webapp.ef0b5d91-4b4a-11e4-ae49-56847afe9799" } ], ' \ '"host": "10.141.141.10", "id": "bridged-webapp.ef0b5d91-4b4a-11e4-ae49-56847afe9799", "ports": [ 31001 ], "servicePorts": [ 9000 ], ' \ '"stagedAt": "2014-10-03T22:16:33.814Z", "startedAt": "2014-10-03T22:57:41.593Z", "version": "2014-10-03T22:16:23.634Z" } ] }' with requests_mock.mock() as m: m.get('http://fake_server/v2/tasks', text=fake_response) mock_client = MarathonClient(servers='http://fake_server') actual_deployments = mock_client.list_tasks() expected_deployments = [ models.task.MarathonTask( app_id="/anapp", health_check_results=[ models.task.MarathonHealthCheckResult( alive=True, consecutive_failures=0, first_success="2014-10-03T22:57:02.246Z", last_failure=None, last_success="2014-10-03T22:57:41.643Z", task_id= "bridged-webapp.eb76c51f-4b4a-11e4-ae49-56847afe9799") ], host="10.141.141.10", id="bridged-webapp.eb76c51f-4b4a-11e4-ae49-56847afe9799", ports=[31000], service_ports=[9000], staged_at="2014-10-03T22:16:27.811Z", started_at="2014-10-03T22:57:41.587Z", version="2014-10-03T22:16:23.634Z"), models.task.MarathonTask( app_id="/anotherapp", health_check_results=[ models.task.MarathonHealthCheckResult( alive=True, consecutive_failures=0, first_success="2014-10-03T22:57:02.246Z", last_failure=None, last_success="2014-10-03T22:57:41.649Z", task_id= "bridged-webapp.ef0b5d91-4b4a-11e4-ae49-56847afe9799") ], host="10.141.141.10", id="bridged-webapp.ef0b5d91-4b4a-11e4-ae49-56847afe9799", ports=[31001], service_ports=[9000], staged_at="2014-10-03T22:16:33.814Z", started_at="2014-10-03T22:57:41.593Z", version="2014-10-03T22:16:23.634Z") ] assert actual_deployments == expected_deployments
def create_client(urls: str): marathonlist = urls.split(',') client = MarathonClient(marathonlist) try: if client.ping().strip() != b'pong': raise MarathonError except MarathonError: print('Could not connect to Marathon in {}'.format(marathonlist)) sys.exit(1) return client
def __init__(self, scheduler, marathon, name=None, nprocs=1, nthreads=0, docker='daskos/daskathon', volumes=[], **kwargs): self.scheduler = scheduler self.executor = ThreadPoolExecutor(1) self.client = MarathonClient(marathon) self.name = name or 'dask-%s' % uuid.uuid4() self.docker = docker self.volumes = volumes self.nprocs = nprocs self.nthreads = nthreads self.options = kwargs
def undeploy(app_name): """Calls marathon API to undeploy application :param app_name: :return: """ marathon_addresses = _addresses() cli = MarathonClient(marathon_addresses) if _is_deployed(cli, app_name): return cli.delete_app(app_name) else: return None
def __init__(self, scheduler, executable='dask-worker', docker_image='mrocklin/dask-distributed', marathon_address='http://localhost:8080', username=None, password=None, auth_token=None, app_name=None, **kwargs): self.scheduler = scheduler self.executor = ThreadPoolExecutor(1) # Create Marathon App to run dask-worker args = [ executable, scheduler.address, '--name', '$MESOS_TASK_ID', # use Mesos task ID as worker name '--worker-port', '$PORT_WORKER', '--nanny-port', '$PORT_NANNY', '--http-port', '$PORT_HTTP' ] ports = [{ 'port': 0, 'protocol': 'tcp', 'name': port_name } for port_name in ['worker', 'nanny', 'http']] if 'mem' in kwargs: args.extend( ['--memory-limit', str(int(kwargs['mem'] * 0.6 * 1e6))]) kwargs['cmd'] = ' '.join(args) container = MarathonContainer({'image': docker_image}) app = MarathonApp(instances=0, container=container, port_definitions=ports, **kwargs) # Connect and register app self.client = MarathonClient(servers=marathon_address, username=username, password=password, auth_token=auth_token) self.app = self.client.create_app(app_name or 'dask-%s' % uuid.uuid4(), app)
def ajax_deployments(request): mc = MarathonClient('http://{}:{}'.format(settings.MARATHON['host'], settings.MARATHON['port'])) deployments = mc.list_deployments() data = {} for deployment in deployments: deployment.complete = (deployment.current_step - 1) * 100 / deployment.total_steps data['deployments'] = deployments data['total_depl'] = len(deployments) return render(request, 'marathon_mgmt/ajax_deployments.html', data)
def get_marathon_client(url, user, passwd): """Get a new marathon client connection in the form of a MarathonClient object. :param url: The url to connect to marathon at :param user: The username to connect with :param passwd: The password to connect with :returns: A new marathon.MarathonClient object""" log.info("Connecting to Marathon server at: %s", url) session = requests.Session() session.headers.update({'User-Agent': get_user_agent()}) return MarathonClient(url, user, passwd, timeout=30, session=session)
def conn(environment): ''' DC/OS Auth for the API is a pain. The best I can do for now is send a POST to the ACS endpoint with username and password to fetch a temporary JWT. ''' marathon_url = config['dcos']['endpoints'][environment] + "/service/marathon" auth_api_url = config['dcos']['endpoints'][environment] + "/acs/api/v1/auth/login" r = requests.post(auth_api_url, headers=headers, data=payload) c = MarathonClient(marathon_url, auth_token=r.json()['token']) return c
def get_random_marathon_task(app_id): """Connect to Marathon and return a random task for a given application ID. :param app_id: The Marathon application ID. :return: tuple of the instance IP or hostname and listening port. """ c = MarathonClient('http://{}'.format(options.marathon_host)) app = c.get_app(app_id) task_host, task_port = None, None rand = randrange(0, len(app.tasks)) task_host = app.tasks[rand].host task_port = app.tasks[rand].ports[0] return task_host, task_port
def create_client(urls: str, user: str, password: str, https_verify: bool): marathonlist = urls.split(',') client = MarathonClient(marathonlist, username=user, password=password, verify=https_verify, timeout=10) # in seconds try: ping_answer = client.ping().strip().decode() print(ping_answer) if ping_answer != '"pong"': raise MarathonError except MarathonError: print('Could not connect to Marathon in {}'.format(marathonlist)) sys.exit(1) return client
def ajax_list_apps(request): mc = MarathonClient('http://{}:{}'.format(settings.MARATHON['host'], settings.MARATHON['port'])) apps = mc.list_apps() apps = sorted(apps, key=lambda app: app.id) filter_name = request.GET.get('filter_name', "") if filter_name != "": for app in apps[:]: app.tag_id = app.id.replace("/", "__") if app.id.find(filter_name) == -1: apps.remove(app) else: for app in apps: app.tag_id = app.id.replace("/", "__") data = {'apps': apps} return render(request, 'marathon_mgmt/ajax_list_apps.html', data)
def get_marathon_client(): def disable_requests_ssl_verify(): import requests origin_request = requests.request def request(*args, **kwargs): kwargs['verify'] = False return origin_request(*args, **kwargs) requests.request = request disable_requests_ssl_verify() return MarathonClient(settings.MARATHON_SERVERS, username=settings.MARATHON_USERNAME, password=settings.MARATHON_PASSWORD)
def re_deploy(app_name, app_file): """Calls marathon API to redeploy application with new file as request body :param app_name: :param app_file: :return: """ with open(app_file, 'r') as content_file: content = content_file.read() app_attr = json.loads(content) marathon_addresses = _addresses() cli = MarathonClient(marathon_addresses) if _is_deployed(cli, app_name): return cli.update_app(app_name, models.MarathonApp.from_json(app_attr)) else: return None
def test_get_deployments_pre_1_0(): fake_response = """[ { "affectedApps": [ "/test" ], "id": "fakeid", "steps": [ [ { "action": "ScaleApplication", "app": "/test" } ] ], "currentActions": [ { "action": "ScaleApplication", "app": "/test" } ], "version": "fakeversion", "currentStep": 1, "totalSteps": 1 } ]""" with requests_mock.mock() as m: m.get('http://fake_server/v2/deployments', text=fake_response) mock_client = MarathonClient(servers='http://fake_server') actual_deployments = mock_client.list_deployments() expected_deployments = [ models.MarathonDeployment( id=u"fakeid", steps=[[ models.MarathonDeploymentAction(action="ScaleApplication", app="/test") ]], current_actions=[ models.MarathonDeploymentAction(action="ScaleApplication", app="/test") ], current_step=1, total_steps=1, affected_apps=[u"/test"], version=u"fakeversion") ] assert expected_deployments == actual_deployments
def new_app(request, type): data = {} if request.method == 'POST': data['msg'] = "Post" post_params = {} for key in request.POST: if key.startswith("filehidden"): fkey = key[11:] if (request.FILES.get(fkey, None)): post_file = request.FILES[fkey] file_content = "" for chunk in post_file.chunks(): file_content += chunk.decode("utf8") post_params[fkey] = convert(file_content) else: post_params[fkey] = request.POST[key] else: post_params[key] = request.POST[key] template = Template.objects.get(pk=post_params['template_id']) content = template.content % post_params data['content'] = content mc = MarathonClient('http://{}:{}'.format(settings.MARATHON['host'], settings.MARATHON['port'])) try: if (type == "app"): mc.create_app_by_json(content) elif (type == "group"): mc.create_group(content) data['result'] = "Success" except Exception as e: data['result'] = str(e) if (type == "app"): data['type'] = "Application" templates = Template.objects.filter( type="marathon-app").order_by('name').all() elif (type == "group"): data['type'] = "Group" templates = Template.objects.filter( type="marathon-group").order_by('name').all() for template in templates: template.params = template.param_set.order_by('id') data['templates'] = templates return render(request, 'marathon_mgmt/new_app.html', data)
def wait_for_healthy_tasks(app_id, tasks_no=1): """Waits for at least tasks_no tasks to be healthy in application :param app_id: application id :param tasks_no: amount of tasks to wait for :return: """ marathon_addresses = _addresses() cli = MarathonClient(marathon_addresses) sorted_apps = __salt__['system.wait_for']( lambda x: _fetch_tasks(cli, app_id), 10, 6) if sorted_apps is None: return {} else: healthy_app = __salt__['system.wait_for']( lambda x: _healthy_tasks(cli, app_id, tasks_no), 10, 6) return {} if healthy_app is None else healthy_app
def new_deploy(app_name, app_file): """Calls marathon API to make new deployment of application given file as request body :param app_name: :param app_file: :return: """ marathon_addresses = _addresses() with open(app_file, 'r') as content_file: content = content_file.read() app_attr = json.loads(content) cli = MarathonClient(marathon_addresses) if not _is_deployed(cli, app_name): m_app = models.MarathonApp.from_json(app_attr) created_app = cli.create_app(app_name, m_app) return created_app.to_json() else: return None
def test_cassandra_command(self, create_app): marathon_client = MarathonClient(self.marathon_url) cass_cql = 'insert into movies (movie, release, rating) values (\'my movie\', \'2016-01-01\', 5.5);' cass_host = '127.0.0.2' cass_port = '9042' cass_app = CassandraCommand(marathon_client, cass_host, cass_port, cass_cql) cass_app.create() self.assertEqual(1, len(create_app.mock_calls)) app_id = tuple(create_app.mock_calls)[0][1][0] gen_cmd = tuple(create_app.mock_calls)[0][1][1].cmd cmd = 'echo "{}" > input.cql && cqlsh -f input.cql {} {} && curl -X DELETE {}/v2/apps/{}'\ .format(cass_cql, cass_host, cass_port, self.marathon_url, app_id) self.assertEqual(cmd, gen_cmd)
def main(args): migration_hosts = args.hosts.replace('"','').replace('\'','').split(',') marathon_client = MarathonClient(args.url) # Get the running marathon application dictionary running_instances = utils.dict_by_key_and_value(lambda x: x.id, lambda y: y.instances, marathon_client.list_apps()) print(">>> Total Running Applications: ") print(json.dumps(running_instances, sort_keys=True, indent=4, separators=(',', ': '))) # Get the running marathon applications for all hosts which are going for maintenance all_tasks = marathon_client.list_tasks() filtered_tasks = [task for task in all_tasks if task.host in migration_hosts] dicted_tasks = utils.dict_by_key(lambda x: x.app_id, filtered_tasks) print(">>> Total Running Application: ") print(json.dumps(dicted_tasks.keys(), sort_keys=True, indent=4, separators=(',', ': '))) # Tasks migration migrate_tasks(marathon_client, dicted_tasks, migration_hosts, args.force)
def dashboard(request): data = {} data['total_template'] = Template.objects.count() try: mc = MarathonClient('http://{}:{}'.format(settings.MARATHON['host'], settings.MARATHON['port'])) data['total_app'] = len(mc.list_apps()) except Exception as e: data['total_app'] = [] try: cclient = chronos.connect('{}:{}'.format(settings.CHRONOS['host'], settings.CHRONOS['port'])) jobs = cclient.list() data['total_job'] = len(cclient.list()) except Exception as e: data['total_job'] = [] data['total_watcher'] = len(settings.WATCHER_THREADS) return render(request, 'dashboard/dashboard.html', data)
def ports_used(request): mc = MarathonClient('http://{}:{}'.format(settings.MARATHON['host'], settings.MARATHON['port'])) apps = mc.list_apps() used_ports = {} for app in apps: tasks = mc.list_tasks(app.id) for task in tasks: if task.host in used_ports.keys(): used_ports[task.host].extend(task.ports) else: used_ports[task.host] = task.ports list_host_ports = [] for key in sorted(used_ports.keys()): list_host_ports.append([key, sorted(used_ports[key])]) data = {} data['used_ports'] = list_host_ports return render(request, 'marathon_mgmt/ports_used.html', data)
def __init__(self, host, port=80, use_https=False, user=None, password=None): self.user = user self.password = password self.host = host self.use_https = use_https self.port = str(port) self.url = '{}://{}:{}/'.format('https' if use_https else 'http', host, port) try: self.marathon_cli = MarathonClient([self.url], username=self.user, password=self.password) except Exception as e: logger.critical(e) raise e
def __init__(self, marathon_url, image, tasks): self.concurrency = 20 self.docker_image = image self.app_base_name = 'health-check-test-' self.total_tasks_cout = int(tasks) self.instances_per_app = 50 if tasks < self.instances_per_app: self.instances_per_app = self.total_tasks_cout self.app_count = 1 else: self.app_count = self.total_tasks_cout/self.instances_per_app self.heath_check_interval = 30 self.test_duration = 20 self.marathon_cluster = MarathonClient(marathon_url, timeout=240) self.work_queue = Queue() self.result_queue = Queue() self.app_list_queue = Queue() self.action_list = [self.start_collect, 'sleep={}'.format(self.test_duration), self.get_stats]
def restart(app_name): """Calls marathon restart API to rolling restart if file artifacts changed :param app_name: :return: """ marathon_addresses = _addresses() cli = MarathonClient(marathon_addresses) if _is_deployed(cli, app_name): apps = __salt__['system.wait_for']( lambda x: _non_empty_deployments(cli), 3, 1) deploy_name = '/' + app_name if apps and deploy_name in apps: return None else: r = requests.post(url=marathon_addresses[0] + '/v2/apps/' + app_name + '/restart?force=true', headers={'Content-Type': 'application/json'}) return r.status_code else: return None