Last active
February 20, 2019 04:22
-
-
Save paambaati/8774bf56a696a4c39317ab4cabf6be81 to your computer and use it in GitHub Desktop.
Handy script to help migrate all Mesos Marathon apps from 1 cluster to another. Can use either a Marathon URI or a local file location for both source & destination sinks. Works on both Python2 & Python3.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
import argparse | |
from os import environ | |
from json import load, loads, dumps | |
from urlparse import urlparse | |
try: | |
from urllib.request import urlopen, Request | |
from urllib.error import HTTPError | |
except ImportError: | |
from urllib2 import urlopen, Request, HTTPError | |
class PutRequest(Request): | |
def __init__(self, *args, **kwargs): | |
return Request.__init__(self, *args, **kwargs) | |
def get_method(self, *args, **kwargs): | |
return 'PUT' | |
def read(source_marathon): | |
source_scheme = urlparse(source_marathon).scheme | |
if not source_scheme or source_scheme == 'file': | |
with open(source_marathon) as json_data: | |
apps = load(json_data) | |
return apps | |
else: | |
response = urlopen('{}/v2/apps'.format(source_marathon)) | |
apps = loads(response.read()) | |
return apps | |
def write(data, dest_marathon): | |
dest_scheme = urlparse(dest_marathon).scheme | |
if not dest_scheme or dest_scheme == 'file': | |
with open(dest_marathon, 'w') as json_dump: | |
json_dump.write(dumps(data, indent=4)) | |
else: | |
current_apps = data.get('apps', []) | |
for (index, app) in enumerate(current_apps): | |
keys_to_remove = ['version', 'versionInfo', 'uris'] | |
new_app = {x: app[x] for x in app if x not in keys_to_remove} | |
print('Force deploying app #{} of {} ({}) to destination Marathon... '.format(index + 1, len(current_apps), new_app.get('id'))), | |
req = PutRequest('{}/v2/apps?force=true'.format(dest_marathon), headers={'Content-Type': 'application/json'}, data=dumps([new_app])) | |
try: | |
response = urlopen(req) | |
print('[OK]') | |
except HTTPError as error: | |
print('[FAILED] ({})'.format(error.code)) | |
def copy_apps(source_marathon, dest_marathon): | |
print('Copying apps from {} to {}'.format(source_marathon, dest_marathon)) | |
apps = read(source_marathon) | |
write(apps, dest_marathon) | |
if __name__ == '__main__': | |
parser = argparse.ArgumentParser(description='Copy all apps from 1 Marathon cluster to another', epilog='You can also use local file locations for both source & destination.') | |
parser.add_argument('source', help='Source Marathon to copy apps from. Can also be a file location.', type=str) | |
parser.add_argument('dest', help='Destination Marathon to deploy copied apps to. Can also be a file location.', type=str) | |
args = parser.parse_args() | |
copy_apps(args.source, args.dest) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment