Skip to content

Commit

Permalink
refactor(pycloudlib): add more typehint on manager, secret, and confi…
Browse files Browse the repository at this point in the history
…g modules (#1582)

* refactor: add more typehints to manager module and config/secret subpackages

* refactor: replace typing Optional with Union

* docs(pycloudlib): adjust docstrings for manager, config, and secret modules

* test(pycloudlib): add missing testcases for k8s configs and secrets

* refactor: fix return type for create_secret function

* refactor: fix incompatible types on function calls

* docs: fix typo on pip install

* test: handle unsupported config/secret adapter
  • Loading branch information
iromli committed Jun 22, 2022
1 parent fb4dae4 commit 39b9b42
Show file tree
Hide file tree
Showing 19 changed files with 600 additions and 463 deletions.
40 changes: 36 additions & 4 deletions jans-pycloudlib/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,44 @@

Utilities for Janssen cloud deployment. Used in Janssen docker images.

## Developer Guide
## Developer guide

Refer to https://github.com/JanssenProject/jans-pycloudlib/wiki for guidance on how to use/develop this library.
### Run testcases

Testcase files are available under `tests` directory.
To run testcase suite, follow steps below:

1. Install [tox](https://tox.wiki/en/latest/) by running `pip install tox`
1. Run `tox` executable to run all testcase suites (note, to run a single testcase suite, run `tox -- tests/path/to/testfile` instead; see avaiable test files under `tests` directory)

### Check docstrings

The sourcecode of `jans.pycloudlib` are heavily documented internally using docstrings.
To check whether they are missing docstrings, run the following steps:

1. Install [pydocstyle](http://www.pydocstyle.org/en/stable/) by running `pip install pydocstyle[toml]`
1. Check docstrings by running `pydocstyle`
1. Adjust docstrings if any error is reported by `pydocstyle`

### Check Python types

We are adding more typehints into the `jans.pycloudlib` sourcecode, gradually.

1. Install [mypy](https://mypy.readthedocs.io/en/stable/index.html) by running `pip install mypy`
1. Check typehints by running `mypy --install-types /path/to/python/file`
1. Fix errors reported by `mypy`

### Building internal docs

Internal docs are generated from sphinx-based docs at `docs` directory.
To generate/preview docs, run the following steps:

1. Install [sphinx-autobuild](https://github.com/executablebooks/sphinx-autobuild) by running `pip install sphinx-autobuild`
1. Generate docs by running `sphinx-autobuild --watch=jans docs docs/_build/html`
1. Visit http://localhost:8000 to see the generated docs (they are reloaded automatically when sourcecode is modified)

## Refs

# Refs
- https://www.linuxfoundation.org/press-release/2020/12/the-janssen-project-takes-on-worlds-most-demanding-digital-trust-challenges-at-linux-foundation/
- https://betanews.com/2020/12/08/linux-foundation-open-source-identity-management/
- https://www.techrepublic.com/article/linux-foundation-debuts-new-secure-open-source-cloud-native-access-management-software-platform/

5 changes: 5 additions & 0 deletions jans-pycloudlib/docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,8 @@ def find_version(*file_paths):
# relative to this directory. They are copied after the builtin static files,
# so a file named "default.css" will overwrite the builtin "default.css".
html_static_path = ['_static']

autodoc_default_options = {
"undoc-members": True,
"exclude-members": "_abc_impl",
}
6 changes: 3 additions & 3 deletions jans-pycloudlib/docs/config.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,20 @@ Consul
.. autoclass:: jans.pycloudlib.config.consul_config.ConsulConfig
:members:
:private-members:
:undoc-members:
:show-inheritance:

Kubernetes
==========

.. autoclass:: jans.pycloudlib.config.kubernetes_config.KubernetesConfig
:members:
:private-members:
:undoc-members:
:show-inheritance:

Google
======

.. autoclass:: jans.pycloudlib.config.google_config.GoogleConfig
:members:
:private-members:
:undoc-members:
:show-inheritance:
14 changes: 13 additions & 1 deletion jans-pycloudlib/docs/manager.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,28 @@ Manager

.. module:: jans.pycloudlib.manager

.. autoclass:: AdapterProtocol

.. autoclass:: BaseConfiguration
:members:
:private-members:
:undoc-members:

.. autoclass:: ConfigManager
:members:
:private-members:
:undoc-members:
:show-inheritance:

.. autoclass:: SecretManager
:members:
:private-members:
:undoc-members:
:show-inheritance:

.. autodata:: jans.pycloudlib.manager._Manager
.. autoclass:: jans.pycloudlib.manager._Manager
:members:
:private-members:
:undoc-members:

.. autofunction:: get_manager
3 changes: 3 additions & 0 deletions jans-pycloudlib/docs/secret.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ Vault
:members:
:private-members:
:undoc-members:
:show-inheritance:

Kubernetes
==========
Expand All @@ -21,6 +22,7 @@ Kubernetes
:members:
:private-members:
:undoc-members:
:show-inheritance:

Google
======
Expand All @@ -29,3 +31,4 @@ Google
:members:
:private-members:
:undoc-members:
:show-inheritance:
40 changes: 22 additions & 18 deletions jans-pycloudlib/jans/pycloudlib/config/base_config.py
Original file line number Diff line number Diff line change
@@ -1,48 +1,52 @@
"""This module contains base class for config adapter."""

from typing import Any
from typing import NoReturn
import typing as _t
from abc import ABC
from abc import abstractmethod


class BaseConfig:
class BaseConfig(ABC):
"""Base class for config adapter.
Must be sub-classed per implementation details.
"""

type = "config"
@property
def type(self) -> str:
"""Name of the configuration type.
def get(self, key: str, default: Any = "") -> NoReturn:
This attribute always returns ``config``.
"""
return "config"

@abstractmethod
def get(self, key: str, default: _t.Any = "") -> _t.Any:
"""Get specific config.
Subclass **MUST** implement this method.
"""
raise NotImplementedError

def set(self, key: str, value: Any) -> NoReturn:
@abstractmethod
def set(self, key: str, value: _t.Any) -> bool:
"""Set specific config.
Subclass **MUST** implement this method.
"""
raise NotImplementedError

def all(self) -> NoReturn: # pragma: no cover
"""Get all config (deprecated in favor of ``get_all``).

Subclass **MUST** implement this method.
"""
def all(self) -> dict[str, _t.Any]: # noqa: A003
"""Get all config (deprecated in favor of ``get_all``)."""
return self.get_all()

def set_all(self, data: dict) -> NoReturn:
@abstractmethod
def set_all(self, data: dict[str, _t.Any]) -> bool:
"""Set all config.
Subclass **MUST** implement this method.
"""
raise NotImplementedError

def get_all(self) -> NoReturn:
"""Get all secrets.
@abstractmethod
def get_all(self) -> dict[str, _t.Any]:
"""Get all configs.
Subclass **MUST** implement this method.
"""
raise NotImplementedError
Loading

0 comments on commit 39b9b42

Please sign in to comment.