Skip to content

Commit

Permalink
Merge pull request #1506 from alan-turing-institute/hatch
Browse files Browse the repository at this point in the history
Pulumi: Migrate pyproject to PyPA standard and hatch
  • Loading branch information
jemrobinson authored Jul 27, 2023
2 parents f0a8906 + 6bb9fd0 commit ed154d1
Show file tree
Hide file tree
Showing 82 changed files with 1,496 additions and 3,270 deletions.
15 changes: 0 additions & 15 deletions .flake8

This file was deleted.

16 changes: 9 additions & 7 deletions .github/workflows/lint_code.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ name: Lint code
# Run workflow on pushes to matching branches
on: # yamllint disable-line rule:truthy
push:
branches: [develop]
branches: [develop, python-migration]
pull_request:
branches: [develop]
branches: [develop, python-migration]

jobs:
lint_json:
Expand Down Expand Up @@ -53,12 +53,14 @@ jobs:
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install requirements
shell: bash
run: pip install flake8
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: 3.11
- name: Install hatch
run: pip install hatch
- name: Lint Python
shell: bash
run: flake8 . --statistics --count
run: hatch run lint:style

lint_shell:
runs-on: ubuntu-latest
Expand Down
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,5 @@ expanded.yaml
# mypy cache
.mypy_cache

# Pulumi secrets files
pulumi/Pulumi.*.yaml
# ruff cache
.ruff_cache
26 changes: 11 additions & 15 deletions data_safe_haven/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ Install the following requirements before starting
- [Poetry](https://python-poetry.org/docs/#installation)
- [Pulumi](https://www.pulumi.com/docs/get-started/install/)

# Deploying a Data Safe Haven

Create a directory where you want to store local configuration files for this deployment.
This is the `project directory`
## Deploying a Data Safe Haven

- Run the following to initialise the deployment [approx 5 minutes]:

Expand All @@ -25,42 +22,41 @@ If you prefer to enter these at the command line, run `dsh init -h` to see the n
> dsh deploy shm
```

You will be prompted for various project settings.
If you prefer to enter these at the command line, run `dsh deploy shm -h` to see the necessary command line flags.
You will be prompted for various settings.
Run `dsh deploy shm -h` to see the necessary command line flags and provide them as arguments.

- Add one or more users from a CSV file with columns named (`GivenName`, `Surname`, `Phone`, `Email`). Note that the phone number must be in full international format.

```bash
> dsh users add <my CSV users file>
> dsh admin add-users <my CSV users file>
```

- Next deploy the infrastructure for one or more Secure Research Environments (SREs) [approx 30 minutes]:

```bash
> dsh deploy sre <SRE name> -r <VM1 SKU> -r <VM2 SKU>
> dsh deploy sre <SRE name>
```

where you must specify a VM SKU for each user-accessible secure research desktop that you want to deploy
On first run, you will be prompted for various project settings.
If you prefer to enter these at the command line, run `dsh deploy sre -h` to see the necessary command line flags.
You will be prompted for various settings.
Run `dsh deploy sre -h` to see the necessary command line flags and provide them as arguments.

- Next add one or more existing users to your SRE

```bash
> dsh users register -s <SRE name> <username1> <username2>
> dsh admin register-users -s <SRE name> <username1> <username2>
```

where you must specify the usernames for each user you want to add to this SRE

# Administering a Data Safe Haven
## Administering a Data Safe Haven

- Run the following to list the currently available users

```bash
> dsh users list
> dsh admin list-users
```

# Removing a deployed Data Safe Haven
## Removing a deployed Data Safe Haven

- Run the following if you want to teardown a deployed SRE:

Expand Down
5 changes: 3 additions & 2 deletions data_safe_haven/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
"""Data Safe Haven"""
import pkg_resources

__version__ = pkg_resources.get_distribution("data-safe-haven").version
from .version import __version__, __version_info__

__all__ = ["__version__", "__version_info__"]
12 changes: 6 additions & 6 deletions data_safe_haven/administration/users/active_directory_users.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
"""Interact with users in an Azure Active Directory"""
# Standard library imports
import pathlib
from typing import Any, Optional, Sequence
from collections.abc import Sequence
from typing import Any

# Local imports
from data_safe_haven.config import Config
from data_safe_haven.external import AzureApi
from data_safe_haven.functions import b64encode
from data_safe_haven.pulumi import PulumiSHMStack
from data_safe_haven.utility import FileReader, Logger

from .research_user import ResearchUser


Expand Down Expand Up @@ -70,7 +70,7 @@ def add(self, new_users: Sequence[ResearchUser]) -> None:
for line in output.split("\n"):
self.logger.parse(line)

def list(self, sre_name: Optional[str] = None) -> Sequence[ResearchUser]:
def list(self, sre_name: str | None = None) -> Sequence[ResearchUser]: # noqa: A003
"""List users in a local Active Directory"""
list_users_script = FileReader(
self.resources_path / "active_directory" / "list_users.ps1"
Expand All @@ -85,7 +85,7 @@ def list(self, sre_name: Optional[str] = None) -> Sequence[ResearchUser]:
users = []
for line in output.split("\n"):
tokens = line.split(";")
if len(tokens) >= 6:
if len(tokens) >= 6: # noqa: PLR2004
users.append(
ResearchUser(
email_address=tokens[4],
Expand Down Expand Up @@ -127,7 +127,7 @@ def remove(self, users: Sequence[ResearchUser]) -> None:
for line in output.split("\n"):
self.logger.parse(line)

def set(self, users: Sequence[ResearchUser]) -> None:
def set(self, users: Sequence[ResearchUser]) -> None: # noqa: A003
"""Set local Active Directory users to specified list"""
users_to_remove = [user for user in self.list() if user not in users]
self.remove(users_to_remove)
Expand Down
18 changes: 9 additions & 9 deletions data_safe_haven/administration/users/azure_ad_users.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
"""Interact with users in an Azure Active Directory"""
# Standard library imports
from typing import Any, Sequence
from collections.abc import Sequence
from typing import Any

# Local imports
from data_safe_haven.external import GraphApi
from data_safe_haven.functions import password
from data_safe_haven.utility import Logger

from .research_user import ResearchUser


Expand All @@ -25,11 +25,11 @@ def __init__(
def add(self, new_users: Sequence[ResearchUser]) -> None:
"""Add list of users to AzureAD"""
# Get the default domain
default_domain = [
default_domain = next(
domain["id"]
for domain in self.graph_api.read_domains()
if domain["isDefault"]
][0]
)
for user in new_users:
request_json = {
"accountEnabled": user.account_enabled,
Expand All @@ -56,7 +56,7 @@ def add(self, new_users: Sequence[ResearchUser]) -> None:
# # Also add the user to the research users group
# self.graph_api.add_user_to_group(user.username, self.researchers_group_name)

def list(self) -> Sequence[ResearchUser]:
def list(self) -> Sequence[ResearchUser]: # noqa: A003
user_list = self.graph_api.read_users()
return [
ResearchUser(
Expand Down Expand Up @@ -98,14 +98,14 @@ def remove(self, users: Sequence[ResearchUser]) -> None:
# f"Removed '{user.preferred_username}' from group '{self.researchers_group_name}'"
# )
# else:
# raise DataSafeHavenMicrosoftGraphException
# except DataSafeHavenMicrosoftGraphException:
# raise DataSafeHavenMicrosoftGraphError
# except DataSafeHavenMicrosoftGraphError:
# self.logger.error(
# f"Unable to remove '{user.preferred_username}' from group '{self.researchers_group_name}'"
# )
pass

def set(self, users: Sequence[ResearchUser]) -> None:
def set(self, users: Sequence[ResearchUser]) -> None: # noqa: A003
"""Set Guacamole users to specified list"""
users_to_remove = [user for user in self.list() if user not in users]
self.remove(users_to_remove)
Expand Down
15 changes: 9 additions & 6 deletions data_safe_haven/administration/users/guacamole_users.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Standard library imports
import pathlib
from typing import Any, Optional, Sequence
from collections.abc import Sequence
from typing import Any

# Local imports
from data_safe_haven.config import Config
from data_safe_haven.external import AzurePostgreSQLDatabase
from data_safe_haven.pulumi import PulumiSREStack

from .research_user import ResearchUser


Expand All @@ -20,7 +20,7 @@ def __init__(self, config: Config, sre_name: str, *args: Any, **kwargs: Any):
sre_stack.output("remote_desktop")["resource_group_name"],
config.subscription_name,
)
self.users_: Optional[Sequence[ResearchUser]] = None
self.users_: Sequence[ResearchUser] | None = None
self.postgres_script_path: pathlib.Path = (
pathlib.Path(__file__).parent.parent.parent
/ "resources"
Expand All @@ -30,14 +30,17 @@ def __init__(self, config: Config, sre_name: str, *args: Any, **kwargs: Any):
self.sre_name = sre_name
self.group_name = f"Data Safe Haven Users SRE {sre_name}"

def list(self) -> Sequence[ResearchUser]:
def list(self) -> Sequence[ResearchUser]: # noqa: A003
"""List all Guacamole users"""
if self.users_ is None: # Allow for the possibility of an empty list of users
postgres_output = self.postgres_provisioner.execute_scripts(
[self.postgres_script_path / "list_users.mustache.sql"],
mustache_values={"group_name": self.group_name},
)
# The output is of the form [["sam_account_name1", "email_address1"], ["sam_account_name2", "email_address2"]]
# The output is of the form [
# ["sam_account_name1", "email_address1"],
# ["sam_account_name2", "email_address2"]
# ]
self.users_ = [
ResearchUser(
sam_account_name=user_details[0].split("@")[0],
Expand Down
19 changes: 9 additions & 10 deletions data_safe_haven/administration/users/research_user.py
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
# Standard library imports
from typing import Any, Optional
from typing import Any


class ResearchUser:
def __init__(
self,
account_enabled: Optional[bool] = None,
country: Optional[str] = None,
email_address: Optional[str] = None,
given_name: Optional[str] = None,
phone_number: Optional[str] = None,
sam_account_name: Optional[str] = None,
surname: Optional[str] = None,
user_principal_name: Optional[str] = None,
account_enabled: bool | None = None,
country: str | None = None,
email_address: str | None = None,
given_name: str | None = None,
phone_number: str | None = None,
sam_account_name: str | None = None,
surname: str | None = None,
user_principal_name: str | None = None,
) -> None:
self.account_enabled = account_enabled
self.country = country
Expand Down
Loading

0 comments on commit ed154d1

Please sign in to comment.