Add SDK Feature Flags (#313)

## Summary of the Pull Request

This enables feature flags for the SDK, which enables gating access to preview features to those that have specifically asked for them.  This is intended to be used within #266.

Note, this change also moves to using a `pydantic` model for the config, rather than hand-crafted JSON dicts.
This commit is contained in:
bmc-msft
2020-11-17 10:40:16 -05:00
committed by GitHub
parent c4f266ee00
commit ce3356d597
3 changed files with 78 additions and 32 deletions

View File

@ -9,6 +9,7 @@ import os
import re
import subprocess # nosec
import uuid
from enum import Enum
from shutil import which
from typing import Callable, Dict, List, Optional, Tuple, Type, TypeVar, cast
from uuid import UUID
@ -21,15 +22,15 @@ from pydantic import BaseModel
from six.moves import input # workaround for static analysis
from .__version__ import __version__
from .backend import Backend, ContainerWrapper, wait
from .backend import Backend, BackendConfig, ContainerWrapper, wait
from .ssh import build_ssh_command, ssh_connect, temp_file
UUID_EXPANSION = TypeVar("UUID_EXPANSION", UUID, str)
DEFAULT = {
"authority": "https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47",
"client_id": "72f1562a-8c0c-41ea-beb9-fa2b71c80134",
}
DEFAULT = BackendConfig(
authority="https://login.microsoftonline.com/72f988bf-86f1-41af-91ab-2d7cd011db47",
client_id="72f1562a-8c0c-41ea-beb9-fa2b71c80134",
)
# This was generated randomly and should be preserved moving forwards
ONEFUZZ_GUID_NAMESPACE = uuid.UUID("27f25e3f-6544-4b69-b309-9b096c5a9cbc")
@ -44,6 +45,10 @@ REPRO_SSH_FORWARD = "1337:127.0.0.1:1337"
UUID_RE = r"^[a-f0-9]{8}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[a-f0-9]{4}-?[a-f0-9]{12}\Z"
class PreviewFeature(Enum):
pass
def is_uuid(value: str) -> bool:
return bool(re.match(UUID_RE, value))
@ -1449,7 +1454,7 @@ class Onefuzz:
def __setup__(self, endpoint: Optional[str] = None) -> None:
if endpoint:
self._backend.config["endpoint"] = endpoint
self._backend.config.endpoint = endpoint
def licenses(self) -> object:
""" Return third-party licenses used by this package """
@ -1476,7 +1481,8 @@ class Onefuzz:
authority: Optional[str] = None,
client_id: Optional[str] = None,
client_secret: Optional[str] = None,
) -> Dict[str, str]:
enable_feature: Optional[PreviewFeature] = None,
) -> BackendConfig:
""" Configure onefuzz CLI """
self.logger.debug("set config")
@ -1493,22 +1499,24 @@ class Onefuzz:
"This could be an invalid OneFuzz API endpoint: "
"Missing HTTP Authentication"
)
self._backend.config["endpoint"] = endpoint
self._backend.config.endpoint = endpoint
if authority is not None:
self._backend.config["authority"] = authority
self._backend.config.authority = authority
if client_id is not None:
self._backend.config["client_id"] = client_id
self._backend.config.client_id = client_id
if client_secret is not None:
self._backend.config["client_secret"] = client_secret
self._backend.config.client_secret = client_secret
if enable_feature:
self._backend.enable_feature(enable_feature.name)
self._backend.app = None
self._backend.save_config()
data: Dict[str, str] = self._backend.config.copy()
if "client_secret" in data:
data = self._backend.config.copy(deep=True)
if data.client_secret is not None:
# replace existing secrets with "*** for user display
data["client_secret"] = "***" # nosec
data.client_secret = "***" # nosec
if not data["endpoint"]:
if not data.endpoint:
self.logger.warning("endpoint not configured yet")
return data
@ -1655,6 +1663,12 @@ class Onefuzz:
webhooks=webhooks,
)
def _warn_preview(self, feature: PreviewFeature) -> None:
self.logger.warning(
"%s are a preview-feature and may change in an upcoming release",
feature.name,
)
from .debug import Debug # noqa: E402
from .status.cmd import Status # noqa: E402