def create_tls_artifacts(cn: str, marathon_task: str) -> str:
    pub_path = "{}_pub.crt".format(cn)
    priv_path = "{}_priv.key".format(cn)
    log.info("Generating certificate. cn={}, task={}".format(cn, marathon_task))

    output = sdk_cmd.marathon_task_exec(
        marathon_task,
        "openssl req -nodes -newkey rsa:2048 -keyout {} -out request.csr "
        '-subj "/C=US/ST=CA/L=SF/O=Mesosphere/OU=Mesosphere/CN={}"'.format(priv_path, cn),
    )
    assert output[0] == 0

    rc, raw_csr, _ = sdk_cmd.marathon_task_exec(marathon_task, "cat request.csr")
    assert rc == 0
    request = {"certificate_request": raw_csr}

    output = sdk_cmd.marathon_task_exec(
        marathon_task,
        "curl --insecure -L -X POST "
        "-H 'Authorization: token={}' "
        "leader.mesos/ca/api/v2/sign "
        "-d '{}'".format(sdk_utils.dcos_token(), json.dumps(request)),
    )
    assert output[0] == 0

    # Write the public cert to the client
    certificate = json.loads(output[1])["result"]["certificate"]
    output = sdk_cmd.marathon_task_exec(
        marathon_task, "bash -c \"echo '{}' > {}\"".format(certificate, pub_path)
    )
    assert output[0] == 0

    _create_keystore_truststore(cn, marathon_task)
    return "CN={},OU=Mesosphere,O=Mesosphere,L=SF,ST=CA,C=US".format(cn)
Exemplo n.º 2
0
def _retried_run_janitor(service_name):
    cmd_list = [
        "docker",
        "run",
        "mesosphere/janitor",
        "/janitor.py",
        "-r",
        sdk_utils.get_role(service_name),
        "-p",
        service_name + "-principal",
        "-z",
        sdk_utils.get_zk_path(service_name),
        "--auth_token={}".format(sdk_utils.dcos_token()),
    ]
    rc, _, _ = sdk_cmd.master_ssh(" ".join(cmd_list))
    assert rc == 0, "Janitor command failed"
def create_tls_artifacts(cn: str, marathon_task: str) -> str:
    pub_path = "{}_pub.crt".format(cn)
    priv_path = "{}_priv.key".format(cn)
    log.info("Generating certificate. cn={}, task={}".format(
        cn, marathon_task))

    output = sdk_cmd.marathon_task_exec(
        marathon_task,
        "openssl req -nodes -newkey rsa:2048 -keyout {} -out request.csr "
        '-subj "/C=US/ST=CA/L=SF/O=Mesosphere/OU=Mesosphere/CN={}"'.format(
            priv_path, cn),
    )
    assert output[0] == 0

    rc, raw_csr, _ = sdk_cmd.marathon_task_exec(marathon_task,
                                                "cat request.csr")
    assert rc == 0
    request = {"certificate_request": raw_csr}

    output = sdk_cmd.marathon_task_exec(
        marathon_task,
        "curl --insecure -L -X POST "
        "-H 'Authorization: token={}' "
        "leader.mesos/ca/api/v2/sign "
        "-d '{}'".format(sdk_utils.dcos_token(), json.dumps(request)),
    )
    assert output[0] == 0

    # Write the public cert to the client
    certificate = json.loads(output[1])["result"]["certificate"]
    output = sdk_cmd.marathon_task_exec(
        marathon_task,
        "bash -c \"echo '{}' > {}\"".format(certificate, pub_path))
    assert output[0] == 0

    _create_keystore_truststore(cn, marathon_task)
    return "CN={},OU=Mesosphere,O=Mesosphere,L=SF,ST=CA,C=US".format(cn)
Exemplo n.º 4
0
def check_kibana_adminrouter_integration(path: str) -> bool:
    curl_cmd = 'curl -L -I -k -H "Authorization: token={}" -s -X GET {}/{}'.format(
        sdk_utils.dcos_token(),
        sdk_utils.dcos_url().rstrip("/"), path.lstrip("/"))
    rc, stdout, _ = sdk_cmd.master_ssh(curl_cmd)
    return bool(rc == 0 and stdout and "HTTP/1.1 200" in stdout)
Exemplo n.º 5
0
def check_kibana_adminrouter_integration(path: str) -> bool:
    curl_cmd = 'curl -L -I -k -H "Authorization: token={}" -s {}/{}'.format(
        sdk_utils.dcos_token(), sdk_utils.dcos_url().rstrip("/"), path.lstrip("/")
    )
    rc, stdout, _ = sdk_cmd.master_ssh(curl_cmd)
    return bool(rc == 0 and stdout and "HTTP/1.1 200" in stdout)
Exemplo n.º 6
0
def cluster_request(
    method: str,
    cluster_path: str,
    retry: bool = True,
    raise_on_error: bool = True,
    log_args: bool = True,
    log_response: bool = False,
    timeout_seconds: int = 60,
    **kwargs: Any,
) -> requests.Response:
    """Queries the provided cluster HTTP path using the provided method, with the following handy features:
    - The DCOS cluster's URL is automatically applied to the provided path.
    - Auth headers are automatically added.
    - If the response code is >= 400, optionally retries and / or raises a `requests.exceptions.HTTPError`.

    : param method: Method to use for the query, such as `GET`, `POST`, `DELETE`, or `PUT`.
    : param cluster_path: HTTP path to be queried on the cluster, e.g. `/ marathon / v2 / apps`. Leading slash is optional.
    : param retry: Whether to retry the request automatically if an HTTP error (>= 400) is returned.
    : param raise_on_error: Whether to raise a `requests.exceptions.HTTPError` if the response code is >= 400.
                           Disabling this effectively implies `retry = False` where HTTP status is concerned.
    : param log_args: Whether to log the contents of `kwargs`. Can be disabled to reduce noise.
    : param log_response: Whether to always log the response content.
                          Otherwise responses are only logged if the response code is >= 400.
    : param kwargs: Additional arguments to requests.request(), such as `json = {"example": "content"}`
                   or `params = {"example": "param"}`.
    : rtype: requests.Response
    """

    url = urllib.parse.urljoin(sdk_utils.dcos_url(), cluster_path)
    # consistently include slash prefix for clearer logging below
    cluster_path = "/" + cluster_path.lstrip("/")

    # Wrap token in callback for requests library to invoke:
    class AuthHeader(requests.auth.AuthBase):
        def __init__(self, token: str) -> None:
            self._token = token

        def __call__(self, r: requests.Request) -> requests.Request:
            r.headers["Authorization"] = "token={}".format(self._token)
            return r

    auth = AuthHeader(sdk_utils.dcos_token())

    def _cluster_request() -> requests.Response:
        start = time.time()

        # check if we have verify key already exists.
        if kwargs is not None and kwargs.get("verify") is not None:
            kwargs["verify"] = False
            response = requests.request(method, url, auth=auth, timeout=timeout_seconds, **kwargs)
        else:
            response = requests.request(
                method, url, auth=auth, verify=False, timeout=timeout_seconds, **kwargs
            )

        end = time.time()

        log_msg = "(HTTP {}) {}".format(method.upper(), cluster_path)
        if kwargs:
            # log arg content (or just arg names, with hack to avoid 'dict_keys([...])') if present
            log_msg += " (args: {})".format(kwargs if log_args else [e for e in kwargs.keys()])
        log_msg += " => {} ({})".format(
            response.status_code, sdk_utils.pretty_duration(end - start)
        )
        log.info(log_msg)

        if log_response or not response.ok:
            # Response logging enabled, or query failed (>= 400). Before (potentially) throwing,
            # print response payload which may include additional error details.
            response_text = response.text
            if response_text:
                log.info(
                    "Response content ({} bytes):\n{}".format(len(response_text), response_text)
                )
            else:
                log.info("No response content")
        if raise_on_error:
            response.raise_for_status()
        return response

    if retry:
        # Use wrapper to implement retry:
        @retrying.retry(wait_fixed=1000, stop_max_delay=timeout_seconds * 1000)
        def retry_fn() -> requests.Response:
            return _cluster_request()

        response = retry_fn()
        assert isinstance(response, requests.Response)
        return response
    else:
        # No retry, invoke directly:
        return _cluster_request()
Exemplo n.º 7
0
def cluster_request(
    method: str,
    cluster_path: str,
    retry: bool = True,
    raise_on_error: bool = True,
    log_args: bool = True,
    log_response: bool = False,
    timeout_seconds: int = 60,
    **kwargs: Any,
) -> requests.Response:
    """Queries the provided cluster HTTP path using the provided method, with the following handy features:
    - The DCOS cluster's URL is automatically applied to the provided path.
    - Auth headers are automatically added.
    - If the response code is >= 400, optionally retries and / or raises a `requests.exceptions.HTTPError`.

    : param method: Method to use for the query, such as `GET`, `POST`, `DELETE`, or `PUT`.
    : param cluster_path: HTTP path to be queried on the cluster, e.g. `/ marathon / v2 / apps`. Leading slash is optional.
    : param retry: Whether to retry the request automatically if an HTTP error (>= 400) is returned.
    : param raise_on_error: Whether to raise a `requests.exceptions.HTTPError` if the response code is >= 400.
                           Disabling this effectively implies `retry = False` where HTTP status is concerned.
    : param log_args: Whether to log the contents of `kwargs`. Can be disabled to reduce noise.
    : param log_response: Whether to always log the response content.
                          Otherwise responses are only logged if the response code is >= 400.
    : param kwargs: Additional arguments to requests.request(), such as `json = {"example": "content"}`
                   or `params = {"example": "param"}`.
    : rtype: requests.Response
    """

    url = urllib.parse.urljoin(sdk_utils.dcos_url(), cluster_path)
    # consistently include slash prefix for clearer logging below
    cluster_path = "/" + cluster_path.lstrip("/")

    # Wrap token in callback for requests library to invoke:
    class AuthHeader(requests.auth.AuthBase):
        def __init__(self, token: str) -> None:
            self._token = token

        def __call__(self, r: requests.Request) -> requests.Request:
            r.headers["Authorization"] = "token={}".format(self._token)
            return r

    auth = AuthHeader(sdk_utils.dcos_token())

    def _cluster_request() -> requests.Response:
        start = time.time()

        # check if we have verify key already exists.
        if kwargs is not None and kwargs.get("verify") is not None:
            kwargs["verify"] = False
            response = requests.request(method,
                                        url,
                                        auth=auth,
                                        timeout=timeout_seconds,
                                        **kwargs)
        else:
            response = requests.request(method,
                                        url,
                                        auth=auth,
                                        verify=False,
                                        timeout=timeout_seconds,
                                        **kwargs)

        end = time.time()

        log_msg = "(HTTP {}) {}".format(method.upper(), cluster_path)
        if kwargs:
            # log arg content (or just arg names, with hack to avoid 'dict_keys([...])') if present
            log_msg += " (args: {})".format(
                kwargs if log_args else [e for e in kwargs.keys()])
        log_msg += " => {} ({})".format(response.status_code,
                                        sdk_utils.pretty_duration(end - start))
        log.info(log_msg)

        if log_response or not response.ok:
            # Response logging enabled, or query failed (>= 400). Before (potentially) throwing,
            # print response payload which may include additional error details.
            response_text = response.text
            if response_text:
                log.info("Response content ({} bytes):\n{}".format(
                    len(response_text), response_text))
            else:
                log.info("No response content")
        if raise_on_error:
            response.raise_for_status()
        return response

    if retry:
        # Use wrapper to implement retry:
        @retrying.retry(wait_fixed=1000, stop_max_delay=timeout_seconds * 1000)
        def retry_fn() -> requests.Response:
            return _cluster_request()

        response = retry_fn()
        assert isinstance(response, requests.Response)
        return response
    else:
        # No retry, invoke directly:
        return _cluster_request()