<commit_before>########
# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#        http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
############


import os
import json
import types
import shutil
import pkgutil
import getpass
import tempfile
import itertools
from base64 import urlsafe_b64encode

import yaml
import requests

from cloudify_rest_client.utils import is_kerberos_env
from cloudify_rest_client import CloudifyClient
from cloudify_rest_client.client import HTTPClient
from cloudify_rest_client.exceptions import (CloudifyClientError,
                                             RemovedFromCluster,
                                             NotClusterMaster)
from . import constants
from .exceptions import CloudifyCliError

_ENV_NAME = 'manager'
DEFAULT_LOG_FILE = os.path.expanduser(
    '{0}/cloudify-{1}/cloudify-cli.log'.format(
        tempfile.gettempdir(), getpass.getuser()))

CLOUDIFY_WORKDIR = os.path.join(
    os.environ.get('CFY_WORKDIR', os.path.expanduser('~')),
    constants.CLOUDIFY_BASE_DIRECTORY_NAME)
PROFILES_DIR = os.path.join(CLOUDIFY_WORKDIR, 'profiles')
ACTIVE_PRO_FILE = os.path.join(CLOUDIFY_WORKDIR, 'active.profile')
MULTIPLE_LOCAL_BLUEPRINTS = (
    os.environ.get('CFY_MULTIPLE_BLUEPRINTS', 'true') == 'true')
CLUSTER_RETRY_INTERVAL = 5


def delete_profile(profile_name):
    if is_profile_exists(profile_name):
        profile_dir = get_profile_dir(profile_name)
        shutil.rmtree(profile_dir)
    else:
        raise CloudifyCliError(
            'Profile {0} does not exist'.format(profile_name))


def is_profile_exists(profile_name):
    try:
        return os.path.isfile(get_context_path(profile_name))
    except CloudifyCliError:
        return False


def assert_profile_exists(profile_name):
    if not is_profile_exists(profile_name):
        raise CloudifyCliError(
            'Profile {0} does not exist. You can run `cfy init {0}` to '
            'create the profile.'.format(profile_name))


def set_active_profile(profile_name):
    global profile
    with open(ACTIVE_PRO_FILE, 'w+') as active_profile:
        active_profile.write(profile_name)
    profile = get_profile_context(profile_name, suppress_error=True)


def get_active_profile():
    if os.path.isfile(ACTIVE_PRO_FILE):
        with open(ACTIVE_PRO_FILE) as active_profile:
            return active_profile.read().strip()
    else:
        # We return None explicitly as no profile is active.
        return None


def get_profile_names():
    # TODO: This is too.. ambiguous. We should change it so there are
    # no exclusions.
    excluded = ['local']
    profile_names = [item for item in os.listdir(PROFILES_DIR)
                     if item not in excluded and not item.startswith('.')]

    return profile_names


def assert_manager_active():
    if not is_manager_active():
        raise CloudifyCliError(
            'This command is only available when using a manager. '
            'Please use the `cfy profiles use` command to connect '
            'to a Cloudify Manager.')


def assert_local_active():
    if is_manager_active():
        raise CloudifyCliError(
            'This command is not available when using a manager. '
            'You can run `cfy profiles use local` to stop using a manager.')


def assert_credentials_set():
    error_msg = 'Manager {0} must be set in order to use a manager.\n' \
                'You can set it in the profile by running ' \
                '`cfy profiles set {1}`, or you can set the `CLOUDIFY_{2}` ' \
                'environment variable.'
    if not get_username():
        raise CloudifyCliError(
            error_msg.format('Username', '--manager-username', 'USERNAME')
        )
    if not get_password():
        raise CloudifyCliError(
            error_msg.format('Password', '--manager-password', 'PASSWORD')
        )
    if not get_tenant_name():
        raise CloudifyCliError(
            error_msg.format('Tenant', '--manager-tenant', 'TENANT')
        )


def is_manager_active():
    active_profile = get_active_profile()
    if not active_profile:
        return False

    if active_profile == 'local':
        return False

    p = get_profile_context(active_profile, suppress_error=True)
    if not (p and p.manager_ip):
        return False
    return True


def get_profile_context(profile_name=None, suppress_error=False):
    profile_name = profile_name or get_active_profile()
    if profile_name == 'local':
        if suppress_error:
            return ProfileContext()
        raise CloudifyCliError('Local profile does not have context')
    try:
        path = get_context_path(profile_name)
        with open(path) as f:
            return yaml.load(f.read())
    except CloudifyCliError:
        if suppress_error:
            return ProfileContext()
        raise


def is_initialized(profile_name=None):
    """Check if a profile or an environment is initialized.

    If profile_name is provided, it will check if the profile
    is initialized. If not, it will just check that workenv is.
    """
    if profile_name:
        return get_profile_dir(profile_name) is not None
    else:
        return os.path.isfile(os.path.join(CLOUDIFY_WORKDIR, 'config.yaml'))


def get_context_path(profile_name, suppress_error=False):
    base_dir = get_profile_dir(profile_name, suppress_error)
    if not base_dir:
        return
    return os.path.join(<commit_msg>CY-597 use default values for missing attributes in profile context<commit_after>########
# Copyright (c) 2014 GigaSpaces Technologies Ltd. All rights reserved
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#        http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
############


import os
import json
import types
import shutil
import pkgutil
import getpass
import tempfile
import itertools
from base64 import urlsafe_b64encode

import yaml
import requests

from cloudify_rest_client.utils import is_kerberos_env
from cloudify_rest_client import CloudifyClient
from cloudify_rest_client.client import HTTPClient
from cloudify_rest_client.exceptions import (CloudifyClientError,
                                             RemovedFromCluster,
                                             NotClusterMaster)
from . import constants
from .exceptions import CloudifyCliError

_ENV_NAME = 'manager'
DEFAULT_LOG_FILE = os.path.expanduser(
    '{0}/cloudify-{1}/cloudify-cli.log'.format(
        tempfile.gettempdir(), getpass.getuser()))

CLOUDIFY_WORKDIR = os.path.join(
    os.environ.get('CFY_WORKDIR', os.path.expanduser('~')),
    constants.CLOUDIFY_BASE_DIRECTORY_NAME)
PROFILES_DIR = os.path.join(CLOUDIFY_WORKDIR, 'profiles')
ACTIVE_PRO_FILE = os.path.join(CLOUDIFY_WORKDIR, 'active.profile')
MULTIPLE_LOCAL_BLUEPRINTS = (
    os.environ.get('CFY_MULTIPLE_BLUEPRINTS', 'true') == 'true')
CLUSTER_RETRY_INTERVAL = 5


def delete_profile(profile_name):
    if is_profile_exists(profile_name):
        profile_dir = get_profile_dir(profile_name)
        shutil.rmtree(profile_dir)
    else:
        raise CloudifyCliError(
            'Profile {0} does not exist'.format(profile_name))


def is_profile_exists(profile_name):
    try:
        return os.path.isfile(get_context_path(profile_name))
    except CloudifyCliError:
        return False


def assert_profile_exists(profile_name):
    if not is_profile_exists(profile_name):
        raise CloudifyCliError(
            'Profile {0} does not exist. You can run `cfy init {0}` to '
            'create the profile.'.format(profile_name))


def set_active_profile(profile_name):
    global profile
    with open(ACTIVE_PRO_FILE, 'w+') as active_profile:
        active_profile.write(profile_name)
    profile = get_profile_context(profile_name, suppress_error=True)


def get_active_profile():
    if os.path.isfile(ACTIVE_PRO_FILE):
        with open(ACTIVE_PRO_FILE) as active_profile:
            return active_profile.read().strip()
    else:
        # We return None explicitly as no profile is active.
        return None


def get_profile_names():
    # TODO: This is too.. ambiguous. We should change it so there are
    # no exclusions.
    excluded = ['local']
    profile_names = [item for item in os.listdir(PROFILES_DIR)
                     if item not in excluded and not item.startswith('.')]

    return profile_names


def assert_manager_active():
    if not is_manager_active():
        raise CloudifyCliError(
            'This command is only available when using a manager. '
            'Please use the `cfy profiles use` command to connect '
            'to a Cloudify Manager.')


def assert_local_active():
    if is_manager_active():
        raise CloudifyCliError(
            'This command is not available when using a manager. '
            'You can run `cfy profiles use local` to stop using a manager.')


def assert_credentials_set():
    error_msg = 'Manager {0} must be set in order to use a manager.\n' \
                'You can set it in the profile by running ' \
                '`cfy profiles set {1}`, or you can set the `CLOUDIFY_{2}` ' \
                'environment variable.'
    if not get_username():
        raise CloudifyCliError(
            error_msg.format('Username', '--manager-username', 'USERNAME')
        )
    if not get_password():
        raise CloudifyCliError(
            error_msg.format('Password', '--manager-password', 'PASSWORD')
        )
    if not get_tenant_name():
        raise CloudifyCliError(
            error_msg.format('Tenant', '--manager-tenant', 'TENANT')
        )


def is_manager_active():
    active_profile = get_active_profile()
    if not active_profile:
        return False

    if active_profile == 'local':
        return False

    p = get_profile_context(active_profile, suppress_error=True)
    if not (p and p.manager_ip):
        return False
    return True


def get_profile_context(profile_name=None, suppress_error=False):
    # empty profile with nothing but default values
    default = ProfileContext()
    profile_name = profile_name or get_active_profile()
    if profile_name == 'local':
        if suppress_error:
            return default
        raise CloudifyCliError('Local profile does not have context')
    try:
        path = get_context_path(profile_name)
        with open(path) as f:
            context = yaml.load(f.read())
        # fill the default with values from existing profile (the default is
        # used as base because some of the attributes may not be in the
        # existing profile file)
        for key, value in context.__dict__.items():
            setattr(default, key, value)
    except CloudifyCliError:
        if not suppress_error:
            raise
    return default


def is_initialized(profile_name=None):
    """Check if a profile or an environment is initialized.

    If profile_name is provided, it will check if the profile
    is initialized. If not, it will just check that workenv is.
    """
    if profile_name:
        return get_profile_dir(profile_name) is not None
    else:
        return os.path.isfile(os.path.join(CLOUDIFY_WORKDIR, 'config.yaml'))


def get_context_path(profile_name, suppress_error=False):
    base_dir = get_profile_dir(profile_name, suppress_error)
    if not base_dir:
        return
    return os.path.join(
{'fraction_non_alphanumeric': 0.08328556219801818, 'fraction_numerical': 0.003685201867168946, 'mean_word_length': 3.0197498354180383, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5480861', 'n_tokens_mistral': 3549, 'n_tokens_neox': 3475, 'n_words': 1071}