Example #1
0
def auth(configuration: Configuration, secrets: Secrets) -> Dict[str, str]:
    """
    Authenticate with the Cloud Foundry API endpoint.

    The `configuration` mapping must include `"api_url"` key associated to the
    URL of the API server, for example: `"https://api.local.pcfdev.io"`.

    When testing against a secured endpoint exposing self-signed certificate,
    you should set `"verify_ssl"` to `True`.

    The `secrets` mapping must contain:

    `"username"`: the user to authenticate with
    `"password"`: the user's password
    `"client_id"` the client id to authenticate with, defaults to `"cf"`
    `"client_secret"`: the client's secret, defaults to `""`

    Returns a mapping with the `access_token` and `refresh_token` keys as per
    http://docs.cloudfoundry.org/api/uaa/version/4.8.0/index.html#password-grant
    """

    api_url = configuration.get("cf_api_url")
    verify_ssl = configuration.get("cf_verify_ssl", True)

    username = secrets.get("cf_username")
    password = secrets.get("cf_password")
    client_id = secrets.get("cf_client_id", "cf")
    client_secret = secrets.get("cf_client_secret", "")

    logger.debug(
        "Querying a new access token for client '{c}'".format(c=client_id))
    return get_tokens(api_url, username, password, client_id, client_secret,
                      verify_ssl)
def rmq_client_connect(configuration: Configuration = None,
                       secrets: Secrets = None):
    rmq_api_rest_endpoint = os.getenv(secrets.get("rabbitmq_restendpoint"))
    rmq_username = os.getenv(secrets.get("rabbitmq_username"))
    rmq_password = os.getenv(secrets.get("rabbitmq_password"))
    return Client(rmq_api_rest_endpoint,
                  rmq_username,
                  rmq_password,
                  scheme='https')
def probe_app_can_connect_and_send_message_to_rabbit(
        configuration: Configuration = None, secrets: Secrets = None):

    if not secrets:
        raise ActivityFailed(
            "Please set the secrets entry to specify the SSH client settings")

    # Create ssh client
    client = ssh.connect(secrets)

    # Get RabbitMQ connection params from secrets
    rmq_api_rest_endpoint = os.getenv(secrets.get("rabbitmq_restendpoint"))
    rmq_username = os.getenv(secrets.get("rabbitmq_username"))
    rmq_password = os.getenv(secrets.get("rabbitmq_password"))
    rmq_vhost_url = os.getenv(
        secrets.get("rabbitmq_host")) + "/api/healthchecks/node"
    rabbit_creds = rmq_username + ":" + rmq_password

    wait_time = int(os.getenv('WAIT_TIME'))
    if wait_time > 0:
        logger.info("Waiting for " + str(wait_time) +
                    " secs before connecting to rabbit")
        time.sleep(wait_time)

    rabbitmq_connect_curl = 'curl -s -u {rabbitmq_creds} {rabbitmq_host}'.format(
        rabbitmq_creds=rabbit_creds, rabbitmq_host=rmq_vhost_url)

    stdin, stdout, stderr = client.exec_command(rabbitmq_connect_curl)
    o, r = stdout.read().decode('utf-8'), stderr.read().decode('utf-8')
    client.close()

    logger.info(o)

    error = False

    if r != "":
        logger.warn(r)
        error = True

    rmq_client = rmq_client_connect(configuration, secrets)

    rmq_client.create_vhost("ce_vhost")
    rmq_client.create_exchange("ce_vhost", "ce_exc", "direct")
    rmq_client.create_queue("ce_vhost", "ce_que")
    rmq_client.create_binding("ce_vhost", "ce_exc", "ce_que", "ce.rtkey")
    if not rmq_client.publish('ce_vhost', 'ce_exc', 'ce.rtkey',
                              'chaos experiment message'):
        error = True
    rmq_client.delete_vhost("ce_vhost")

    return not error
Example #4
0
def run_python_activity(activity: Activity, configuration: Configuration,
                        secrets: Secrets) -> Any:
    """
    Run a Python activity.

    A python activity is a function from any importable module. The result
    of that function is returned as the activity's output.

    This should be considered as a private function.
    """
    provider = activity["provider"]
    mod_path = provider["module"]
    func_name = provider["func"]
    mod = importlib.import_module(mod_path)
    func = getattr(mod, func_name)
    arguments = provider.get("arguments", {}).copy()

    if configuration or secrets:
        arguments = substitute(arguments, configuration, secrets)

    sig = inspect.signature(func)
    if "secrets" in provider and "secrets" in sig.parameters:
        arguments["secrets"] = {}
        for s in provider["secrets"]:
            arguments["secrets"].update(secrets.get(s, {}).copy())

    if "configuration" in sig.parameters:
        arguments["configuration"] = configuration.copy()

    try:
        return func(**arguments)
    except Exception as x:
        raise FailedActivity(
            traceback.format_exception_only(
                type(x), x)[0].strip()).with_traceback(sys.exc_info()[2])
Example #5
0
def substitute(data: Union[None, str, Dict[str, Any],
                           List], configuration: Configuration,
               secrets: Secrets) -> Dict[str, Any]:
    """
    Replace forms such as `${name}` with the first value found in either the
    `configuration` or `secrets` mappings within the given `data`.
    The original payload is not altered.

    The substitition is done recursively and inside sequences as well.

    The goal is to inject values into the experiment by reading them from
    dynamic values.
    """
    if not data:
        return data

    # secrets is a mapping of mapping, only the second level is useful here
    secrets = secrets.values() if secrets else []

    # let's pretend we have a single mapping of everything with the config
    # by the leader
    mapping = ChainMap(configuration or {}, *secrets)

    if isinstance(data, dict):
        return substitute_dict(data, mapping)

    if isinstance(data, str):
        return substitute_string(data, mapping)

    if isinstance(data, list):
        return substitute_in_sequence(data, mapping)

    return data
def get_all_events(from_time: str, to_time: str, configuration: Configuration,
                   secrets: Secrets) -> InstanaResponse:
    """
     Get all events from instana within a time window, given by the from_time
     and the to_time for details of the api see
     https://instana.github.io/openapi/#tag/Events
    """
    logger.debug("get_all_events")
    instana_host = configuration.get("instana_host")
    instana_api_token = secrets.get("instana_api_token")

    if not (instana_host and instana_api_token):
        raise ActivityFailed(
            "No Instana Host or API Token Secrete were found.")

    url = "{}/api/events".format(configuration.get("instana_host"))

    params = {}
    if from_time:
        params["from"] = from_time

    if to_time:
        params["to"] = to_time

    result = execute_instana_get_request(url, params, secrets)
    return result
def terminate_instance_by_tag(tag_name: str = "not_set",
                              configuration: Configuration = None,
                              secrets: Secrets = None):
    """
    Terminates instance marked with specified tag in aws
    :param tag_name: tag to filter aws instances
    :param configuration: configuration: injected by chaostoolkit framework
    :return: result of modify_attribute call
    """
    retval = None

    ec2 = create_aws_resource(secrets, 'ec2')
    filters_to_set = get_aws_filters_from_configuration(configuration)
    filters_to_set.append({'Name': 'tag:' + tag_name, 'Values': [tag_name]})
    dc = secrets.get("KUBERNETES_CONTEXT", "undefined")
    filters_to_set.append({
        'Name': 'tag:KubernetesCluster',
        'Values': ["{}.k8s.wixprod.net".format(dc)]
    })

    filters_to_set.append({
        'Name': 'instance-state-name',
        'Values': ['running']
    })

    response = ec2.instances.filter(Filters=filters_to_set)
    instances = list(response)
    if len(instances) > 0:
        instance = instances[0]
        logger.warning('Terminate instance {} {}'.format(
            instance.id, instance.private_dns_name))
        retval = instance.terminate()
    else:
        logger.info("No aws instances found with tag {}".format(tag_name))
    return retval
Example #8
0
def vsphere_client(configuration: Configuration = None,
                   secrets: Secrets = None):
    """
    Private function that authorizes against the vSphere API.
    """
    # now setup your connection properties
    host = configuration.get("vsphere_server")
    port = configuration.get("vsphere_port", 443)
    verify_ssl = configuration.get("vsphere_verify_ssl", True)

    if secrets:
        username = secrets.get("vsphere_username")
        password = secrets.get("vsphere_password")
    else:
        username = os.getenv("VSPHERE_USERNAME")
        password = os.getenv("VSPHERE_PASSWORD")

    # now connect to your vCenter/vSphere
    context = None
    if hasattr(ssl, '_create_unverified_context'):
        context = ssl._create_unverified_context()
    connection = SmartConnect(host=host,
                              user=username,
                              pwd=password,
                              port=port,
                              sslContext=context)
    if not connection:
        print("Could not connect to the specified host using specified "
              "username and password")
    return connection
Example #9
0
def apply_python_control(level: str, control: Control, experiment: Experiment,
                         context: Union[Activity, Experiment],
                         state: Union[Journal, Run, List[Run]] = None,
                         configuration: Configuration = None,
                         secrets: Secrets = None):
    """
    Apply a control by calling a function matching the given level.
    """
    provider = control["provider"]
    func_name = _level_mapping.get(level)
    func = load_func(control, func_name)
    if not func:
        return

    arguments = deepcopy(provider.get("arguments", {}))

    if configuration or secrets:
        arguments = substitute(arguments, configuration, secrets)

    sig = inspect.signature(func)
    if "secrets" in provider and "secrets" in sig.parameters:
        arguments["secrets"] = {}
        for s in provider["secrets"]:
            arguments["secrets"].update(secrets.get(s, {}).copy())

    if "configuration" in sig.parameters:
        arguments["configuration"] = configuration.copy()

    if "state" in sig.parameters:
        arguments["state"] = state

    if "experiment" in sig.parameters:
        arguments["experiment"] = experiment

    func(context=context, **arguments)
Example #10
0
def init_resource_graph_client(secrets: Secrets) -> ResourceGraphClient:
    with auth(secrets) as cred:
        base_url = __get_cloud_env_by_name(
            secrets.get("azure_cloud")).endpoints.resource_manager
        client = ResourceGraphClient(credentials=cred, base_url=base_url)

        return client
Example #11
0
def auth(secrets: Secrets) -> ServicePrincipalCredentials:
    """
    Attempt to load the Azure authentication information from a local
    configuration file or the passed `configuration` mapping. The latter takes
    precedence over the local configuration file.

    If you provide a secrets dictionary, the returned mapping will
    be created from their content. For instance, you could have:

    Secrets mapping (in your experiment file):
    ```json
    {
        "azure": {
            "client_id": "AZURE_CLIENT_ID",
            "client_secret": "AZURE_CLIENT_SECRET",
            "tenant_id": "AZURE_TENANT_ID"
        }
    }
    ```

    The client_id, tenant_id, and client_secret content will be read
    from the specified local environment variables, e.g. `AZURE_CLIENT_ID`,
    `AZURE_TENANT_ID`, and `AZURE_CLIENT_SECRET` that you will have populated
    before hand.
    ```

    Using this function goes as follows:

    ```python
    with auth(secrets) as cred:
        azure_subscription_id = configuration['azure']['subscription_id']
        resource_client = ResourceManagementClient(cred, azure_subscription_id)
        compute_client = ComputeManagementClient(cred, azure_subscription_id)
    ```
    """
    creds = dict(azure_client_id=None,
                 azure_client_secret=None,
                 azure_tenant_id=None)

    if secrets:
        creds["azure_client_id"] = secrets.get("client_id")
        creds["azure_client_secret"] = secrets.get("client_secret")
        creds["azure_tenant_id"] = secrets.get("tenant_id")

    credentials = __get_credentials(creds)

    yield credentials
Example #12
0
def get_credentials(secrets: Secrets = None) -> Dict[str, str]:
    """
    Credentialss may be provided via the secrets object. When they aren't,
    they will be loaded from the process environment (for instance, read from
    `~/.aws/credentials`).

    See: https://boto3.readthedocs.io/en/latest/guide/configuration.html#guide-configuration
    """  # noqa: E501
    creds = dict(
        aws_access_key_id=None, aws_secret_access_key=None,
        aws_session_token=None)
    if secrets:
        creds["aws_access_key_id"] = secrets.get("aws_access_key_id")
        creds["aws_secret_access_key"] = secrets.get("aws_secret_access_key")
        creds["aws_session_token"] = secrets.get("aws_session_token")

    return creds
Example #13
0
def connect(secrets: Secrets = None, ):
    load_dotenv()
    if not secrets:
        raise ActivityFailed(
            "Please set the secrets entry to specify the SSH client settings")
    ssh_remote_addr = os.getenv(secrets.get("remote_addr"))

    username = os.getenv(secrets.get("username"))
    pwd = os.getenv(secrets.get("password"))
    port = os.getenv(secrets.get("port"))
    client = SSHClient()
    client.load_system_host_keys()
    if pwd == "":
        client.connect(ssh_remote_addr)
    else :
        client.connect(ssh_remote_addr, username=username, password=pwd, port=port)
    return client
def call_api(path: str,
             configuration: Configuration,
             secrets: Secrets,
             query: Dict[str, Any] = None,
             body: Dict[str, Any] = None,
             method: str = "GET",
             headers: Dict[str, str] = None) -> requests.Response:
    """
    Perform a Cloud Foundry API call and return the full response to the
    caller.
    """
    if "cf_access_token" not in secrets:
        tokens = auth(configuration, secrets)
    else:
        tokens = {
            "token_type": secrets.get("cf_token_type", "bearer"),
            "access_token": secrets.get("cf_access_token")
        }

    h = {
        "Accept":
        "application/json",
        "Authorization":
        "{a} {t}".format(a=tokens["token_type"], t=tokens["access_token"])
    }

    if headers:
        h.update(h)

    verify_ssl = configuration.get("cf_verify_ssl", True)
    url = "{u}{p}".format(u=configuration["cf_api_url"], p=path)
    r = requests.request(method,
                         url,
                         params=query,
                         json=body,
                         verify=verify_ssl,
                         headers=h)

    request_id = r.headers.get("X-VCAP-Request-ID")
    logger.debug("Request ID: {i}".format(i=request_id))

    if r.status_code > 399:
        raise FailedActivity("failed to call '{u}': {c} => {s}".format(
            u=url, c=r.status_code, s=r.text))

    return r
Example #15
0
def aws_client(resource_name: str,
               configuration: Configuration = None,
               secrets: Secrets = None):
    """
    Create a boto3 client.
    """
    configuration = configuration or {}
    region = configuration.get("aws_region", "us-east-1")

    creds = dict(aws_access_key_id=None,
                 aws_secret_access_key=None,
                 aws_session_token=None)
    if secrets:
        creds["aws_access_key_id"] = secrets.get("aws_access_key_id")
        creds["aws_secret_access_key"] = secrets.get("aws_secret_access_key")
        creds["aws_session_token"] = secrets.get("aws_session_token")

    return boto3.client(resource_name, region_name=region, **creds)
Example #16
0
def init_client(secrets: Secrets, configuration: Configuration) \
        -> ComputeManagementClient:
    with auth(secrets) as cred:
        subscription_id = configuration['azure']['subscription_id']
        base_url = __get_cloud_env_by_name(
            secrets.get("azure_cloud")).endpoints.resource_manager
        client = ComputeManagementClient(credentials=cred,
                                         subscription_id=subscription_id,
                                         base_url=base_url)

        return client
Example #17
0
def configure_control(secrets: Secrets):
    """
    Enable logging to Humio if the `token` and `dataspace` are set in the
    `secrets` payload.
    """
    token = secrets.get("humio", {}).get("token", "").strip()
    if not token:
        logger.debug("Missing Humio token secret")
        with_logging.enabled = False
        return

    logger.debug("Humio logging control is active for this session")
    with_logging.enabled = True
Example #18
0
def gandi_client(configuration: Configuration,
                 secrets: Secrets) -> requests.Session:
    secrets = secrets or {}
    api_key = secrets.get("apikey")
    if not api_key:
        raise ActivityFailed(
            "You must provide the Gandi API key in the experiment secrets")

    headers = {
        "accept": "application/json",
        "content-type": "application/json; charset=utf-8",
        "Authorization": "Apikey {}".format(api_key.strip())
    }

    with requests.Session() as session:
        session.headers.update(headers)
        yield session
def get_event(event_id: str, configuration: Configuration,
              secrets: Secrets) -> InstanaResponse:
    """
     Get all an event from instana with the privded event_id for details of
     the api see https://instana.github.io/openapi/#operation/getEvent
    """
    logger.debug("get_event")
    instana_host = configuration.get("instana_host")
    instana_api_token = secrets.get("instana_api_token")

    if not (instana_host and instana_api_token):
        raise ActivityFailed(
            "No Instana Host or API Token Secrete were found.")

    url = "{}/api/events/{}".format(configuration.get("instana_host"),
                                    event_id)

    params = {}

    result = execute_instana_get_request(url, params, secrets)

    return result
def execute_instana_get_request(url: str, params: Dict,
                                secrets: Secrets) -> InstanaResponse:
    """
     Call the instana rest api using the url amd params provided, use an
     Authorization header from the secrets provded
    """
    logger.debug("execute_instana_get_request")
    logger.debug("url is : {}".format(url))
    logger.debug("params : {}".format(params))
    r = requests.get(url=url,
                     params=params,
                     headers={
                         "Authorization":
                         "apiToken {}".format(secrets.get("instana_api_token"))
                     })
    if r.status_code > 399:
        raise ActivityFailed("failed to call '{u}': {c} => {s}".format(
            u=url, c=r.status_code, s=r.text))

    logger.debug("Instana response status code: {}".format(r.status_code))
    logger.debug("Instana json response: {}".format(r.json()))

    return r.json()
Example #21
0
def load_secrets(experiment_secrets: Secrets):
    """Load secrets from experiments or azure credential file.

    :param experiment_secrets: Secrets provided in experiment file
    :returns: a secret object

    Load secrets from multiple sources that can contain different format
    such as azure credential file or experiment secrets section.
    The latter takes precedence over azure credential file.

    Function returns following dictionary object:
    ```python
    {
        # always available
        "cloud": "variable contains msrest cloud object"

        # optional - available if user authenticate with service principal
        "client_id": "variable contains client id",
        "client_secret": "variable contains client secret",
        "tenant_id": "variable contains tenant id",

        # optional - available if user authenticate with existing token
        "access_token": "variable contains access token",
    }
    ```

    :Loading secrets from experiment file:

    Function will try to load following secrets from the experiment file:
    ```json
    {
        "azure": {
            "client_id": "AZURE_CLIENT_ID",
            "client_secret": "AZURE_CLIENT_SECRET",
            "tenant_id": "AZURE_TENANT_ID",
            "access_token": "AZURE_ACCESS_TOKEN"
        }
    }
    ```

    :Loading secrets from azure credential file:

    If experiment file contains no secrets, function will try to load secrets
    from the azure credential file. Path to the file should be set under
    AZURE_AUTH_LOCATION environment variable.

    Function will try to load following secrets from azure credential file:
    ```json
    {
        "clientId": "AZURE_CLIENT_ID",
        "clientSecret": "AZURE_CLIENT_SECRET",
        "tenantId": "AZURE_TENANT_ID",
        "resourceManagerEndpointUrl": "AZURE_RESOURCE_MANAGER_ENDPOINT",
        ...
    }
    ```
    More info about azure credential file may be found:
    https://docs.microsoft.com/en-us/azure/developer/python/azure-sdk-authenticate

    """

    # 1: lookup for secrets in experiment  file
    if experiment_secrets:
        return {
            'client_id': experiment_secrets.get('client_id'),
            'client_secret': experiment_secrets.get('client_secret'),
            'tenant_id': experiment_secrets.get('tenant_id'),
            # load cloud object
            'cloud': cloud.get_or_raise(experiment_secrets.get('azure_cloud')),
            'access_token': experiment_secrets.get('access_token'),
        }

    # 2: lookup for credentials in azure auth file
    az_auth_file = _load_azure_auth_file()
    if az_auth_file:
        rm_endpoint = az_auth_file.get('resourceManagerEndpointUrl')
        return {
            'client_id': az_auth_file.get('clientId'),
            'client_secret': az_auth_file.get('clientSecret'),
            'tenant_id': az_auth_file.get('tenantId'),
            # load cloud object
            'cloud': azure_cloud.get_cloud_from_metadata_endpoint(rm_endpoint),
            # access token is not supported for credential files
            'access_token': None,
        }

    # no secretes
    logger.warn("Unable to load Azure credentials.")
    return {}
Example #22
0
def auth(secrets: Secrets) -> ServicePrincipalCredentials:
    """
    Attempt to load the Azure authentication information from a local
    configuration file or the passed `configuration` mapping. The latter takes
    precedence over the local configuration file. Service principle and token
    based credentials are supported. Token based credentials do not currently
    support refresh token functionality.

    If you provide a secrets dictionary, the returned mapping will
    be created from their content. For instance, for service principle based
    credentials, you could have:

    Secrets mapping (in your experiment file):
    ```json
    {
        "azure": {
            "client_id": "AZURE_CLIENT_ID",
            "client_secret": "AZURE_CLIENT_SECRET",
            "tenant_id": "AZURE_TENANT_ID"
        }
    }
    ```
    Also if you are not working with Public Global Azure, e.g. China Cloud
    You can feed the cloud environment name as well.
    Please refer to msrestazure.azure_cloud
    ```json
    {
        "azure": {
            "client_id": "xxxxxxx",
            "client_secret": "*******",
            "tenant_id": "@@@@@@@@@@@",
            "azure_cloud": "AZURE_CHINA_CLOUD"
        }
    }
    ```

    The client_id, tenant_id, and client_secret content will be read
    from the specified local environment variables, e.g. `AZURE_CLIENT_ID`,
    `AZURE_TENANT_ID`, and `AZURE_CLIENT_SECRET` that you will have populated
    before hand.

    If the client_secret is not provided, then token based credentials is
    assumed and an access_token value must be present and updated as the token
    expires.
    ```

    Using this function goes as follows:

    ```python
    with auth(secrets) as cred:
        azure_subscription_id = configuration['azure']['subscription_id']
        resource_client = ResourceManagementClient(cred, azure_subscription_id)
        compute_client = ComputeManagementClient(cred, azure_subscription_id)
    ```

    Again, if you are not working with Public Azure Cloud,
    and you set azure_cloud in secret,
    this will pass one more parameter `base_url` to above function.
    ```python
        cloud = __get_cloud_env_by_name(creds['azure_cloud'])
        client = ComputeManagementClient(
            credentials=cred, subscription_id=subscription_id,
                        base_url=cloud.endpoints.resource_manager)
    ```

    """
    creds = dict(azure_client_id=None,
                 azure_client_secret=None,
                 azure_tenant_id=None,
                 azure_cloud=None,
                 access_token=None)

    if secrets:
        creds["azure_client_id"] = secrets.get("client_id")
        creds["azure_client_secret"] = secrets.get("client_secret")
        creds["azure_tenant_id"] = secrets.get("tenant_id")
        creds["azure_cloud"] = secrets.get("azure_cloud", "AZURE_PUBLIC_CLOUD")
        creds["access_token"] = secrets.get("access_token")

    credentials = __get_credentials(creds)

    yield credentials
def client(service_name: str,
           version: str = 'v1',
           secrets: Secrets = None) -> Resource:
    """
    Create a client for the given service. 

    To authenticate, you need to create a service account manually and either
    pass the filename or the content of the file into the `secrets` object.

    So, in the experiment, use one of the followings:

    ```json
    {
        "gce": {
            "service_account_file": "/path/to/file.json"
        }
    }
    ```

    ```json
    {
        "gce": {
            "service_account_info": {
                "type": "service_account",
                "project_id": "...",
                "private_key_id": "...",
                "private_key": "...",
                "client_email": "...",
                "client_id": "...",
                "auth_uri": "https://accounts.google.com/o/oauth2/auth",
                "token_uri": "https://accounts.google.com/o/oauth2/token",
                "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
                "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/...."
            }
        }
    }
    ```

    You would likely want to read value from the environment or Vault if you
    use the second approach, and avoid storing sensitive data into the
    experiment itself.

    Make sure your service account has enough permissions for the activities
    you wish to conduct (though do not give it too wide permissions either).

    See: https://developers.google.com/api-client-library/python/auth/service-accounts
    Also: http://google-auth.readthedocs.io/en/latest/reference/google.oauth2.service_account.html
    """  # noqa: E501
    secrets = secrets or {}
    service_account_file = secrets.get("service_account_file")
    service_account_info = secrets.get("service_account_info")

    credentials = None
    if service_account_file:
        service_account_file = os.path.expanduser(service_account_file)
        if not os.path.exists(service_account_file):
            raise FailedActivity("GCE account settings not found at {}".format(
                service_account_file))

        logger.debug(
            "Using GCE credentials from file: {}".format(service_account_file))
        credentials = Credentials.from_service_account_file(
            service_account_file)
    elif service_account_info and isinstance(service_account_info, dict):
        logger.debug("Using GCE credentials embedded into secrets")
        credentials = Credentials.from_service_account_info(
            service_account_info)
    else:
        raise FailedActivity(
            "missing GCE credentials settings in secrets of this activity")

    if credentials is not None and credentials.expired:
        logger.debug("GCE credentials need to be refreshed as they expired")
        credentials.refresh(httplib2.Http())

    if not credentials:
        raise FailedActivity(
            "missing a service account to authenticate with the "
            "Google Cloud Services")

    return build(service_name, version=version, credentials=credentials)
Example #24
0
def get_client(secrets: Secrets) -> WebClient:
    slack_token = secrets.get("slack", {}).get("token")
    client = WebClient(token=slack_token)
    return client