def deployWithoutConflict(org, env, name, basePath, revision): response = httptools.httpCall('GET', '/v1/o/%s/apis/%s/deployments' % (org, name)) hdrs = { 'Content-Type': 'application/x-www-form-urlencoded' } deps = parseAppDeployments(org, response, name) for d in deps: if d['environment'] == env and \ d['basePath'] == basePath and \ d['revision'] != revision: print 'Undeploying revision %i in same environment and path:' % d['revision'] resp = httptools.httpCall('POST', '/v1/organizations/%s/apis/%s/deployments' % (org, name), hdrs, 'action=undeploy&env=%s&revision=%i' % (env, d['revision'])) if resp.status != 200 and resp.status != 204: print 'Error %i on undeployment:\n%s' % (resp.status, resp.read()) return False # Deploy the bundle print 'Deploying revision %i' % revision resp = httptools.httpCall('POST', '/v1/organizations/%s/apis/%s/deployments' \ % (org, name), hdrs, 'action=deploy&env=%s&revision=%s&basepath=%s' \ % (env, revision, basePath)) if resp.status != 200 and resp.status != 201: print 'Deploy failed with status %i:\n%s' % (resp.status, resp.read()) return False print ' Deployed.' return True
def getBaseUrl(org, env, name, basePath, revision): response = httptools.httpCall('GET', '/v1/o/%s/apis/%s/revisions/%i/proxies' % (org, name, revision)) proxies = json.load(response) if len(proxies) < 1: # No proxies return '(unknown)' response = httptools.httpCall('GET', '/v1/o/%s/apis/%s/revisions/%i/proxies/%s' % (org, name, revision, proxies[0])) proxy = json.load(response) if len(proxy['connection']['virtualHost']) < 1: # No virtual hosts return '(unknown)' vhName = proxy['connection']['virtualHost'][0] response = httptools.httpCall('GET', '/v1/o/%s/e/%s/virtualhosts/%s' % (org, env, vhName)) vh = json.load(response) if len(vh['hostAliases']) < 1: # No aliases alias = '' else: alias = vh['hostAliases'][0] ret = 'http://%s:%s/' % (alias, vh['port']) if len(basePath) > 0: ret = urlparse.urljoin(ret, basePath) proxyBasePath = proxy['connection']['basePath'] if len(proxyBasePath) > 0: ret = urlparse.urljoin(ret, proxyBasePath) return ret
def undeploy(org, env, name, revision): print 'Undeploying proxy %s revision %i' % (name, revision) hdrs = {'Content-Type': 'application/x-www-form-urlencoded'} resp = httptools.httpCall( 'POST', '/v1/organizations/%s/apis/%s/deployments' % (org, name), hdrs, 'action=undeploy&env=%s&revision=%i' % (env, revision)) if resp.status != 200 and resp.status != 204: print 'Error %i on undeployment:\n%s' % (resp.status, resp.read()) return False return True
def undeploy(org, env, name, revision): print 'Undeploying proxy %s revision %i' % (name, revision) hdrs = { 'Content-Type': 'application/x-www-form-urlencoded' } resp = httptools.httpCall('POST', '/v1/organizations/%s/apis/%s/deployments' % (org, name), hdrs, 'action=undeploy&env=%s&revision=%i' % (env, revision)) if resp.status != 200 and resp.status != 204: print 'Error %i on undeployment:\n%s' % (resp.status, resp.read()) return False return True
def importBundle(org, name, data): hdrs = { 'Content-Type' : 'application/octet-stream' } uri = '/v1/organizations/%s/apis?action=import&name=%s' \ % (org, name) print 'Importing new application %s' % name resp = httptools.httpCall('POST', uri, hdrs, data) if resp.status != 200 and resp.status != 201: print 'Import failed to %s with status %i:\n%s' % (uri, resp.status, resp.read()) return -1 deployment = json.load(resp) revision = int(deployment['revision']) return revision
def deployWithoutConflict(org, env, name, basePath, revision): # Deploy the bundle using: seamless_deployments print 'Deploying revision %i' % revision hdrs = { 'Accept': 'application/json', 'Content-type': 'application/x-www-form-urlencoded' } resp = httptools.httpCall('POST', ('/v1/o/%s/environments/%s/apis/%s/revisions/%s/deployments' + '?override=true') % \ (org, env, name, revision), hdrs) if resp.status != 200 and resp.status != 201: print 'Deploy failed with status %i:\n%s' % (resp.status, resp.read()) return False print ' Deployed.' return True
def importBundle(org, name, data): hdrs = { 'Content-Type': 'application/octet-stream' } uri = '/v1/organizations/%s/apis?action=import&name=%s' \ % (org, name) print 'Importing new application %s' % name resp = None try: resp = httptools.httpCall('POST', uri, hdrs, data) except IOError, e: print traceback.format_exc() err_message = IOError_messages.get(e.errno) if err_message: print '%s uploading API Bundle!\nHINT: %s' % (e, err_message) return -1
def importBundle(org, name, data): hdrs = {'Content-Type': 'application/octet-stream'} uri = '/v1/organizations/%s/apis?action=import&name=%s' \ % (org, name) print 'Importing new application %s' % name resp = None try: resp = httptools.httpCall('POST', uri, hdrs, data) except IOError, e: print traceback.format_exc() err_message = IOError_messages.get(e.errno) if err_message: print '%s uploading API Bundle!\nHINT: %s' % (e, err_message) return -1
def run(): ApigeeURL = 'https://api.enterprise.apigee.com' Username = None Password = None Directory = None MainScript = None Organization = None Environment = None Name = None BasePath = '/' ShouldDeploy = True ZipFile = None Options = 'o:e:n:d:m:u:p:b:l:z:ih' opts = getopt.getopt(sys.argv[2:], Options)[0] for o in opts: if o[0] == '-o': Organization = o[1] elif o[0] == '-e': Environment =o[1] elif o[0] == '-n': Name = o[1] elif o[0] == '-d': Directory =o[1] elif o[0] == '-m': MainScript = o[1] elif o[0] == '-u': Username = o[1] elif o[0] == '-p': Password = o[1] elif o[0] == '-b': BasePath = o[1] elif o[0] == '-l': ApigeeURL = o[1] elif o[0] == '-z': ZipFile = o[1] elif o[0] == '-i': ShouldDeploy = False elif o[0] == '-h': printUsage() sys.exit(1) BadUsage = False if Username == None: BadUsage = True print '-u is required' if Password == None: BadUsage = True print '-p is required' if Directory == None: BadUsage = True print '-d is required' if Environment == None: BadUsage = True print '-e is required' if Name == None: BadUsage = True print '-n is required' if Organization == None: BadUsage = True print '-o is required' if MainScript == None: BadUsage = True print '-m is required' if BadUsage: printUsage() sys.exit(1) httptools.setup(ApigeeURL, Username, Password) def makeApplication(): return '<APIProxy name="%s"/>' % Name def makeProxy(): return '<ProxyEndpoint name="default">\ <HTTPProxyConnection>\ <BasePath>%s</BasePath>\ <VirtualHost>default</VirtualHost>\ </HTTPProxyConnection>\ <RouteRule name="default">\ <TargetEndpoint>default</TargetEndpoint>\ </RouteRule>\ </ProxyEndpoint>' % BasePath def makeTarget(): return '<TargetEndpoint name="default">\ <ScriptTarget>\ <ResourceURL>node://%s</ResourceURL>\ </ScriptTarget>\ </TargetEndpoint>' % MainScript # Return TRUE if any component of the file path contains a directory name that # starts with a "." like '.svn', but not '.' or '..' def pathContainsDot(p): c = re.compile('\.\w+') for pc in p.split('/'): if c.match(pc) != None: return True return False # ZIP a whole directory into a stream and return the result so that it # can be nested into the top-level ZIP def zipDirectory(dir, pfx): ret = StringIO.StringIO() tzip = zipfile.ZipFile(ret, 'w') dirList = os.walk(dir) for dirEntry in dirList: for fileEntry in dirEntry[2]: if not fileEntry.endswith('~'): fn = os.path.join(dirEntry[0], fileEntry) en = os.path.join(pfx, os.path.relpath(dirEntry[0], dir), fileEntry) if (os.path.isfile(fn)): tzip.write(fn, en) tzip.close() return ret.getvalue() # Construct a ZIPped copy of the bundle in memory tf = StringIO.StringIO() zipout = zipfile.ZipFile(tf, 'w') zipout.writestr('apiproxy/%s.xml' % Name, makeApplication()) zipout.writestr('apiproxy/proxies/default.xml', makeProxy()) zipout.writestr('apiproxy/targets/default.xml', makeTarget()) for topName in os.listdir(Directory): if not pathContainsDot(topName): fn = os.path.join(Directory, topName) if (os.path.isdir(fn)): contents = zipDirectory(fn, topName) en = 'apiproxy/resources/node/%s.zip' % topName zipout.writestr(en, contents) else: en = 'apiproxy/resources/node/%s' % topName zipout.write(fn, en) zipout.close() if (ZipFile != None): tzf = open(ZipFile, 'w') tzf.write(tf.getvalue()) tzf.close() revision = deploytools.importBundle(Organization, Name, tf.getvalue()) if (revision < 0): sys.exit(2) print 'Imported new app revision %i' % revision if ShouldDeploy: status = deploytools.deployWithoutConflict(Organization, Environment, Name, '/', revision) if status == False: sys.exit(2) response = httptools.httpCall('GET', '/v1/o/%s/apis/%s/deployments' % (Organization, Name)) deps = deploytools.parseAppDeployments(Organization, response, Name) deploytools.printDeployments(deps)
def getAndParseDeployments(org, name): response = httptools.httpCall('GET', '/v1/o/%s/apis/%s/deployments' % (org, name)) return parseAppDeployments(org, response, name)
def getAndParseEnvDeployments(org, env): response = httptools.httpCall('GET', '/v1/o/%s/e/%s/deployments' % (org, env)) return parseEnvDeployments(org, response, env)
def run(): ApigeeURL = 'https://api.enterprise.apigee.com' Username = None Password = None Directory = None Organization = None Environment = None Name = None BasePath = '/' ShouldDeploy = True ZipFile = None Options = 'o:e:n:d:u:p:b:l:z:ih' opts = getopt.getopt(sys.argv[2:], Options)[0] for o in opts: if o[0] == '-n': Name = o[1] elif o[0] == '-o': Organization = o[1] elif o[0] == '-d': Directory =o[1] elif o[0] == '-e': Environment =o[1] elif o[0] == '-b': BasePath = o[1] elif o[0] == '-u': Username = o[1] elif o[0] == '-p': Password = o[1] elif o[0] == '-l': ApigeeURL = o[1] elif o[0] == '-z': ZipFile = o[1] elif o[0] == '-i': ShouldDeploy = False elif o[0] == '-h': printUsage() sys.exit(0) if Username == None or Password == None or Directory == None or \ Environment == None or Name == None or Organization == None: printUsage() sys.exit(1) httptools.setup(ApigeeURL, Username, Password) # Return TRUE if any component of the file path contains a directory name that # starts with a "." like '.svn', but not '.' or '..' def pathContainsDot(p): c = re.compile('\.\w+') for pc in p.split('/'): if c.match(pc) != None: return True return False # Construct a ZIPped copy of the bundle in memory tf = StringIO.StringIO() zipout = zipfile.ZipFile(tf, 'w') dirList = os.walk(Directory) for dirEntry in dirList: if not pathContainsDot(dirEntry[0]): for fileEntry in dirEntry[2]: if not fileEntry.endswith('~'): fn = os.path.join(dirEntry[0], fileEntry) en = os.path.join(os.path.relpath(dirEntry[0], Directory), fileEntry) zipout.write(fn, en) zipout.close() if (ZipFile != None): tzf = open(ZipFile, 'w') tzf.write(tf.getvalue()) tzf.close() revision = deploytools.importBundle(Organization, Name, tf.getvalue()) if (revision < 0): sys.exit(2) print 'Imported new proxy revision %i' % revision if ShouldDeploy: status = deploytools.deployWithoutConflict(Organization, Environment, Name, BasePath, revision) if status == False: sys.exit(2) response = httptools.httpCall('GET', '/v1/o/%s/apis/%s/deployments' % (Organization, Name)) deps = deploytools.parseAppDeployments(Organization, response, Name) deploytools.printDeployments(deps)
def run(): ApigeeURL = 'https://api.enterprise.apigee.com' Username = None Password = None Directory = None Organization = None Environment = None Name = None BasePath = '/' ShouldDeploy = True ZipFile = None Options = 'o:e:n:d:u:p:b:l:z:ih' opts = getopt.getopt(sys.argv[2:], Options)[0] for o in opts: if o[0] == '-n': Name = o[1] elif o[0] == '-o': Organization = o[1] elif o[0] == '-d': Directory = o[1] elif o[0] == '-e': Environment = o[1] elif o[0] == '-b': BasePath = o[1] elif o[0] == '-u': Username = o[1] elif o[0] == '-p': Password = o[1] elif o[0] == '-l': ApigeeURL = o[1] elif o[0] == '-z': ZipFile = o[1] elif o[0] == '-i': ShouldDeploy = False elif o[0] == '-h': printUsage() sys.exit(0) if not Password: Password = getpass.getpass() if not Username or not Password or not Directory or \ not Environment or not Name or not Organization: printUsage() sys.exit(1) httptools.setup(ApigeeURL, Username, Password) # Return TRUE if any component of the file path contains a directory name that # starts with a "." like '.svn', but not '.' or '..' def pathContainsDot(p): c = re.compile('\.\w+') for pc in p.split('/'): if c.match(pc) != None: return True return False # Construct a ZIPped copy of the bundle in memory tf = StringIO.StringIO() zipout = zipfile.ZipFile(tf, 'w') dirList = os.walk(Directory) for dirEntry in dirList: if not pathContainsDot(dirEntry[0]): for fileEntry in dirEntry[2]: if not fileEntry.endswith('~'): fn = os.path.join(dirEntry[0], fileEntry) en = os.path.join(os.path.relpath(dirEntry[0], Directory), fileEntry) zipout.write(fn, en) zipout.close() if (ZipFile != None): tzf = open(ZipFile, 'w') tzf.write(tf.getvalue()) tzf.close() revision = deploytools.importBundle(Organization, Name, tf.getvalue()) if (revision < 0): sys.exit(2) print 'Imported new proxy revision %i' % revision if ShouldDeploy: status = deploytools.deployWithoutConflict(Organization, Environment, Name, BasePath, revision) if status == False: sys.exit(2) response = httptools.httpCall( 'GET', '/v1/o/%s/apis/%s/deployments' % (Organization, Name)) deps = deploytools.parseAppDeployments(Organization, response, Name) deploytools.printDeployments(deps)
def run(): ApigeeURL = 'https://api.enterprise.apigee.com' Username = None Password = None Directory = None MainScript = None Organization = None Environment = None Name = None BasePath = '/' ShouldDeploy = True ZipFile = None Options = 'o:e:n:d:m:u:p:b:l:z:ih' opts = getopt.getopt(sys.argv[2:], Options)[0] for o in opts: if o[0] == '-o': Organization = o[1] elif o[0] == '-e': Environment = o[1] elif o[0] == '-n': Name = o[1] elif o[0] == '-d': Directory = o[1] elif o[0] == '-m': MainScript = o[1] elif o[0] == '-u': Username = o[1] elif o[0] == '-p': Password = o[1] elif o[0] == '-b': BasePath = o[1] elif o[0] == '-l': ApigeeURL = o[1] elif o[0] == '-z': ZipFile = o[1] elif o[0] == '-i': ShouldDeploy = False elif o[0] == '-h': printUsage() sys.exit(0) BadUsage = False if Username == None: BadUsage = True print '-u is required' if Password == None: BadUsage = True print '-p is required' if Directory == None: BadUsage = True print '-d is required' if Environment == None: BadUsage = True print '-e is required' if Name == None: BadUsage = True print '-n is required' if Organization == None: BadUsage = True print '-o is required' if MainScript == None: BadUsage = True print '-m is required' if BadUsage: printUsage() sys.exit(1) httptools.setup(ApigeeURL, Username, Password) def makeApplication(): return '<APIProxy name="%s"/>' % Name def makeProxy(): return '<ProxyEndpoint name="default">\ <HTTPProxyConnection>\ <BasePath>%s</BasePath>\ <VirtualHost>default</VirtualHost>\ </HTTPProxyConnection>\ <RouteRule name="default">\ <TargetEndpoint>default</TargetEndpoint>\ </RouteRule>\ </ProxyEndpoint>' % BasePath def makeTarget(): return '<TargetEndpoint name="default">\ <ScriptTarget>\ <ResourceURL>node://%s</ResourceURL>\ </ScriptTarget>\ </TargetEndpoint>' % MainScript # Return TRUE if any component of the file path contains a directory name that # starts with a "." like '.svn', but not '.' or '..' def pathContainsDot(p): c = re.compile('\.\w+') for pc in p.split('/'): if c.match(pc) != None: return True return False # ZIP a whole directory into a stream and return the result so that it # can be nested into the top-level ZIP def zipDirectory(dir, pfx): ret = StringIO.StringIO() tzip = zipfile.ZipFile(ret, 'w') dirList = os.walk(dir) for dirEntry in dirList: for fileEntry in dirEntry[2]: if not fileEntry.endswith('~'): fn = os.path.join(dirEntry[0], fileEntry) en = os.path.join(pfx, os.path.relpath(dirEntry[0], dir), fileEntry) if (os.path.isfile(fn)): tzip.write(fn, en) tzip.close() return ret.getvalue() # Construct a ZIPped copy of the bundle in memory tf = StringIO.StringIO() zipout = zipfile.ZipFile(tf, 'w') zipout.writestr('apiproxy/%s.xml' % Name, makeApplication()) zipout.writestr('apiproxy/proxies/default.xml', makeProxy()) zipout.writestr('apiproxy/targets/default.xml', makeTarget()) for topName in os.listdir(Directory): if not pathContainsDot(topName): fn = os.path.join(Directory, topName) if (os.path.isdir(fn)): contents = zipDirectory(fn, topName) en = 'apiproxy/resources/node/%s.zip' % topName zipout.writestr(en, contents) else: en = 'apiproxy/resources/node/%s' % topName zipout.write(fn, en) zipout.close() if (ZipFile != None): tzf = open(ZipFile, 'w') tzf.write(tf.getvalue()) tzf.close() revision = deploytools.importBundle(Organization, Name, tf.getvalue()) if (revision < 0): sys.exit(2) print 'Imported new app revision %i' % revision if ShouldDeploy: status = deploytools.deployWithoutConflict(Organization, Environment, Name, '/', revision) if status == False: sys.exit(2) response = httptools.httpCall( 'GET', '/v1/o/%s/apis/%s/deployments' % (Organization, Name)) deps = deploytools.parseAppDeployments(Organization, response, Name) deploytools.printDeployments(deps)