Esempio n. 1
0
def get_aad_token(endpoint, no_verify):
    #pylint: disable-msg=too-many-locals
    """Get AAD token"""
    from azure.servicefabric.service_fabric_client_ap_is import (
        ServiceFabricClientAPIs)
    from sfctl.auth import ClientCertAuthentication
    from sfctl.config import set_aad_metadata

    auth = ClientCertAuthentication(None, None, no_verify)

    client = ServiceFabricClientAPIs(auth, base_url=endpoint)
    aad_metadata = client.get_aad_metadata()

    if aad_metadata.type != "aad":
        raise CLIError("Not AAD cluster")

    aad_resource = aad_metadata.metadata

    tenant_id = aad_resource.tenant
    authority_uri = aad_resource.login + '/' + tenant_id
    context = adal.AuthenticationContext(authority_uri, api_version=None)
    cluster_id = aad_resource.cluster
    client_id = aad_resource.client

    set_aad_metadata(authority_uri, cluster_id, client_id)

    code = context.acquire_user_code(cluster_id, client_id)
    print(code['message'])
    token = context.acquire_token_with_device_code(cluster_id, code, client_id)
    print("Succeed!")
    return token, context.cache
Esempio n. 2
0
def create(_):
    """Create a client for Service Fabric APIs."""

    endpoint = client_endpoint()

    if not endpoint:
        raise CLIError(
            'Connection endpoint not found. '
            'Before running sfctl commands, connect to a cluster using '
            'the "sfctl cluster select" command. '
            'If you are seeing this message on Linux after already selecting a cluster, '
            'you may need to run the command with sudo.')

    no_verify = no_verify_setting()

    if security_type() == 'aad':
        auth = AdalAuthentication(no_verify)
    else:
        cert = cert_info()
        ca_cert = ca_cert_info()
        auth = ClientCertAuthentication(cert, ca_cert, no_verify)

    client = ServiceFabricClientAPIs(auth, base_url=endpoint)

    # client.config.retry_policy has type msrest.pipeline.ClientRetryPolicy
    client.config.retry_policy.total = False
    client.config.retry_policy.policy.total = False

    # msrest defines ClientRetryPolicy in pipline.py.
    # ClientRetryPolicy.__init__ defines values for status_forcelist
    # which is passed to urllib3.util.retry.Retry
    client.config.retry_policy.policy.status_forcelist = None

    return client
class Cluster(object):

    _fabric_client = None
    _namespace = '{http://schemas.microsoft.com/2011/01/fabric}'
    _url = None
    
    def __init__(self, credentials, url):
        self._url = url
        self._fabric_client = ServiceFabricClientAPIs(credentials, url)
        
    @staticmethod
    def from_sfclient(sfclient):
        credentials = sfclient.config.credentials
        url = sfclient.config.base_url
        return Cluster(credentials, url)

    def get_applications(self):
        applications = []
        
        continuation_token = None
        while True:
            paged_application_info_list = self._fabric_client.get_application_info_list(0, None, False, continuation_token)
            for application_info in paged_application_info_list.items:
                applications.append(Application(self, application_info.id))
            if paged_application_info_list.continuation_token == '':
                break
            else: 
                continuation_token = paged_application_info_list.continuation_token
        return applications

    def get_application(self, name):
        applications = self.get_applications()
        for application in applications:
            if application.name == name:
                return application
        raise ValueError("Could not find application with name: {}".format(name))
    
    def _get_httpapplicationgatewayendpoint(self):
        manifestxml = et.fromstring(self.get_manifest().manifest)
        endpoints = manifestxml.find(
            './/' + self._namespace + "HttpApplicationGatewayEndpoint")
        return endpoints.get("Port")
    
    def get_manifest(self):
        return self._fabric_client.get_cluster_manifest()
Esempio n. 4
0
def create(_):
    """Create a client for Service Fabric APIs."""

    endpoint = client_endpoint()

    if not endpoint:
        raise CLIError("Connection endpoint not found")

    no_verify = no_verify_setting()

    if security_type() == 'aad':
        auth = AdalAuthentication(no_verify)
    else:
        cert = cert_info()
        ca_cert = ca_cert_info()
        auth = ClientCertAuthentication(cert, ca_cert, no_verify)

    return ServiceFabricClientAPIs(auth, base_url=endpoint)
Esempio n. 5
0
def create(_):
    """Create a client for Service Fabric APIs."""

    endpoint = client_endpoint()

    if not endpoint:
        raise CLIError(
            "Connection endpoint not found. "
            "Before running sfctl commands, connect to a cluster using "
            "the 'sfctl cluster select' command.")

    no_verify = no_verify_setting()

    if security_type() == 'aad':
        auth = AdalAuthentication(no_verify)
    else:
        cert = cert_info()
        ca_cert = ca_cert_info()
        auth = ClientCertAuthentication(cert, ca_cert, no_verify)

    return ServiceFabricClientAPIs(auth, base_url=endpoint)
 def __init__(self, credentials, url):
     self._url = url
     self._fabric_client = ServiceFabricClientAPIs(credentials, url)
Esempio n. 7
0
def check_cluster_version(on_failure_or_connection,
                          dummy_cluster_version=None):
    """ Check that the cluster version of sfctl is compatible with that of the cluster.

    Failures in making the API call (to check the cluster version)
    will be ignored and the time tracker will be reset to the current time.
    This is because we have no way of knowing if the
    API call failed because it doesn't exist on the cluster, or because of some other reason.
    We set the time tracker to the current time to avoid calling the API continuously
    for clusters without this API.

    Rather than each individual component deciding when to call this function, this should
    be called any time this might need to be triggered, and logic within this function will
    judge if a call to the cluster is required.

    :param on_failure_or_connection: True if this function is called due to an API call failure,
        or because it was called on connection to a new cluster endpoint.
        False otherwise.
    :type on_failure_or_connection: bool

    :param dummy_cluster_version: Used for testing purposes only. This is passed
        in to replace a call to the service fabric cluster to get the cluster version, in order to
        keep tests local.
        By default this value is None. If you would like to simulate the cluster call returning
        None, then enter 'NoResult' as a string
    :type dummy_cluster_version: str

    :returns: True if versions match, or if the check is not performed. False otherwise.
    """

    from sfctl.state import get_cluster_version_check_time, set_cluster_version_check_time
    from warnings import warn

    # Before doing anything, see if a check needs to be triggered.
    # Always trigger version check if on failure or connection
    if not on_failure_or_connection:

        # Check if sufficient time has passed since last check
        last_check_time = get_cluster_version_check_time()
        if last_check_time is not None:
            # If we've already checked the cluster version before, see how long ago it has been
            time_since_last_check = datetime.utcnow() - last_check_time
            allowable_time = timedelta(hours=SF_CLI_VERSION_CHECK_INTERVAL)
            if allowable_time > time_since_last_check:
                # Don't perform any checks
                return True
        else:
            # If last_check_time is None, this means that we've not yet set a time, so it's never
            # been checked. Set the initial value.
            set_cluster_version_check_time()

    cluster_auth = get_cluster_auth()

    auth = _get_client_cert_auth(cluster_auth['pem'], cluster_auth['cert'],
                                 cluster_auth['key'], cluster_auth['ca'],
                                 cluster_auth['no_verify'])

    client = ServiceFabricClientAPIs(auth, base_url=client_endpoint())

    sfctl_version = get_sfctl_version()

    # Update the timestamp of the last cluster version check
    set_cluster_version_check_time()

    if dummy_cluster_version is None:
        # This command may fail for various reasons. Most common reason as of writing this comment
        # is that the corresponding get_cluster_version API on the cluster doesn't exist.
        try:
            logger.info('Performing cluster version check')
            cluster_version = client.get_cluster_version().version

        except:  # pylint: disable=bare-except
            ex = exc_info()[0]
            logger.info('Check cluster version failed due to error: %s',
                        str(ex))
            return True
    else:
        if dummy_cluster_version == 'NoResult':
            cluster_version = None
        else:
            cluster_version = dummy_cluster_version

    if cluster_version is None:
        # Do no checks if the get cluster version API fails, since most likely it failed
        # because the API doesn't exist.
        return True

    if not sfctl_cluster_version_matches(cluster_version, sfctl_version):
        warn(
            str.format(
                'sfctl has version "{0}" which does not match the cluster version "{1}". '
                'See https://docs.microsoft.com/azure/service-fabric/service-fabric-cli#service-fabric-target-runtime '  # pylint: disable=line-too-long
                'for version compatibility. Upgrade to a compatible version for the best experience.',
                sfctl_version,
                cluster_version))
        return False

    return True