def refresh(self, args, props): namespace, _ = parseQName(args.name, props) url = '%(apibase)s/namespaces/%(namespace)s/packages/refresh' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace) } res = request('POST', url, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: result = json.loads(res.read()) print '%(namespace)s refreshed successfully!' % {'namespace': args.name} print hilite('created bindings:', True) print '\n'.join(result['added']) print hilite('updated bindings:', True) print '\n'.join(result['updated']) print hilite('deleted bindings:', True) print '\n'.join(result['deleted']) return 0 elif res.status == httplib.NOT_IMPLEMENTED: print 'error: This feature is not implemented in the targeted deployment' return responseError(res) else: result = json.loads(res.read()) print 'error: %(error)s' % {'error': result['error']} return responseError(res)
def dockerDownload(self, args, props): tarFile = 'blackbox-0.1.0.tar.gz' blackboxDir = 'dockerSkeleton' if os.path.exists(tarFile): print('The path ' + tarFile + ' already exists. Please delete it and retry.') return -1 if os.path.exists(blackboxDir): print('The path ' + blackboxDir + ' already exists. Please delete it and retry.') return -1 url = 'https://%s/%s' % (props['apihost'], tarFile) try: res = request('GET', url) if res.status == httplib.OK: with open(tarFile, 'wb') as f: f.write(res.read()) except: print('Download of docker skeleton failed.') return -1 rc = subprocess.call(['tar', 'pxf', tarFile]) if (rc != 0): print('Could not install docker skeleton.') return -1 rc = subprocess.call(['rm', tarFile]) print('\nThe docker skeleton is now installed at the current directory.') return 0
def listCmd(self, args, props): namespace, pname = parseQName(args.name, props) url = '%(apibase)s/namespaces/%(namespace)s/activations?docs=%(full)s&skip=%(skip)s&limit=%(limit)s&%(filter)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'collection': self.collection, 'full': 'true' if args.full else 'false', 'skip': args.skip, 'limit': args.limit, 'filter': 'name=%s' % urllib.quote(pname) if pname and len(pname) > 0 else '' } if args.upto > 0: url = url + '&upto=' + str(args.upto) if args.since > 0: url = url + '&since=' + str(args.since) res = request('GET', url, auth=args.auth, verbose=args.verbose) return res
def bind(self, args, props): namespace, pname = parseQName(args.name, props) url = '%(apibase)s/namespaces/%(namespace)s/packages/%(name)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'name': self.getSafeName(pname) } pkgNamespace, pkgName = parseQName(args.package, props) if pkgName is None or len(pkgName) <= 0: print 'package name malformed. name or /namespace/name allowed' sys.exit(1) binding = { 'namespace': pkgNamespace, 'name': pkgName } payload = { 'binding': binding, 'annotations': getAnnotations(args), 'parameters': getParams(args) } args.shared = False self.addPublish(payload, args) headers= { 'Content-Type': 'application/json' } res = request('PUT', url, json.dumps(payload), headers, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: print 'ok: created binding %(name)s ' % {'name': args.name } return 0 else: return responseError(res)
def setState(self, args, props, enable): namespace, pname = parseQName(args.name, props) desc = 'active' if enable else 'inactive' status = json.dumps({'status': desc}) url = '%(apibase)s/namespaces/%(namespace)s/rules/%(name)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'name': self.getSafeName(pname) } headers = {'Content-Type': 'application/json'} res = request('POST', url, status, headers, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: print 'ok: rule %(name)s is %(desc)s' % { 'desc': desc, 'name': args.name } return 0 elif res.status == httplib.ACCEPTED: desc = 'activating' if enable else 'deactivating' print 'ok: rule %(name)s is %(desc)s' % { 'desc': desc, 'name': args.name } return 0 else: return responseError(res)
def dockerDownload(self, args, props): tarFile = 'blackbox-0.1.0.tar.gz' blackboxDir = 'dockerSkeleton' if os.path.exists(tarFile): print('The path ' + tarFile + ' already exists. Please delete it and retry.') return -1 if os.path.exists(blackboxDir): print('The path ' + blackboxDir + ' already exists. Please delete it and retry.') return -1 url = 'https://%s/%s' % (props['apihost'], tarFile) try: res = request('GET', url) if res.status == httplib.OK: with open(tarFile, 'wb') as f: f.write(res.read()) except: print('Download of docker skeleton failed.') return -1 rc = subprocess.call(['tar', 'pxf', tarFile]) if (rc != 0): print('Could not install docker skeleton.') return -1 rc = subprocess.call(['rm', tarFile]) print( '\nThe docker skeleton is now installed at the current directory.') return 0
def list(self, args, props): namespace, pname = parseQName(args.name, props) if pname: pname = ('/%s' % pname) if pname.endswith('/') else '/%s/' % pname url = 'https://%(apibase)s/namespaces/%(namespace)s/%(collection)s%(package)s?skip=%(skip)s&limit=%(limit)s%(public)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'collection': self.collection, 'package': pname if pname else '', 'skip': args.skip, 'limit': args.limit, 'public': '&public=true' if 'shared' in args and args.shared else '' } res = request('GET', url, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: result = json.loads(res.read()) print bold(self.collection) for e in result: print self.formatListEntity(e) return 0 else: return responseError(res)
def fire(self, args, props): namespace, pname = parseQName(args.name, props) url = '%(apibase)s/namespaces/%(namespace)s/triggers/%(name)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'name': self.getSafeName(pname) } payload = json.dumps(getActivationArgument(args)) headers = {'Content-Type': 'application/json'} res = request('POST', url, payload, headers, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: result = json.loads(res.read()) print('ok: triggered %(name)s with id %(id)s' % { 'name': args.name, 'id': result['activationId'] }) return 0 else: return responseError(res)
def refresh(self, args, props): namespace, _ = parseQName(args.name, props) url = 'https://%(apibase)s/namespaces/%(namespace)s/packages/refresh' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace) } res = request('POST', url, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: result = json.loads(res.read()) print '%(namespace)s refreshed successfully!' % {'namespace': args.name} print hilite('created bindings:', True) print '\n'.join(result['added']) print hilite('updated bindings:', True) print '\n'.join(result['updated']) print hilite('deleted bindings:', True) print '\n'.join(result['deleted']) return 0 elif res.status == httplib.NOT_IMPLEMENTED: print 'error: This feature is not implemented in the targeted deployment' return responseError(res) else: result = json.loads(res.read()) print 'error: %(error)s' % {'error': result['error']} return responseError(res)
def bind(self, args, props): namespace, pname = parseQName(args.name, props) url = 'https://%(apibase)s/namespaces/%(namespace)s/packages/%(name)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'name': self.getSafeName(pname) } pkgNamespace, pkgName = parseQName(args.package, props) if pkgName is None or len(pkgName) <= 0: print 'package name malformed. name or /namespace/name allowed' sys.exit(1) binding = { 'namespace': pkgNamespace, 'name': pkgName } payload = { 'binding': binding, 'annotations': getAnnotations(args), 'parameters': getParams(args) } args.shared = False self.addPublish(payload, args) headers= { 'Content-Type': 'application/json' } res = request('PUT', url, json.dumps(payload), headers, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: print 'ok: created binding %(name)s ' % {'name': args.name } return 0 else: return responseError(res)
def listNamespaces(self, args, props): url = 'https://%(apibase)s/namespaces' % {'apibase': apiBase(props)} res = request('GET', url, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: result = json.loads(res.read()) print bold("namespaces") for n in result: print "{:<25}".format(n) return 0 else: return responseError(res)
def listNamespaces(self, args, props): url = 'https://%(apibase)s/namespaces' % { 'apibase': apiBase(props) } res = request('GET', url, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: result = json.loads(res.read()) print bold('namespaces') for n in result: print '{:<25}'.format(n) return 0 else: return responseError(res)
def doInvoke(self, args, props): namespace, pname = parseQName(args.name, props) url = 'https://%(apibase)s/namespaces/%(namespace)s/actions/%(name)s?blocking=%(blocking)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'name': self.getSafeName(pname), 'blocking': 'true' if args.blocking else 'false' } payload = json.dumps(getActivationArgument(args)) headers = { 'Content-Type': 'application/json' } res = request('POST', url, payload, headers, auth=args.auth, verbose=args.verbose) return res
def GetActivation(activation_id, namespace='guest'): """ Returns details for an activation id. """ configs = GetDBConfigs() url = configs['db_protocol']+'://'+configs['db_host']+':'+configs['db_port'] + \ '/'+configs['db_prefix']+'activations'+'/'+namespace+'%2F'+activation_id headers = { 'Content-Type': 'application/json', } res = request('GET', url, headers=headers, auth='%s:%s' % (configs['db_username'], configs['db_password'])) return json.loads(res.read())
def GetAllActivationDocs(): """ Returns all activation record keys. """ configs = GetDBConfigs() url = configs['db_protocol']+'://'+configs['db_host']+':' + \ configs['db_port']+'/'+configs['db_prefix']+'activations/_all_docs' headers = { 'Content-Type': 'application/json', } res = request('GET', url, headers=headers, auth='%s:%s' % (configs['db_username'], configs['db_password'])) return json.loads(res.read())
def httpDelete(self, args, props): code = self.preProcessDelete(args, props) if (code != 0): return code namespace, pname = parseQName(args.name, props) url = 'https://%(apibase)s/namespaces/%(namespace)s/%(collection)s/%(name)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'collection': self.collection, 'name': self.getSafeName(pname) } res = request('DELETE', url, auth=args.auth, verbose=args.verbose) return res
def listEntitiesInNamespace(self, args, props): namespace, _ = parseQName(args.name, props) url = 'https://%(apibase)s/namespaces/%(namespace)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace) } res = request('GET', url, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: result = json.loads(res.read()) print 'entities in namespace: %s' % bold(namespace if namespace != '_' else 'default') self.printCollection(result, 'packages') self.printCollection(result, 'actions') self.printCollection(result, 'triggers') self.printCollection(result, 'rules') return 0 else: return responseError(res)
def httpGet(self, args, props, name=None): if name is None: name = args.name namespace, pname = parseQName(name, props) if pname is None or pname.strip() == '': print 'error: entity name missing, did you mean to list collection' sys.exit(2) url = 'https://%(apibase)s/namespaces/%(namespace)s/%(collection)s/%(name)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'collection': self.collection, 'name': self.getSafeName(pname) } return request('GET', url, auth=args.auth, verbose=args.verbose)
def httpPut(self, args, props, update, payload): namespace, pname = parseQName(args.name, props) url = 'https://%(apibase)s/namespaces/%(namespace)s/%(collection)s/%(name)s%(update)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'collection': self.collection, 'name': self.getSafeName(pname), 'update': '?overwrite=true' if update else '' } headers= { 'Content-Type': 'application/json' } res = request('PUT', url, payload, headers, auth=args.auth, verbose=args.verbose) return res
def getState(self, args, props): namespace, pname = parseQName(args.name, props) url = '%(apibase)s/namespaces/%(namespace)s/rules/%(name)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'name': self.getSafeName(pname) } res = request('GET', url, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: result = json.loads(res.read()) print 'ok: rule %(name)s is %(status)s' % { 'name': args.name, 'status': result['status'] } return 0 else: return responseError(res)
def httpGet(self, args, props, name = None): if name is None: name = args.name namespace, pname = parseQName(name, props) if pname is None or pname.strip() == '': print 'error: entity name missing, did you mean to list collection' sys.exit(2) url = 'https://%(apibase)s/namespaces/%(namespace)s/%(collection)s/%(name)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'collection': self.collection, 'name': self.getSafeName(pname) } return request('GET', url, auth=args.auth, verbose=args.verbose)
def iosStarterAppDownload(self, args, props): zipFile = 'OpenWhiskIOSStarterApp.zip' if os.path.exists(zipFile): print('The path ' + zipFile + ' already exists. Please delete it and retry.') return -1 url = 'https://%s/%s' % (props['apihost'], zipFile) try: res = request('GET', url) if res.status == httplib.OK: with open(zipFile, 'wb') as f: f.write(res.read()) except IOError as e: print('Download of OpenWhisk iOS starter app failed.') return -1 print('\nDownloaded OpenWhisk iOS starter app. Unzip ' + zipFile + ' and open the project in Xcode.') return 0
def doInvoke(self, args, props): namespace, pname = parseQName(args.name, props) url = 'https://%(apibase)s/namespaces/%(namespace)s/actions/%(name)s?blocking=%(blocking)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'name': self.getSafeName(pname), 'blocking': 'true' if args.blocking else 'false' } payload = json.dumps(getActivationArgument(args)) headers = {'Content-Type': 'application/json'} res = request('POST', url, payload, headers, auth=args.auth, verbose=args.verbose) return res
def result(self, args, props): fqid = getQName(args.id, '_') # kludge: use default namespace unless explicitly specified namespace, aid = parseQName(fqid, props) url = '%(apibase)s/namespaces/%(namespace)s/activations/%(id)s/result' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'id': aid } res = request('GET', url, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: response = json.loads(res.read()) if 'result' in response: result = response['result'] print getPrettyJson(result) return 0 else: return responseError(res)
def httpPut(self, args, props, update, payload): namespace, pname = parseQName(args.name, props) url = 'https://%(apibase)s/namespaces/%(namespace)s/%(collection)s/%(name)s%(update)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'collection': self.collection, 'name': self.getSafeName(pname), 'update': '?overwrite=true' if update else '' } headers = {'Content-Type': 'application/json'} res = request('PUT', url, payload, headers, auth=args.auth, verbose=args.verbose) return res
def listEntitiesInNamespace(self, args, props): namespace, _ = parseQName(args.name, props) url = 'https://%(apibase)s/namespaces/%(namespace)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace) } res = request('GET', url, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: result = json.loads(res.read()) print 'entities in namespace: %s' % bold( namespace if namespace != '_' else 'default') self.printCollection(result, 'packages') self.printCollection(result, 'actions') self.printCollection(result, 'triggers') self.printCollection(result, 'rules') return 0 else: return responseError(res)
def fire(self, args, props): namespace, pname = parseQName(args.name, props) url = 'https://%(apibase)s/namespaces/%(namespace)s/triggers/%(name)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'name': self.getSafeName(pname) } payload = json.dumps(getActivationArgument(args)) headers= { 'Content-Type': 'application/json' } res = request('POST', url, payload, headers, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: result = json.loads(res.read()) print 'ok: triggered %(name)s with id %(id)s' % {'name': args.name, 'id': result['activationId'] } return 0 else: return responseError(res)
def GetActivationRecordsSince(since, limit=100): """ Returns details on activation records since a given tick in milliseconds """ configs = GetDBConfigs() url = configs['db_protocol']+'://'+configs['db_host']+':' + \ configs['db_port']+'/'+'whisk_local_activations/_find' headers = { 'Content-Type': 'application/json', } body = {"selector": {"start": {"$gte": since}}, "limit": limit} res = request('POST', url, body=json.dumps(body), headers=headers, auth='%s:%s' % (configs['db_username'], configs['db_password'])) return json.loads(res.read())
def logs(self, args, props): fqid = getQName(args.id, '_') # kludge: use default namespace unless explicitly specified namespace, aid = parseQName(fqid, props) url = '%(apibase)s/namespaces/%(namespace)s/activations/%(id)s/logs' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'id': aid } res = request('GET', url, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: result = json.loads(res.read()) logs = result['logs'] if args.strip: logs = map(stripTimeStampAndString, logs) print '\n'.join(logs) return 0 else: return responseError(res)
def GetActivationIDsSince(since, limit=100): """ Returns the activation IDs (including the namespace) """ configs = GetDBConfigs() url = configs['db_protocol']+'://'+configs['db_host']+':' + \ configs['db_port']+'/'+'whisk_local_activations/_find' headers = { 'Content-Type': 'application/json', } body = {"selector": {"start": {"$gte": since}}, "limit": limit} res = request('POST', url, body=json.dumps(body), headers=headers, auth='%s:%s' % (configs['db_username'], configs['db_password'])) doc = json.loads(res.read()) IDs = [x['_id'] for x in doc["docs"]] return IDs
def setState(self, args, props, enable): namespace, pname = parseQName(args.name, props) desc = 'active' if enable else 'inactive' status = json.dumps({ 'status': desc }) url = '%(apibase)s/namespaces/%(namespace)s/rules/%(name)s' % { 'apibase': apiBase(props), 'namespace': urllib.quote(namespace), 'name': self.getSafeName(pname) } headers = { 'Content-Type': 'application/json' } res = request('POST', url, status, headers, auth=args.auth, verbose=args.verbose) if res.status == httplib.OK: print 'ok: rule %(name)s is %(desc)s' % {'desc': desc, 'name': args.name} return 0 elif res.status == httplib.ACCEPTED: desc = 'activating' if enable else 'deactivating' print 'ok: rule %(name)s is %(desc)s' % {'desc': desc, 'name': args.name} return 0 else: return responseError(res)
def invoke(url, body): res = request('POST', url, body=body, headers=HEADERS, auth=AUTH_KEY) return res