Skip to content

Utils

Module containing various util functions and classes.

TIMSource

Utility click type for TIM sources.

Allows a TIM source to be either a local file path or a GIT repository URI. Common repository link formats e.g.,

  • https://github.com/acme/foobar.git
  • git@github.com:acme/foobar.git

will be detected automatically. For less common formats like SSH links with a username that is not git you will have to prefix git+ to the link.

convert(self, value, param, ctx)

Check if the TIM source is a local path or remote URL.

Parameters:

Name Type Description Default
value str

The str tim source

required
param str

The param name

required
ctx Context

The click cli context

required

Returns:

Type Description
Union[str, pathlib.Path]

The path parameter as pathlib.Path or a str if the path is a URL.

Source code in generator/utils.py
def convert(self, value: str, param: str, ctx: Context) -> Union[str, Path]:  # type: ignore[override]
    """Check if the TIM source is a local path or remote URL.

    Args:
        value: The str tim source
        param: The param name
        ctx: The click cli context

    Returns:
        The path parameter as pathlib.Path or a str
        if the path is a URL.
    """
    if self.__git_regex.match(value):
        return self.__git_replace.sub(r"\1", value)

    return Path(super().convert(value, param, ctx))  # type: ignore[arg-type]

create_seed()

Create a random integer seed

Returns:

Type Description
int

An integer seed

Source code in generator/utils.py
def create_seed() -> int:
    """Create a random integer seed

    Returns:
        An integer seed
    """
    return Random().randint(sys.maxsize * -1, sys.maxsize)

is_git_repo(path)

Checks if the directory at the given path is a GIT repository.

Parameters:

Name Type Description Default
path Union[str, pathlib.Path]

The path to check

required

Returns:

Type Description
Optional[git.repo.base.Repo]

A Repo object if the directory is a valid repository or None otherwise.

Source code in generator/utils.py
def is_git_repo(path: Union[str, Path]) -> Optional[Repo]:
    """Checks if the directory at the given path is a GIT repository.

    Args:
        path: The path to check

    Returns:
        A Repo object if the directory is a valid repository or None otherwise.
    """
    try:
        return Repo(path)
    except InvalidGitRepositoryError:
        return None

load_config(config)

Loads either a YAML or JSON config string.

Non string arguments are returned as is.

Parameters:

Name Type Description Default
config str

The config string

required

Returns:

Type Description
Any

The loaded config as python data types

Source code in generator/utils.py
def load_config(config: str) -> Any:
    """Loads either a YAML or JSON config string.

    Non string arguments are returned as is.

    Args:
        config: The config string

    Returns:
        The loaded config as python data types
    """
    if isinstance(config, str):
        yaml = YAML(typ="safe")
        try:
            return yaml.load(config)
        except YAMLError:
            return json.loads(config)
    else:
        return config

version_info()

Returns formatted version information about the cr_kyoushi.generator package.

Adapted from Pydantic version.py

Returns:

Type Description
str

CLI information about the Cyber Range Kyoushi Generator tool.

Source code in generator/utils.py
def version_info() -> str:
    """Returns formatted version information about the `cr_kyoushi.generator package`.

    Adapted from
    [Pydantic version.py](https://github.com/samuelcolvin/pydantic/blob/master/pydantic/version.py)

    Returns:
        CLI information about the Cyber Range Kyoushi Generator tool.
    """
    import platform

    from . import __version__

    info = {
        "cr_kyoushi.testbed version": __version__,
        "install path": Path(__file__).resolve().parent,
        "python version": sys.version,
        "platform": platform.platform(),
    }
    return "\n".join(
        "{:>30} {}".format(k + ":", str(v).replace("\n", " ")) for k, v in info.items()
    )

write_config(config, dest)

Writes a complex config data type to a file in YAML format.

Parameters:

Name Type Description Default
config Any

The data to write

required
dest Path

The destination file path

required
Source code in generator/utils.py
def write_config(config: Any, dest: Path):
    """Writes a complex config data type to a file in YAML format.

    Args:
        config: The data to write
        dest: The destination file path
    """
    # need to dump to json first to support the additional types
    # provided by pydantic
    json_str = json.dumps(config, default=pydantic_encoder)

    yaml = YAML(typ="safe")
    yaml.indent(mapping=2, sequence=4, offset=2)
    yaml.default_flow_style = False
    yaml.sort_base_mapping_type_on_output = False  # type: ignore
    with open(dest, "w") as config_file:
        obj = json.loads(json_str)
        yaml.dump(obj, config_file)