示例#1
0
def get_feature_toggles(api_url, client_access_token, defer=None):
    # hide INFO logging from UnleashClient
    logger = logging.getLogger()
    default_logging = logger.level
    logger.setLevel(logging.ERROR)
    defer(lambda: logger.setLevel(default_logging))

    # create temporary cache dir
    cache_dir = tempfile.mkdtemp()
    defer(lambda: shutil.rmtree(cache_dir))

    # create Unleash client
    headers = {"Authorization": f"Bearer {client_access_token}"}
    client = UnleashClient(
        url=api_url,
        app_name="qontract-reconcile",
        custom_headers=headers,
        cache_directory=cache_dir,
    )
    client.initialize_client()
    defer(client.destroy)

    return {
        k: "enabled" if v.enabled else "disabled"
        for k, v in client.features.items()
    }
示例#2
0
class Unleash():
    def __init__(self, app=None):
        # Constants
        self.name = 'unleash_client'
        self.client = None

        # Setup
        self.app = app
        if app is not None:
            self.init_app(app)

    def init_app(self, app):
        # Populate required arguments.
        unleash_args = {
            'url': app.config['UNLEASH_URL'],
            'app_name': app.config['UNLEASH_APP_NAME'],
            'environment': app.config['UNLEASH_ENVIRONMENT']
        }

        # Populate optional arguments.
        populated_optional_args = filter(lambda x: x in app.config,
                                         CONFIG_MAPPING.keys())
        for option in populated_optional_args:
            unleash_args[CONFIG_MAPPING[option]] = app.config[option]

        # Set up client.
        self.client = UnleashClient(**unleash_args)

        self.client.initialize_client()
        app.extensions = getattr(app, 'extensions', {})
        app.extensions['Unleash'] = self
示例#3
0
def unleash_client():
    unleash_client = UnleashClient(URL,
                                   APP_NAME,
                                   refresh_interval=REFRESH_INTERVAL,
                                   metrics_interval=METRICS_INTERVAL)
    yield unleash_client
    unleash_client.destroy()
def unleash_client(tmpdir):
    unleash_client = UnleashClient(URL,
                                   APP_NAME,
                                   refresh_interval=REFRESH_INTERVAL,
                                   metrics_interval=METRICS_INTERVAL,
                                   cache_directory=tmpdir.dirname)
    yield unleash_client
    unleash_client.destroy()
示例#5
0
def unleash_client_toggle_only():
    unleash_client = UnleashClient(URL,
                                   APP_NAME,
                                   refresh_interval=REFRESH_INTERVAL,
                                   metrics_interval=METRICS_INTERVAL,
                                   disable_registration=True,
                                   disable_metrics=True)
    yield unleash_client
    unleash_client.destroy()
def unleash_client_project(cache):
    unleash_client = UnleashClient(
        URL,
        APP_NAME,
        refresh_interval=REFRESH_INTERVAL,
        metrics_interval=METRICS_INTERVAL,
        cache=cache,
        project_name=PROJECT_NAME
    )
    yield unleash_client
    unleash_client.destroy()
def test_uc_get_variant():
    # Set up API
    responses.add(responses.POST, URL + REGISTER_URL, json={}, status=202)
    responses.add(responses.GET,
                  URL + FEATURES_URL,
                  json=MOCK_FEATURE_RESPONSE,
                  status=200)
    responses.add(responses.POST, URL + METRICS_URL, json={}, status=202)

    unleash_client = UnleashClient(URL, APP_NAME)
    # Create Unleash client and check initial load
    unleash_client.initialize_client()

    time.sleep(1)
    # If feature flag is on.
    variant = unleash_client.get_variant("testVariations",
                                         context={'userId': '2'})
    assert variant['name'] == 'VarA'
    assert variant['enabled']

    # If feature flag is not.
    variant = unleash_client.get_variant("testVariations",
                                         context={'userId': '3'})
    assert variant['name'] == 'disabled'
    assert not variant['enabled']

    unleash_client.destroy()
def test_uc_cache_bootstrap_file(cache):
    # Set up cache
    test_file = Path(Path(__file__).parent.resolve(), '..', 'utilities', 'mocks', 'mock_bootstrap.json')
    cache.bootstrap_from_file(initial_config_file=test_file)

    # Check bootstrapping
    unleash_client = UnleashClient(
        URL,
        APP_NAME,
        refresh_interval=REFRESH_INTERVAL,
        metrics_interval=METRICS_INTERVAL,
        cache=cache
    )
    assert len(unleash_client.features) >= 1
    assert unleash_client.is_enabled("ivan-project")
def test_uc_cache_bootstrap_url(cache):
    # Set up API
    responses.add(responses.GET, URL + FEATURES_URL, json=MOCK_FEATURE_RESPONSE, status=200, headers={'etag': ETAG_VALUE})

    # Set up cache
    cache.bootstrap_from_url(initial_config_url=URL + FEATURES_URL)

    # Check bootstrapping
    unleash_client = UnleashClient(
        URL,
        APP_NAME,
        refresh_interval=REFRESH_INTERVAL,
        metrics_interval=METRICS_INTERVAL,
        cache=cache
    )
    assert len(unleash_client.features) >= 4
    assert unleash_client.is_enabled("testFlag")
示例#10
0
def test_UC_initialize_full():
    client = UnleashClient(URL, APP_NAME, INSTANCE_ID, REFRESH_INTERVAL,
                           METRICS_INTERVAL, DISABLE_METRICS, CUSTOM_HEADERS)
    assert client.unleash_instance_id == INSTANCE_ID
    assert client.unleash_refresh_interval == REFRESH_INTERVAL
    assert client.unleash_metrics_interval == METRICS_INTERVAL
    assert client.unleash_disable_metrics == DISABLE_METRICS
    assert client.unleash_custom_headers == CUSTOM_HEADERS
示例#11
0
def get_feature_toggle_state(integration_name, defer=None):
    api_url = os.environ.get("UNLEASH_API_URL")
    client_access_token = os.environ.get("UNLEASH_CLIENT_ACCESS_TOKEN")
    if not (api_url and client_access_token):
        return True

    # create temporary cache dir
    cache_dir = tempfile.mkdtemp()
    defer(lambda: shutil.rmtree(cache_dir))

    # hide INFO logging from UnleashClient
    with log_lock:
        logger = logging.getLogger()
        default_logging = logger.level
        logger.setLevel(logging.ERROR)

        # create Unleash client
        headers = {"Authorization": f"Bearer {client_access_token}"}
        client = UnleashClient(
            url=api_url,
            app_name="qontract-reconcile",
            custom_headers=headers,
            cache_directory=cache_dir,
        )
        client.initialize_client()

        # get feature toggle state
        state = client.is_enabled(integration_name,
                                  fallback_function=get_feature_toggle_default)
        client.destroy()
        logger.setLevel(default_logging)
        return state
def unleash_client_nodestroy(cache):
    unleash_client = UnleashClient(
        URL,
        APP_NAME,
        refresh_interval=REFRESH_INTERVAL,
        metrics_interval=METRICS_INTERVAL,
        cache=cache
    )
    yield unleash_client
示例#13
0
def test_uc_customstrategy_depredationwarning():
    responses.add(responses.POST, URL + REGISTER_URL, json={}, status=202)
    responses.add(responses.GET,
                  URL + FEATURES_URL,
                  json=MOCK_CUSTOM_STRATEGY,
                  status=200)
    responses.add(responses.POST, URL + METRICS_URL, json={}, status=202)

    custom_strategies_dict = {"amIACat": CatTest, "amIADog": DogTest}

    unleash_client = UnleashClient(URL,
                                   APP_NAME,
                                   environment="prod",
                                   custom_strategies=custom_strategies_dict)

    unleash_client.initialize_client()

    # Check a toggle that contains an outdated custom strategy
    assert unleash_client.is_enabled("CustomToggleWarning", {"sound": "meow"})
def test_UC_initialize_full():
    client = UnleashClient(URL, APP_NAME, ENVIRONMENT, INSTANCE_ID,
                           REFRESH_INTERVAL, METRICS_INTERVAL, DISABLE_METRICS,
                           DISABLE_REGISTRATION, CUSTOM_HEADERS,
                           CUSTOM_OPTIONS)
    assert client.unleash_instance_id == INSTANCE_ID
    assert client.unleash_refresh_interval == REFRESH_INTERVAL
    assert client.unleash_metrics_interval == METRICS_INTERVAL
    assert client.unleash_disable_metrics == DISABLE_METRICS
    assert client.unleash_disable_registration == DISABLE_REGISTRATION
    assert client.unleash_custom_headers == CUSTOM_HEADERS
    assert client.unleash_custom_options == CUSTOM_OPTIONS
def test_uc_cache_bootstrap_dict(cache):
    # Set up API
    responses.add(responses.POST, URL + REGISTER_URL, json={}, status=202)
    responses.add(responses.GET, URL + FEATURES_URL, json=MOCK_FEATURE_RESPONSE, status=200, headers={'etag': ETAG_VALUE})
    responses.add(responses.POST, URL + METRICS_URL, json={}, status=202)

    # Set up cache
    cache.bootstrap_from_dict(initial_config=MOCK_FEATURE_RESPONSE_PROJECT)

    # Check bootstrapping
    unleash_client = UnleashClient(
        URL,
        APP_NAME,
        refresh_interval=REFRESH_INTERVAL,
        metrics_interval=METRICS_INTERVAL,
        cache=cache
    )
    assert len(unleash_client.features) == 1
    assert unleash_client.is_enabled("ivan-project")

    # Create Unleash client and check initial load
    unleash_client.initialize_client()
    time.sleep(1)
    assert unleash_client.is_initialized
    assert len(unleash_client.features) >= 4
    assert unleash_client.is_enabled("testFlag")
示例#16
0
def get_unleash_strategies(api_url, token, strategy_names, defer=None):
    # create strategy mapping
    unleash_strategies = {name: strategies.Strategy for name in strategy_names}

    # create temporary cache dir
    cache_dir = tempfile.mkdtemp()
    defer(lambda: shutil.rmtree(cache_dir))

    # hide INFO logging from UnleashClient
    with log_lock:
        logger = logging.getLogger()
        default_logging = logger.level
        logger.setLevel(logging.ERROR)

        # create Unleash client
        headers = {"Authorization": f"Bearer {token}"}
        client = UnleashClient(
            url=api_url,
            app_name="qontract-reconcile",
            custom_headers=headers,
            cache_directory=cache_dir,
            custom_strategies=unleash_strategies,
        )
        client.initialize_client()

        strats = {
            name: toggle.strategies
            for name, toggle in client.features.items()
        }
        client.destroy()

        logger.setLevel(default_logging)
        return strats
def test_uc_is_enabled_with_context():
    # Set up API
    responses.add(responses.POST, URL + REGISTER_URL, json={}, status=202)
    responses.add(responses.GET, URL + FEATURES_URL, json=MOCK_FEATURE_RESPONSE, status=200)
    responses.add(responses.POST, URL + METRICS_URL, json={}, status=202)

    custom_strategies_dict = {
        "custom-context": EnvironmentStrategy
    }

    unleash_client = UnleashClient(URL, APP_NAME, environment='prod', custom_strategies=custom_strategies_dict)
    # Create Unleash client and check initial load
    unleash_client.initialize_client()

    time.sleep(1)
    assert unleash_client.is_enabled("testContextFlag")
    unleash_client.destroy()
示例#18
0
    def __get_unleash_client():
        """
        Initialize the client if client is None Else Return the established client
        """
        if FeatureToggles.__enable_toggle_service:
            if FeatureToggles.__client is None:
                FeatureToggles.__client = UnleashClient(
                    url=FeatureToggles.__url,
                    app_name=FeatureToggles.__app_name,
                    instance_id=FeatureToggles.__instance_id,
                    cas_name=FeatureToggles.__cas_name,
                    environment=FeatureToggles.__environment,
                    redis_host=FeatureToggles.__redis_host,
                    redis_port=FeatureToggles.__redis_port,
                    redis_db=FeatureToggles.__redis_db)
                FeatureToggles.__client.initialize_client()
        else:
            FeatureToggles.__client = FeatureTogglesFromConst()

        return FeatureToggles.__client
def test_uc_custom_strategy():
    # Set up API
    responses.add(responses.POST, URL + REGISTER_URL, json={}, status=202)
    responses.add(responses.GET,
                  URL + FEATURES_URL,
                  json=MOCK_CUSTOM_STRATEGY,
                  status=200)
    responses.add(responses.POST, URL + METRICS_URL, json={}, status=202)

    custom_strategies_dict = {"amIACat": CatTest}

    unleash_client = UnleashClient(URL,
                                   APP_NAME,
                                   custom_strategies=custom_strategies_dict)

    # Create Unleash client and check initial load
    unleash_client.initialize_client()

    assert unleash_client.is_enabled("CustomToggle", {"sound": "meow"})
    assert not unleash_client.is_enabled("CustomToggle", {"sound": "bark"})
示例#20
0
def test_uc_customstrategy_happypath(recwarn):
    responses.add(responses.POST, URL + REGISTER_URL, json={}, status=202)
    responses.add(responses.GET,
                  URL + FEATURES_URL,
                  json=MOCK_CUSTOM_STRATEGY,
                  status=200)
    responses.add(responses.POST, URL + METRICS_URL, json={}, status=202)

    custom_strategies_dict = {"amIACat": CatTest, "amIADog": DogTest}

    unleash_client = UnleashClient(URL,
                                   APP_NAME,
                                   environment="prod",
                                   custom_strategies=custom_strategies_dict)

    unleash_client.initialize_client()

    # Check custom strategy.
    assert unleash_client.is_enabled("CustomToggle", {"sound": "meow"})
    assert not unleash_client.is_enabled("CustomToggle", {"sound": "bark"})

    # Check warning on deprecated strategy.
    assert len(recwarn) == 1
    assert recwarn.pop(DeprecationWarning)
def test_uc_with_network_error():
    unleash_client = UnleashClient("https://thisisavalidurl.com", APP_NAME)
    unleash_client.initialize_client()

    assert unleash_client.is_enabled
def test_uc_with_invalid_url():
    unleash_client = UnleashClient("thisisnotavalidurl", APP_NAME)

    with pytest.raises(ValueError):
        unleash_client.initialize_client()
def test_uc_not_initialized_getvariant():
    unleash_client = UnleashClient(URL, APP_NAME)
    variant = unleash_client.get_variant("ThisFlagDoesn'tExist")
    assert not variant['enabled']
    assert variant['name'] == 'disabled'
def test_uc_not_initialized_isenabled():
    unleash_client = UnleashClient(URL, APP_NAME)
    assert not unleash_client.is_enabled("ThisFlagDoesn'tExist")
    assert unleash_client.is_enabled("ThisFlagDoesn'tExist", fallback_function=lambda x, y: True)
def test_UC_type_violation():
    client = UnleashClient(URL, APP_NAME, refresh_interval="60")
    assert client.unleash_url == URL
    assert client.unleash_app_name == APP_NAME
    assert client.unleash_refresh_interval == "60"
示例#26
0
        "NAME":
        "django.contrib.auth.password_validation.CommonPasswordValidator",
    },
    {
        "NAME":
        "django.contrib.auth.password_validation.NumericPasswordValidator",
    },
]

# Internationalization
# https://docs.djangoproject.com/en/3.1/topics/i18n/

LANGUAGE_CODE = "en-us"

TIME_ZONE = "UTC"

USE_I18N = True

USE_L10N = True

USE_TZ = True

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.1/howto/static-files/

STATIC_URL = "/static/"

# unleash (feature-flag service)
UNLEASH_CLIENT = UnleashClient("http://localhost:4242/api", "Flagged App")
UNLEASH_CLIENT.initialize_client()
def test_UC_initialize_default():
    client = UnleashClient(URL, APP_NAME)
    assert client.unleash_url == URL
    assert client.unleash_app_name == APP_NAME
    assert client.unleash_metrics_interval == 60
示例#28
0
import time
from UnleashClient import UnleashClient

# ---
import logging
import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
root.addHandler(handler)
# ---

my_client = UnleashClient(url="http://localhost:4242/api", app_name="pyIvan")

my_client.initialize_client()

while True:
    time.sleep(10)
    print(my_client.is_enabled("Demo"))
示例#29
0
def unleash_client():
    unleash_client = UnleashClient(url=URL,
                                   app_name=APP_NAME,
                                   instance_id='pytest_%s' % uuid.uuid4())
    yield unleash_client
    unleash_client.destroy()
from UnleashClient import UnleashClient
from UnleashClient.strategies import Strategy

# ---
import logging
import sys

root = logging.getLogger()
root.setLevel(logging.DEBUG)

handler = logging.StreamHandler(sys.stdout)
handler.setLevel(logging.DEBUG)
formatter = logging.Formatter(
    '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
handler.setFormatter(formatter)
root.addHandler(handler)
# ---

my_client = UnleashClient(
    url="https://unleash.herokuapp.com/api",
    environment="staging",
    app_name="pyIvan",
)

my_client.initialize_client()

while True:
    time.sleep(10)
    context = {'userId': "1", 'sound': 'woof'}
    print(f"ivantest: {my_client.is_enabled('ivantest', context)}")