Esempio n. 1
0
    def __init__(self, service_url: str, token: str) -> None:
        """Create a Swagger API client, load the Swagger definition from the provided service url, and set the
        authentication token for the domain name in the url.

        :param service_url: The base URL for the service, e.g. 'https://mon.hausnet.io/api', without a trailing slash.
        :param token:       The access token provided by the HausNet service.
        :raises:            Any exceptions that were raised during the Swagger client initialization, including
                            connection to the service.
        """
        host = urlparse(service_url).hostname
        http_client = RequestsClient()
        http_client.set_api_key(host=host,
                                api_key=f'Token {token}',
                                param_in='header',
                                param_name='Authorization')
        # noinspection PyBroadException
        try:
            self.client = SwaggerClient.from_url(f'{service_url}/swagger.json',
                                                 http_client=http_client)
            log.info(f"Connected to Heartbeat client at: url={service_url}")
        except Exception as e:
            log.exception(
                f"Failed to connect to Heartbeat client: url={service_url}")
            self.client = None
            raise e
Esempio n. 2
0
def client_factory(args):
    """ create a connection """
    global _CLIENT
    if not _CLIENT:
        config = {
            'validate_requests': False,
            'validate_responses': False
        }
        http_client = RequestsClient()
        hostname = urlparse(args.dos_server).hostname
        if args.api_key:
            http_client.set_api_key(hostname, args.api_key,
                                    param_name=args.api_key_name,
                                    param_in='header')
        if args.user_pass:
            (user, passwd) = args.user_pass.split(':')
            http_client.set_basic_auth(hostname, user, passwd)

        local_client = Client(args.dos_server, config=config,
                              http_client=http_client)

        class C(object):
            def __init__(self, local_client):
                self.client = local_client.client
                self.models = local_client.models

        _CLIENT = C(local_client)

    return _CLIENT
def annotate_scarif_video(uuid, start, end, label, assignmentId):
    """annotates a video in scarif using bravado.
    args:
        uuid: scarif video uuid (string)
        start: start frame (int)
        end: end frame (int)
        label: string
        assignmentId: AMT assignmentId (string)

    return:
        response: response of swagger client
            http://scarif-api.staging.wearkinetic.com/swagger.json

    side effects:
        a new entry is placed in the videoAnnotations table in scarif
    """
    # query to check that we've not already uploaded this annotation
    query = 'SELECT * FROM \"videoAnnotation\" WHERE label ~\'{:s}\''.format(
        assignmentId)
    import pg8000
    from os import environ as env
    conn = pg8000.connect(user=env['SCARIF_USER'],
                          host=env['SCARIF_HOST'],
                          database='scarif',
                          password=env['SCARIF_PASS'])
    cursor = conn.cursor()
    cursor.execute(query)
    response = cursor.fetchone()
    cursor.close()
    conn.close()

    if response != None:
        print('annotation is already present', file=sys.stderr)
        return response[0]

    #EXAMPLE CURL COMMAND
    #curl -X POST "http://scarif-api.wearkinetic.com/v1/annotate/video" -H "accept: application/json" -H "api_key: asdasd" -H "Content-Type: application/json" -d "{ \"end_time\": 0, \"label\": \"string\", \"start_time\": 1, \"target_uuid\": \"b607a3c1-87d1-417d-afa5-972ab2ce694f\"}"
    from bravado.requests_client import RequestsClient
    from bravado.client import SwaggerClient
    import json
    http_client = RequestsClient()
    http_client.set_api_key('scarif-api.wearkinetic.com',
                            'LITERALLY ANY STRING',
                            param_name='api_key',
                            param_in='header')
    client = SwaggerClient.from_url(
        'http://scarif-api.wearkinetic.com/swagger.json',
        http_client=http_client)
    label_aug = json.dumps({'label': label, 'assignmentId': assignmentId})
    ann = client.get_model('Annotation')(label=label_aug,
                                         start_time=start,
                                         end_time=end,
                                         target_uuid=uuid)
    return client.annotations.annotate(type='video', body=ann).result()
Esempio n. 4
0
def get_client(auth_token=AUTH_TOKEN):
    with open(os.getenv("SWAGGER_SCHEMA", "swagger.yml")) as f:
        spec = yaml.load(f)

    http_client = RequestsClient()
    http_client.set_api_key(
        HOSTNAME, auth_token,
        param_name='X-API-Key', param_in='header'
    )
    _client = SwaggerClient.from_spec(spec, http_client=http_client)
    _client.swagger_spec.api_url = HOST
    return _client
Esempio n. 5
0
 def __init__(self, url, jwt=None, config=DEFAULT_CONFIG):
     swagger_path = "{url}/swagger.json".format(url=url.rstrip("/"))
     if jwt:
         http_client = RequestsClient()
         http_client.set_api_key(host=urlparse(url).netloc,
                                 api_key=f"Bearer {jwt}",
                                 param_name="Authorization",
                                 param_in="header")
     else:
         http_client = None
     self.models = SwaggerClient.from_url(swagger_path, config=config)
     self.client = self.models.TaskService
 def __init__(self, api_key=None):
     http_client = RequestsClient()
     if api_key:
         http_client.set_api_key(self.host,
                                 api_key,
                                 param_name='Authorization',
                                 param_in='header')
     # Usually I'll use `from_url` generation, but current version of specification is not valid OpenAPI 2.0
     # self.client = SwaggerClient.from_url(self.swagger_spec, http_client=http_client)
     swagger_spec = json.load(self.swagger_file.open())
     self.client = SwaggerClient.from_spec(swagger_spec,
                                           http_client=http_client)
Esempio n. 7
0
 def __init__(self, apikey=None):
     http_client = None
     if apikey:
         http_client = RequestsClient()
         http_client.set_api_key('www.openml.org',
                                 apikey,
                                 param_name='api_key',
                                 param_in='header')
     file_path = os.path.abspath(__file__)
     src_path = os.path.join(os.path.dirname(file_path), '..')
     api_defs = os.path.join(src_path, 'swagger.yml')
     self.client = SwaggerClient.from_spec(load_file(api_defs),
                                           http_client=http_client)
Esempio n. 8
0
def _init_http_client(service_id=None, opts=None):
    """
    Initialize and configure HTTP requests client for selected service.
    """
    auth_header = {'token': 'Authorization', 'api_key': 'X-API-KEY', None: ''}
    if service_id:
        opts = _get_trs_opts(service_id)

    http_client = RequestsClient()

    http_client.set_api_key(host=opts['host'],
                            api_key=opts['auth'],
                            param_in='header')
    return http_client
Esempio n. 9
0
def load_client(apikey=None):
    host = 'api.mpcontribs.org' if apikey else 'localhost:5000'
    protocol = 'https' if apikey else 'http'
    spec_url = f'{protocol}://{host}/apispec.json'
    http_client = RequestsClient()
    if apikey:
        http_client.set_api_key(
            host, apikey, param_in='header', param_name='x-api-key'
        )
    loader = Loader(http_client)
    spec_dict = loader.load_spec(spec_url)
    spec_dict['host'] = host
    spec_dict['schemes'] = [protocol]
    return SwaggerClient.from_spec(spec_dict, spec_url, http_client,
                                   {'validate_responses': False})
Esempio n. 10
0
def init_http_client(service_id=None, opts=None):
    """
    Initialize and configure HTTP requests client for selected service.
    """
    auth_header = {'token': 'Authorization', 'api_key': 'X-API-KEY'}
    if service_id:
        opts = wes_config[service_id]

    http_client = RequestsClient()

    http_client.set_api_key(host=opts['host'],
                            api_key=opts['auth'],
                            param_name=auth_header[opts['auth_type']],
                            param_in='header')
    return http_client
Esempio n. 11
0
def get_client():
    access_token = "Bearer " + get_token()
    http_client = RequestsClient()
    http_client.set_api_key(
        'api.test.sabre.com', access_token,
        param_name='Authorization', param_in='header'
    )

    resource_package = __name__
    resource_path = '/swagger.yaml'  # Do not use os.path.join()

    swagger_path = pkg_resources.resource_filename(resource_package, resource_path)
    return SwaggerClient.from_spec(load_file(swagger_path),
                                   http_client=http_client,
                                   # config={'also_return_response': True}
                                   )
Esempio n. 12
0
def fog_venmo_client(use_models=True):
    host = settings.VENMO_HOST_URL
    requests_client = RequestsClient()
    api_token_header_name = swagger_file["securityDefinitions"]["api_key"][
        "name"]
    requests_client.set_api_key(
        host,
        settings.VENMO_API_TOKEN,
        param_name=api_token_header_name,
        param_in="header",
    )
    swagger_file["host"] = settings.VENMO_HOST_URL
    swagger_file["basePath"] = settings.VENMO_BASE_PATH
    return SwaggerClient.from_spec(swagger_file,
                                   http_client=requests_client,
                                   config={"use_models": use_models})
Esempio n. 13
0
def load_client(apikey=None):
    host = 'api.mpcontribs.org' if apikey else 'localhost:5000'
    protocol = 'https' if apikey else 'http'
    spec_url = f'{protocol}://{host}/apispec.json'
    http_client = RequestsClient()
    if apikey:
        http_client.set_api_key(host,
                                apikey,
                                param_in='header',
                                param_name='x-api-key')
    loader = Loader(http_client)
    spec_dict = loader.load_spec(spec_url)
    spec_dict['host'] = host
    spec_dict['schemes'] = [protocol]
    return SwaggerClient.from_spec(spec_dict, spec_url, http_client,
                                   {'validate_responses': False})
Esempio n. 14
0
    def test_api_key(self):
        httpretty.register_uri(
            httpretty.GET, "http://swagger.py/client-test",
            body='expected')

        client = RequestsClient()
        client.set_api_key("swagger.py", 'abc123', param_name='test')
        params = self._default_params()
        params['params'] = {'foo': 'bar'}

        resp = client.request(params).result()

        self.assertEqual(200, resp.status_code)
        self.assertEqual('expected', resp.text)
        self.assertEqual({'foo': ['bar'], 'test': ['abc123']},
                         httpretty.last_request().querystring)
Esempio n. 15
0
def _init_http_client(service_id=None, opts=None):
    """
    Initialize and configure HTTP requests client for selected service.

    Args:
        service_id (str): ...
        opts (dict): ...
    """
    if service_id:
        opts = _get_wes_opts(service_id)

    http_client = RequestsClient()
    http_client.set_api_key(
        host=opts['host'],
        api_key=opts['auth'],
        # param_name=auth_header[opts['auth_type']],
        param_in='header')
    return http_client
Esempio n. 16
0
    def test_api_key_header(self):
        httpretty.register_uri(
            httpretty.GET, "http://swagger.py/client-test",
            body='expected')

        client = RequestsClient()
        client.set_api_key("swagger.py", 'abc123', param_name='Key',
                           param_in='header')
        params = self._default_params()
        params['params'] = {'foo': 'bar'}

        resp = typing.cast(IncomingResponse, client.request(params).result())

        self.assertEqual(200, resp.status_code)
        self.assertEqual('expected', resp.text)
        self.assertEqual({'foo': ['bar']},
                         httpretty.last_request().querystring)
        self.assertEqual('abc123', httpretty.last_request().headers['Key'])
Esempio n. 17
0
    def test_api_key_header_overwrite(self):
        httpretty.register_uri(
            httpretty.GET, "http://swagger.py/client-test",
            body='expected')

        client = RequestsClient()
        client.set_api_key("swagger.py", 'abc123', param_name='Key',
                           param_in='header')
        params = self._default_params()
        params['params'] = {'foo': 'bar'}
        params['headers'] = {'Key': 'def456'}

        resp = client.request(params).result()  # type: IncomingResponse

        self.assertEqual(200, resp.status_code)
        self.assertEqual('expected', resp.text)
        self.assertEqual({'foo': ['bar']},
                         httpretty.last_request().querystring)
        self.assertEqual('def456', httpretty.last_request().headers['Key'])
Esempio n. 18
0
def TRSClient(host, auth, proto):
    """
    Build a :class:`SwaggerClient` from a url to the Swagger
    specification for the GA4GH Tool Registry Service RESTful API.
    """
    http_client = RequestsClient()
    split = urlparse.urlsplit("%s://%s/" % (proto, host))

    http_client.set_api_key(split.hostname,
                            auth,
                            param_name='Authorization',
                            param_in='header')

    return SwaggerClient.from_url("%s://%s/swagger.json" % (proto, host),
                                  http_client=http_client,
                                  config={
                                      'use_models': False,
                                      'validate_swagger_spec': False
                                  })
Esempio n. 19
0
def load_client(apikey=None):
    global client
    if client is None:
        # docker containers networking within docker-compose or Fargate task
        host = 'api.mpcontribs.org'
        if apikey is None:
            host = 'api:5000' if DEBUG else 'localhost:5000'
        protocol = 'https' if apikey else 'http'
        spec_url = f'{protocol}://{host}/apispec.json'
        http_client = RequestsClient()
        if apikey:
            http_client.set_api_key(host,
                                    apikey,
                                    param_in='header',
                                    param_name='x-api-key')
        loader = Loader(http_client)
        spec_dict = loader.load_spec(spec_url)
        spec_dict['host'] = host
        spec_dict['schemes'] = [protocol]
        client = SwaggerClient.from_spec(spec_dict, spec_url, http_client, {
            'validate_responses': False,
            'use_models': False
        })
    return client
Esempio n. 20
0
class OptlyAPI:
    """
    The OptlyAPI class gives an accesible wrapper to interact with Optimizely Rest & Event APIs

    Parameters:
    -----------
    accountId: int
        The Account ID you are wishing to access

    projectId: int
        The Project ID you are wishing to access

    token: str (optional)
        The Bearer token used for REST API authentication
        reference here: https://help.optimizely.com/Integrate_Other_Platforms/Generate_a_personal_access_token_in_Optimizely_X_Web

    swaggerURL: str
        URL for swagger file to help build API client via bravado
        https://bravado.readthedocs.io/en/stable/quickstart.html#usage
    """
    def __init__(self,
                 accountId,
                 projectId,
                 token=False,
                 download_swagger=True,
                 swaggerURL='https://api.optimizely.com/v2/swagger.json'):
        """
        Please refer to help(OptlyAPI) for more information
        """

        warnings.simplefilter("ignore")  # not log schema validation warnings

        self.accountId = accountId
        self.projectId = projectId
        self.swaggerURL = swaggerURL
        if download_swagger:
            self.config = {
                'use_models': False,
                'validate_responses': False,
                'validate_requests': False
            }

            if token:
                self.token = 'Bearer {}'.format(token)
                # applying authentication to all future requests for REST API
                self.http_client = RequestsClient()
                self.http_client.set_api_key('api.optimizely.com',
                                             self.token,
                                             param_name='Authorization',
                                             param_in='header')
                self.client = SwaggerClient.from_url(
                    swaggerURL,
                    http_client=self.http_client,
                    config=self.config
                )  # creating bravado client from swagger.json
            else:
                self.client = SwaggerClient.from_url(
                    swaggerURL, config=self.config
                )  # creating bravado client from swagger.json if no token provided

    def read_data(self,
                  data=None,
                  file_path=None,
                  type='csv/tsv',
                  delimiter=','):
        """
        The read_csv method wraps the pandas read_csv method and makes it possible to read in csv/tsv. This method returns an instance
        of the Response class.

        Parameters:
        -----------

        file_path: str 
            CSV/TSV data filepath

        delimiter: str
            The delimiter between data columns, denotes CSV (,) or TSV (\t)
        """
        if type == 'csv/tsv':
            df = read_csv(file_path,
                          delimiter=delimiter)  # read in the csv/tsv data
        elif type == 'df':
            df = data
        else:
            df = None
            print(
                'An invalid type was given for this method, the following are the supported values for the type param: csv/tsv, df'
            )
        response = Response(df, self.accountId)

        return response

    def get(self, type_list, all_asset_data=False, include_archived=False):
        """
        Fetch Optimizely assets using via REST API

        Parameters:
        -----------

        type_list: list
            List of strings denoting what kind of assets to fetch 

        all_asset_data: bool
            Denote whether or not to fetch the full asset data payload or just the trimmed versioning (search api)
            (Default): True 

        include_archived:bool
            Denote whether to include archived assets 
            (Default): False
        """
        # Initial variables
        response = []
        headers = {'Authorization': self.token}
        page = 1
        per_page = 100
        r_done = False
        r2_done = not include_archived

        # constructing base URL and all the types you want to query for
        url = 'https://api.optimizely.com/v2/search?&project_id={}&per_page={}&query'.format(
            self.projectId, per_page)
        for t in type_list:
            url += '&type={}'.format(t[:-1])

        # dictionary of swagger defined methods to fetch assets by id
        id_dict = {
            "audience": (getattr(self.client.Audiences,
                                 'get_audience'), 'audience_id'),
            "campaign": (getattr(self.client.Campaigns,
                                 'get_campaign'), 'campaign_id'),
            "event": (getattr(self.client.Events, 'get_event'), 'event_id'),
            "experiment": (getattr(self.client.Experiments,
                                   'get_experiment'), 'experiment_id'),
            "feature": (getattr(self.client.Features,
                                'get_feature'), 'feature_id'),
            "page": (getattr(self.client.Pages, 'get_page'), 'page_id')
        }

        while True:

            r_total_json = []

            if not r_done:  #grabbing non archived assets here
                r = requests.get(url + '&page={}'.format(page),
                                 headers=headers)
                if r.status_code == 200:
                    r_total_json += r.json()
                r_done = 'Link' not in r.headers or 'rel=last' not in r.headers[
                    'Link']

            if not r2_done:  # grabbing the archived assets here (if necessary)
                r2 = requests.get(url + '&archived=True&page={}'.format(page),
                                  headers=headers)
                if r2.status_code == 200:
                    r_total_json += r2.json()
                r2_done = 'Link' not in r2.headers or 'rel=last' not in r2.headers[
                    'Link']

            if all_asset_data:  # We want full asset payload
                asset_list = [(int(x['id']), x['type']) for x in r_total_json]

                # had to use a for loop here because in sub Python 3.8 you can't assign a local variable within list comprehension
                for asset in asset_list:
                    params = {id_dict[asset[1]][1]: asset[0]}
                    response.append(
                        id_dict[asset[1]][0](**params).response().result)

            else:  # Just want search_api response types
                response += r_total_json

            if r_done and r2_done:  # when both archived and non-archived have reached final page, exit while loop
                break

            page += 1  # get next page if no break

        response = Response(
            response)  # convert list of dicts to Response class instance

        return response
Esempio n. 21
0
def main(argv=sys.argv[1:]):

    parser = argparse.ArgumentParser(description='Workflow Execution Service')
    parser.add_argument("--host", type=str, default=os.environ.get("WES_API_HOST"))
    parser.add_argument("--auth", type=str, default=os.environ.get("WES_API_AUTH"))
    parser.add_argument("--proto", type=str, default=os.environ.get("WES_API_PROTO", "https"))
    parser.add_argument("--quiet", action="store_true", default=False)
    parser.add_argument("--outdir", type=str)

    exgroup = parser.add_mutually_exclusive_group()
    exgroup.add_argument("--run", action="store_true", default=False)
    exgroup.add_argument("--get", type=str, default=None)
    exgroup.add_argument("--log", type=str, default=None)
    exgroup.add_argument("--cancel", type=str, default=None)
    exgroup.add_argument("--list", action="store_true", default=False)
    exgroup.add_argument("--info", action="store_true", default=False)
    exgroup.add_argument("--version", action="store_true", default=False)

    exgroup = parser.add_mutually_exclusive_group()
    exgroup.add_argument("--wait", action="store_true", default=True, dest="wait")
    exgroup.add_argument("--no-wait", action="store_false", default=True, dest="wait")

    parser.add_argument("workflow_url", type=str, nargs="?", default=None)
    parser.add_argument("job_order", type=str, nargs="?", default=None)
    args = parser.parse_args(argv)

    if args.version:
        pkg = pkg_resources.require("wes_service")
        print(u"%s %s" % (sys.argv[0], pkg[0].version))
        exit(0)

    http_client = RequestsClient()
    split = urlparse.urlsplit("%s://%s/" % (args.proto, args.host))

    http_client.set_api_key(
        split.hostname, args.auth,
        param_name='Authorization', param_in='header')
    client = SwaggerClient.from_url("%s://%s/swagger.json" % (args.proto, args.host),
                                    http_client=http_client, config={'use_models': False})

    if args.info:
        l = client.WorkflowExecutionService.GetServiceInfo()
        json.dump(l.result(), sys.stdout, indent=4)
        return 0

    if args.list:
        l = client.WorkflowExecutionService.ListWorkflows()
        json.dump(l.result(), sys.stdout, indent=4)
        return 0

    if args.log:
        l = client.WorkflowExecutionService.GetWorkflowLog(workflow_id=args.log)
        sys.stdout.write(l.result()["workflow_log"]["stderr"])
        return 0

    if args.get:
        l = client.WorkflowExecutionService.GetWorkflowStatus(workflow_id=args.get)
        json.dump(l.result(), sys.stdout, indent=4)
        return 0

    if args.cancel:
        l = client.WorkflowExecutionService.CancelJob(workflow_id=args.cancel)
        json.dump(l.result(), sys.stdout, indent=4)
        return 0

    with open(args.job_order) as f:
        input = yaml.safe_load(f)
        basedir = os.path.dirname(args.job_order)
        def fixpaths(d):
            if isinstance(d, dict) and "location" in d:
                if not ":" in d["location"]:
                    d["location"] = urllib.pathname2url(os.path.normpath(os.path.join(os.getcwd(), basedir, d["location"])))
        visit(input, fixpaths)

    workflow_url = args.workflow_url
    if not workflow_url.startswith("/") and ":" not in workflow_url:
        workflow_url = os.path.abspath(workflow_url)

    if args.quiet:
        logging.basicConfig(level=logging.WARNING)
    else:
        logging.basicConfig(level=logging.INFO)

    r = client.WorkflowExecutionService.RunWorkflow(body={
        "workflow_url": workflow_url,
        "workflow_params": input,
        "workflow_type": "CWL",
        "workflow_type_version": "v1.0"}).result()

    if args.wait:
        logging.info("Workflow id is %s", r["workflow_id"])
    else:
        sys.stdout.write(r["workflow_id"]+"\n")
        exit(0)

    r = client.WorkflowExecutionService.GetWorkflowStatus(workflow_id=r["workflow_id"]).result()
    while r["state"] in ("QUEUED", "INITIALIZING", "RUNNING"):
        time.sleep(1)
        r = client.WorkflowExecutionService.GetWorkflowStatus(workflow_id=r["workflow_id"]).result()

    logging.info("State is %s", r["state"])

    s = client.WorkflowExecutionService.GetWorkflowLog(workflow_id=r["workflow_id"]).result()
    logging.info(s["workflow_log"]["stderr"])

    if "fields" in s["outputs"] and s["outputs"]["fields"] is None:
        del s["outputs"]["fields"]
    json.dump(s["outputs"], sys.stdout, indent=4)

    if r["state"] == "COMPLETE":
        return 0
    else:
        return 1
Esempio n. 22
0
def main(argv=sys.argv[1:]):
    parser = argparse.ArgumentParser(description='Workflow Execution Service')
    parser.add_argument("--host",
                        type=str,
                        default=os.environ.get("WES_API_HOST"))
    parser.add_argument("--auth",
                        type=str,
                        default=os.environ.get("WES_API_AUTH"))
    parser.add_argument("--proto",
                        type=str,
                        default=os.environ.get("WES_API_PROTO", "https"))
    parser.add_argument("--quiet", action="store_true", default=False)
    parser.add_argument("--outdir", type=str)

    exgroup = parser.add_mutually_exclusive_group()
    exgroup.add_argument("--run", action="store_true", default=False)
    exgroup.add_argument("--get", type=str, default=None)
    exgroup.add_argument("--log", type=str, default=None)
    exgroup.add_argument("--list", action="store_true", default=False)
    exgroup.add_argument("--info", action="store_true", default=False)
    exgroup.add_argument("--version", action="store_true", default=False)

    exgroup = parser.add_mutually_exclusive_group()
    exgroup.add_argument("--wait",
                         action="store_true",
                         default=True,
                         dest="wait")
    exgroup.add_argument("--no-wait",
                         action="store_false",
                         default=True,
                         dest="wait")

    parser.add_argument("workflow_url", type=str, nargs="?", default=None)
    parser.add_argument("job_order", type=str, nargs="?", default=None)
    args = parser.parse_args(argv)

    if args.version:
        pkg = pkg_resources.require("wes_service")
        print(u"%s %s" % (sys.argv[0], pkg[0].version))
        exit(0)

    http_client = RequestsClient()
    split = urlparse.urlsplit("%s://%s/" % (args.proto, args.host))

    http_client.set_api_key(split.hostname,
                            args.auth,
                            param_name='Authorization',
                            param_in='header')
    client = SwaggerClient.from_url("%s://%s/ga4gh/wes/v1/swagger.json" %
                                    (args.proto, args.host),
                                    http_client=http_client,
                                    config={'use_models': False})

    if args.list:
        response = client.WorkflowExecutionService.ListWorkflows()
        json.dump(response.result(), sys.stdout, indent=4)
        return 0

    if args.log:
        response = client.WorkflowExecutionService.GetWorkflowLog(
            workflow_id=args.log)
        sys.stdout.write(response.result()["workflow_log"]["stderr"])
        return 0

    if args.get:
        response = client.WorkflowExecutionService.GetWorkflowLog(
            workflow_id=args.get)
        json.dump(response.result(), sys.stdout, indent=4)
        return 0

    if args.info:
        response = client.WorkflowExecutionService.GetServiceInfo()
        json.dump(response.result(), sys.stdout, indent=4)
        return 0

    loader = schema_salad.ref_resolver.Loader({
        "location": {
            "@type": "@id"
        },
        "path": {
            "@type": "@id"
        }
    })
    input, _ = loader.resolve_ref(args.job_order)

    basedir = os.path.dirname(args.job_order)

    def fixpaths(d):
        if isinstance(d, dict):
            if "path" in d:
                if ":" not in d["path"]:
                    local_path = os.path.normpath(
                        os.path.join(os.getcwd(), basedir, d["path"]))
                    d["location"] = urllib.pathname2url(local_path)
                else:
                    d["location"] = d["path"]
                del d["path"]
            loc = d.get("location", "")
            if d.get("class") == "Directory":
                if loc.startswith("http:") or loc.startswith("https:"):
                    logging.error(
                        "Directory inputs not supported with http references")
                    exit(33)
            if not (loc.startswith("http:") or loc.startswith("https:")
                    or args.job_order.startswith("http:")
                    or args.job_order.startswith("https:")):
                logging.error(
                    "Upload local files not supported, must use http: or https: references."
                )
                exit(33)

    visit(input, fixpaths)

    workflow_url = args.workflow_url
    if not workflow_url.startswith("/") and ":" not in workflow_url:
        workflow_url = "file://" + os.path.abspath(workflow_url)

    if args.quiet:
        logging.basicConfig(level=logging.WARNING)
    else:
        logging.basicConfig(level=logging.INFO)

    body = {
        "workflow_params": input,
        "workflow_type": "CWL",
        "workflow_type_version": "v1.0"
    }

    if workflow_url.startswith("file://"):
        with open(workflow_url[7:], "r") as f:
            body["workflow_descriptor"] = f.read()
    else:
        body["workflow_url"] = workflow_url

    r = client.WorkflowExecutionService.RunWorkflow(body=body).result()

    if args.wait:
        logging.info("Workflow id is %s", r["workflow_id"])
    else:
        sys.stdout.write(r["workflow_id"] + "\n")
        exit(0)

    r = client.WorkflowExecutionService.GetWorkflowStatus(
        workflow_id=r["workflow_id"]).result()
    while r["state"] in ("QUEUED", "INITIALIZING", "RUNNING"):
        time.sleep(1)
        r = client.WorkflowExecutionService.GetWorkflowStatus(
            workflow_id=r["workflow_id"]).result()

    logging.info("State is %s", r["state"])

    s = client.WorkflowExecutionService.GetWorkflowLog(
        workflow_id=r["workflow_id"]).result()
    logging.info("Workflow log:\n" + s["workflow_log"]["stderr"])

    if "fields" in s["outputs"] and s["outputs"]["fields"] is None:
        del s["outputs"]["fields"]
    json.dump(s["outputs"], sys.stdout, indent=4)

    if r["state"] == "COMPLETE":
        return 0
    else:
        return 1
def main():
    module_args = {
        "state": {
            "type": "str",
            "default": "present",
            "choices": ["present", "absent", "exists"],
        },
        "name": {
            "type": "str",
            "required": True,
        },
        "server_id": {
            "type": "str",
            "default": "localhost",
        },
        "api_url": {
            "type": "str",
            "default": "http://localhost:8081",
        },
        "api_key": {
            "type": "str",
            "required": True,
            "no_log": True,
        },
        "api_spec_file": {
            "type": "path",
            "required": True,
        },
        "algorithm": {
            "type":
            "str",
            "default":
            "hmac-md5",
            "choices": [
                "hmac-md5",
                "hmac-sha1",
                "hmac-sha224",
                "hmac-sha256",
                "hmac-sha384",
                "hmac-sha512",
            ],
        },
        "key": {
            "type": "str"
        },
    }

    module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)

    try:
        from bravado.requests_client import RequestsClient
        from bravado.client import SwaggerClient
        from bravado.swagger_model import load_file
    except ImportError:
        module.fail_json(
            msg="The pdns_auth_tsigkey module requires the 'bravado' package.")

    result = {
        "changed": False,
    }

    state = module.params["state"]
    server_id = module.params["server_id"]
    key = module.params["name"]

    if module.check_mode:
        module.exit_json(**result)

    url = urlparse(module.params["api_url"])

    http_client = RequestsClient()
    http_client.set_api_key(url.netloc,
                            module.params["api_key"],
                            param_name="X-API-Key",
                            param_in="header")

    spec = load_file(module.params["api_spec_file"])
    spec["host"] = url.netloc
    spec["schemes"] = [url.scheme]

    api = SwaggerClient.from_spec(spec, http_client=http_client)

    result["key"] = {"name": key, "exists": False}

    # first step is to get information about the key, if it exists
    # this is required to translate the user-friendly key name into
    # the key_id required for subsequent API calls

    partial_key_info = [
        k for k in api.tsigkey.listTSIGKeys(server_id=server_id).result()
        if k["name"] == key
    ]

    if len(partial_key_info) == 0:
        if (state == "exists") or (state == "absent"):
            # exit as there is nothing left to do
            module.exit_json(**result)
        else:
            # state must be 'present'
            key_id = None
    else:
        # get the full key info and populate the result dict
        key_id = partial_key_info[0]["id"]
        key_info = api.tsigkey.getTSIGKey(server_id=server_id,
                                          tsigkey_id=key_id).result()
        result["key"]["exists"] = True
        result["key"]["algorithm"] = key_info["algorithm"]
        result["key"]["key"] = key_info["key"]

    # if only an existence check was requested,
    # the operation is complete
    if state == "exists":
        module.exit_json(**result)

    # if absence was requested, remove the zone and exit
    if state == "absent":
        api.tsigkey.deleteTSIGKey(server_id=server_id,
                                  tsigkey_id=key_id).result()
        result["changed"] = True
        module.exit_json(**result)

    # state must be 'present'
    if not key_id:
        # create the requested key
        key_struct = {
            "name": key,
            "algorithm": module.params["algorithm"],
        }

        if module.params["key"]:
            key_struct["key"] = module.params["key"]

        key_info = api.tsigkey.createTSIGKey(server_id=server_id,
                                             tsigkey=key_struct).result()
        result["changed"] = True
        result["key"]["exists"] = True
        result["key"]["algorithm"] = key_info["algorithm"]
        result["key"]["key"] = key_info["key"]
    else:
        # compare the key's attributes to the provided
        # options and update it if necessary
        key_struct = {}

        if module.params["algorithm"]:
            if module.params["algorithm"] != key_info["algorithm"]:
                key_struct["algorithm"] = module.params["algorithm"]

        if module.params["key"]:
            if module.params["key"] != key_info["key"]:
                key_struct["key"] = module.params["key"]

        if len(key_struct):
            key_info = api.tsigkey.putTSIGKey(server_id=server_id,
                                              tsigkey_id=key_id,
                                              tsigkey=key_struct).result()
            result["changed"] = True

        if result["changed"]:
            result["key"]["algorithm"] = key_info["algorithm"]
            result["key"]["key"] = key_info["key"]

    module.exit_json(**result)
Esempio n. 24
0
#!/usr/bin/env python

import os
from bravado.requests_client import RequestsClient
from bravado.client import SwaggerClient
from bravado.swagger_model import load_file
from pprint import pprint
import bravado_core

http_client = RequestsClient()
http_client.set_api_key(os.environ.get('SPACECRAB_API_HOSTNAME'),
                        os.environ.get('SPACECRAB_API_KEY'),
                        param_name='x-api-key',
                        param_in='header')

client = SwaggerClient.from_spec(
    load_file('SpaceCrab API-v0-swagger-apigateway.yaml'),
    http_client=http_client,
    config={'also_return_response': True})

AddTokenRequest = client.get_model('AddTokenRequest')
requestBody = AddTokenRequest(Owner="John Smithington",
                              Location="DMZ",
                              ExpiresAt="2016-01-01 00:00:00",
                              Notes="Generated by bravado")
AddToken, http_response = client.token.AddToken(
    AddTokenRequest=requestBody).result()
print(AddToken)

UpdateTokenRequest = client.get_model('UpdateTokenRequest')
requestBody = UpdateTokenRequest(AccessKeyId=AddToken.AccessKey['AccessKeyId'],
Esempio n. 25
0
from bravado.requests_client import RequestsClient
from bravado.client import SwaggerClient

http_client = RequestsClient()
url = 'http://172.30.3.174/content/apidocs/index.html'
token = 'eyJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJkZWZhdWx0Iiwic3ViIjoiZGVsaXZlcnlAdG9rZW4uY29tIiwiYXVkIjoicWVkOmRlZmF1bHQiLCJxZWRwIjpbImQiLCJnIiwiYyIsInMiLCJtIiwiYSIsInAiXSwiZXhwIjoxNTY3MTk5ODQ4fQ.SLo2AoCFsj9awqYxG7u5UwC6QZD4S9IlE1XMOuOKNGo'
# header1 = {
# "Accept": "application/json,application/vnd.qumu.qed+json,application/vnd.qumu.qed.v1+json" ,
# "Authorization": "Bearer "+token+""
# }

http_client.set_api_key(
    'url',
    'token'
)
client = SwaggerClient.from_url('http://172.30.3.174/services/apidocs/qed.json', http_client=http_client)
AuthorizationSystemsByID = client.AuthorizationSystems.authorizationSystemsById(authorizationSystemsid= 'default').result()

# from bravado.requests_client import RequestsClient
# from bravado.client import SwaggerClient
#
# http_client = RequestsClient()
# http_client.set_api_key(
#     'http://petstore.swagger.io', 'special-key'
# )
# client = SwaggerClient.from_url(
#     'http://petstore.swagger.io/v2/swagger.json',
#     http_client=http_client,
# )
# pet = client.pet.getPetById(petId=42).result()
# print pet
Esempio n. 26
0
            "accept": "application/json",
            "Content-Type": "application/json"
        },
    )
    if token.status_code == 401:
        print("Login failed")
        sys.exit(1)
    if token.status_code != 200:
        print(token.status_code, token.text)
        sys.exit(1)
    return token.json()


if __name__ == "__main__":

    token = get_token("*****@*****.**", "bla")["token"]

    http_client = RequestsClient()
    http_client.set_api_key(api_host,
                            token,
                            param_name='x-access-token',
                            param_in='header')

    client = SwaggerClient.from_url(
        'https://' + api_host + '/swagger.json',
        http_client=http_client,
    )

    print("Starting tests")
    test_api()
Esempio n. 27
0
def main(argv=sys.argv[1:]):
    parser = argparse.ArgumentParser(description="Workflow Execution Service")
    parser.add_argument("--host", type=str, default=os.environ.get("WES_API_HOST"),
                        help="Example: '--host=localhost:8080'.  Defaults to WES_API_HOST.")
    parser.add_argument("--auth", type=str, default=os.environ.get("WES_API_AUTH"), help="Defaults to WES_API_AUTH.")
    parser.add_argument("--proto", type=str, default=os.environ.get("WES_API_PROTO", "https"),
                        help="Options: [http, https].  Defaults to WES_API_PROTO (https).")
    parser.add_argument("--quiet", action="store_true", default=False)
    parser.add_argument("--outdir", type=str)
    parser.add_argument("--page", type=str, default=None)
    parser.add_argument("--page-size", type=int, default=None)

    exgroup = parser.add_mutually_exclusive_group()
    exgroup.add_argument("--run", action="store_true", default=False)
    exgroup.add_argument("--get", type=str, default=None,
                         help="Specify a <workflow-id>.  Example: '--get=<workflow-id>'")
    exgroup.add_argument("--log", type=str, default=None,
                         help="Specify a <workflow-id>.  Example: '--log=<workflow-id>'")
    exgroup.add_argument("--list", action="store_true", default=False)
    exgroup.add_argument("--info", action="store_true", default=False)
    exgroup.add_argument("--version", action="store_true", default=False)

    exgroup = parser.add_mutually_exclusive_group()
    exgroup.add_argument("--wait", action="store_true", default=True, dest="wait")
    exgroup.add_argument("--no-wait", action="store_false", default=True, dest="wait")

    parser.add_argument("workflow_url", type=str, nargs="?", default=None)
    parser.add_argument("job_order", type=str, nargs="?", default=None)
    args = parser.parse_args(argv)

    if args.version:
        pkg = pkg_resources.require("wes_service")
        print(u"%s %s" % (sys.argv[0], pkg[0].version))
        exit(0)

    http_client = RequestsClient()
    split = urlparse.urlsplit("%s://%s/" % (args.proto, args.host))

    http_client.set_api_key(
        split.hostname, args.auth,
        param_name="Authorization", param_in="header")
    client = SwaggerClient.from_url(
        "%s://%s/ga4gh/wes/v1/swagger.json" % (args.proto, args.host),
        http_client=http_client, config={"use_models": False})

    if args.list:
        response = client.WorkflowExecutionService.ListRuns(page_token=args.page, page_size=args.page_size)
        json.dump(response.result(), sys.stdout, indent=4)
        return 0

    if args.log:
        response = client.WorkflowExecutionService.GetRunLog(workflow_id=args.log)
        sys.stdout.write(response.result()["workflow_log"]["stderr"])
        return 0

    if args.get:
        response = client.WorkflowExecutionService.GetRunLog(workflow_id=args.get)
        json.dump(response.result(), sys.stdout, indent=4)
        return 0

    if args.info:
        response = client.WorkflowExecutionService.GetServiceInfo()
        json.dump(response.result(), sys.stdout, indent=4)
        return 0

    if not args.workflow_url:
        parser.print_help()
        return 1

    if args.workflow_url.lower().endswith('wdl'):
        wf_type = 'WDL'
    elif args.workflow_url.lower().endswith('cwl'):
        wf_type = 'CWL'
    elif args.workflow_url.lower().endswith('py'):
        wf_type = 'PY'

    if not args.job_order:
        logging.error("Missing job order")
        return 1

    loader = schema_salad.ref_resolver.Loader({
        "location": {"@type": "@id"},
        "path": {"@type": "@id"}
    })
    input_dict, _ = loader.resolve_ref(args.job_order, checklinks=False)

    basedir = os.path.dirname(args.job_order)

    def fixpaths(d):
        """Make sure all paths have a schema."""
        if isinstance(d, dict):
            if "path" in d:
                if ":" not in d["path"]:
                    local_path = os.path.normpath(os.path.join(os.getcwd(), basedir, d["path"]))
                    d["location"] = urllib.pathname2url(local_path)
                else:
                    d["location"] = d["path"]
                del d["path"]
    visit(input_dict, fixpaths)

    workflow_url = args.workflow_url
    if ":" not in workflow_url:
        workflow_url = "file://" + os.path.abspath(workflow_url)

    if args.quiet:
        logging.basicConfig(level=logging.WARNING)
    else:
        logging.basicConfig(level=logging.INFO)

    parts = [
        ("workflow_params", json.dumps(input_dict)),
        ("workflow_type", wf_type),
        ("workflow_type_version", "v1.0")
    ]
    if workflow_url.startswith("file://"):
        # with open(workflow_url[7:], "rb") as f:
        #     body["workflow_attachment"] = f.read()
        rootdir = os.path.dirname(workflow_url[7:])
        dirpath = rootdir
        # for dirpath, dirnames, filenames in os.walk(rootdir):
        for f in os.listdir(rootdir):
            if f.startswith("."):
                continue
            fn = os.path.join(dirpath, f)
            if os.path.isfile(fn):
                parts.append(('workflow_attachment', (fn[len(rootdir)+1:], open(fn, "rb"))))
        parts.append(("workflow_url", os.path.basename(workflow_url[7:])))
    else:
        parts.append(("workflow_url", workflow_url))

    postresult = http_client.session.post("%s://%s/ga4gh/wes/v1/runs" % (args.proto, args.host),
                                          files=parts,
                                          headers={"Authorization": args.auth})

    try:
        r = json.loads(postresult.text)
    except ValueError:
        logging.error("%s", postresult.text)
        exit(1)

    if postresult.status_code != 200:
        logging.error("%s", r)
        exit(1)

    if args.wait:
        logging.info("Workflow run id is %s", r["run_id"])
    else:
        sys.stdout.write(r["run_id"] + "\n")
        exit(0)

    r = client.WorkflowExecutionService.GetRunStatus(run_id=r["run_id"]).result()
    while r["state"] in ("QUEUED", "INITIALIZING", "RUNNING"):
        time.sleep(8)
        r = client.WorkflowExecutionService.GetRunStatus(run_id=r["run_id"]).result()

    logging.info("State is %s", r["state"])

    s = client.WorkflowExecutionService.GetRunLog(run_id=r["run_id"]).result()

    try:
        # TODO: Only works with Arvados atm
        logging.info(str(s["workflow_log"]["stderr"]))
        logs = requests.get(s["workflow_log"]["stderr"], headers={"Authorization": args.auth}).text
        logging.info("Workflow log:\n" + logs)
    except InvalidSchema:
        logging.info("Workflow log:\n" + str(s["workflow_log"]["stderr"]))
    except MissingSchema:
        logging.info("Workflow log:\n" + str(s["workflow_log"]["stderr"]))

    if "fields" in s["outputs"] and s["outputs"]["fields"] is None:
        del s["outputs"]["fields"]
    json.dump(s["outputs"], sys.stdout, indent=4)

    if r["state"] == "COMPLETE":
        return 0
    else:
        return 1
Esempio n. 28
0
def main():
    module_args = {
        "state": {
            "type": "str",
            "default": "present",
            "choices": ["present", "absent", "exists", "notify", "retrieve"],
        },
        "name": {
            "type": "str",
            "required": True,
        },
        "server_id": {
            "type": "str",
            "default": "localhost",
        },
        "api_url": {
            "type": "str",
            "default": "http://localhost:8081",
        },
        "api_key": {
            "type": "str",
            "required": True,
            "no_log": True,
        },
        "api_spec_file": {
            "type": "path",
            "required": True,
        },
        "properties": {
            "type": "dict",
            "options": {
                "kind": {
                    "type": "str",
                    "choices": ["Native", "Master", "Slave"],
                    "required": True,
                },
                "account": {
                    "type": "str",
                },
                "nameservers": {
                    "type": "list",
                    "elements": "str",
                },
                "masters": {
                    "type": "list",
                    "elements": "str",
                },
            },
        },
        "metadata": {
            "type": "dict",
            "options": {
                "allow_axfr_from": {
                    "type": "list",
                    "elements": "str",
                },
                "allow_dnsupdate_from": {
                    "type": "list",
                    "elements": "str",
                },
                "also_notify": {
                    "type": "list",
                    "elements": "str",
                },
                "axfr_source": {
                    "type": "str",
                },
                "forward_dnsupdate": {
                    "type": "bool",
                },
                "gss_acceptor_principal": {
                    "type": "str",
                },
                "gss_allow_axfr_principal": {
                    "type": "str",
                },
                "ixfr": {
                    "type": "bool",
                },
                "notify_dnsupdate": {
                    "type": "bool",
                },
                "publish_cndskey": {
                    "type": "bool",
                },
                "publish_cds": {
                    "type": "list",
                    "elements": "str",
                },
                "slave_renotify": {
                    "type": "bool",
                },
                "soa_edit_dnsupdate": {
                    "type":
                    "str",
                    "default":
                    "DEFAULT",
                    "choices": [
                        "DEFAULT",
                        "INCREASE",
                        "EPOCH",
                        "SOA-EDIT",
                        "SOA-EDIT-INCREASE",
                    ],
                },
                "tsig_allow_dnsupdate": {
                    "type": "list",
                    "elements": "str",
                },
            },
        },
    }

    module = AnsibleModule(argument_spec=module_args, supports_check_mode=True)

    try:
        from bravado.requests_client import RequestsClient
        from bravado.client import SwaggerClient
        from bravado.swagger_model import load_file
    except ImportError:
        module.fail_json(
            msg="The pdns_auth_zone module requires the 'bravado' package.")

    result = {
        "changed": False,
    }

    state = module.params["state"]
    server_id = module.params["server_id"]
    zone = module.params["name"]

    if module.check_mode:
        module.exit_json(**result)

    url = urlparse(module.params["api_url"])

    http_client = RequestsClient()
    http_client.set_api_key(url.netloc,
                            module.params["api_key"],
                            param_name="X-API-Key",
                            param_in="header")

    spec = load_file(module.params["api_spec_file"])
    spec["host"] = url.netloc
    spec["schemes"] = [url.scheme]

    raw_api = SwaggerClient.from_spec(spec, http_client=http_client)

    # create an APIWrapper to proxy the raw_api object
    # and curry the server_id and zone_id into all API
    # calls automatically
    api = APIWrapper(raw_api, server_id, None)

    result["zone"] = {}
    result["zone"]["name"] = zone
    result["zone"]["exists"] = False

    # first step is to get information about the zone, if it exists
    # this is required to translate the user-friendly zone name into
    # the zone_id required for subsequent API calls

    partial_zone_info = api.zones.listZones(zone=zone)

    if len(partial_zone_info) == 0:
        if (state == "exists") or (state == "absent"):
            # exit as there is nothing left to do
            module.exit_json(**result)
        elif state == "notify":
            module.fail_json(
                msg="NOTIFY cannot be requested for a non-existent zone",
                **result)
        elif state == "retrieve":
            module.fail_json(
                msg="Retrieval cannot be requested for a non-existent zone",
                **result)
        else:
            # state must be 'present'
            zone_id = None
    else:
        #
        # get the full zone info and populate the result dict
        zone_id = partial_zone_info[0]["id"]
        api.setZoneID(zone_id)
        zone_info, result["zone"] = build_zone_result(api)

    # if only an existence check was requested,
    # the operation is complete
    if state == "exists":
        module.exit_json(**result)

    # if absence was requested, remove the zone and exit
    if state == "absent":
        api.zones.deleteZone()
        result["changed"] = True
        module.exit_json(**result)

    # if NOTIFY was requested, process it and exit
    if state == "notify":
        if zone_info["kind"] == "Native":
            module.fail_json(
                msg="NOTIFY cannot be requested for 'Native' zones", **result)

        api.zones.notifyZone()
        result["changed"] = True
        module.exit_json(**result)

    # if retrieval was requested, process it and exit
    if state == "retrieve":
        if zone_info["kind"] != "Slave":
            module.fail_json(
                msg="Retrieval can only be requested for 'Slave' zones",
                **result)

        api.zones.axfrRetrieveZone()
        result["changed"] = True
        module.exit_json(**result)

    # state must be 'present'
    if not zone_id:
        # create the requested zone
        zone_struct = {
            "name": zone,
        }

        if module.params["properties"]:
            props = module.params["properties"]

            if props["kind"]:
                zone_struct["kind"] = props["kind"]

                if props["kind"] != "Slave":
                    zone_struct["nameservers"] = props["nameservers"]

                if props["kind"] == "Slave":
                    zone_struct["masters"] = props["masters"]

            if props["account"]:
                zone_struct["account"] = props["account"]

        api.zones.createZone(rrsets=False, zone_struct=zone_struct)
        result["changed"] = True
        partial_zone_info = api.zones.listZones(zone=zone)
        api.setZoneID(partial_zone_info[0]["id"])

        if module.params["metadata"]:
            meta = module.params["metadata"]
            Metadata.set_all(meta, api)

        zone_info, result["zone"] = build_zone_result(api)
    else:
        # compare the zone's attributes to the provided
        # options and update it if necessary
        zone_struct = {}

        if module.params["properties"]:
            props = module.params["properties"]

            if props["kind"]:
                if zone_info["kind"] != props["kind"]:
                    zone_struct["kind"] = props["kind"]

                if props["kind"] == "Slave":
                    if props["masters"]:
                        mp_masters = props["masters"].sort()
                        zi_masters = zone_info["masters"].sort()

                        if zi_masters != mp_masters:
                            zone_struct["masters"] = props["masters"]

            if props["account"]:
                if zone_info["account"] != props["account"]:
                    zone_struct["account"] = props["account"]

        if len(zone_struct):
            api.zones.putZone(zone_struct=zone_struct)
            result["changed"] = True

        if module.params["metadata"]:
            old = result["zone"]["metadata"]
            new = module.params["metadata"]
            if Metadata.update_all(old, new, api):
                result["changed"] = True

        if result["changed"]:
            zone_info, result["zone"] = build_zone_result(api)

    module.exit_json(**result)