Skip to content

Commit 151e4b2

Browse files
committed
Merge remote-tracking branch 'origin/main' into tests/test-purge-openstack-resources
2 parents 8b18ff7 + da4a3c6 commit 151e4b2

File tree

13 files changed

+228
-127
lines changed

13 files changed

+228
-127
lines changed

.github/dependabot.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@ updates:
2323
schedule:
2424
# Check for new versions daily
2525
interval: daily
26+
groups:
27+
pip-updates:
28+
patterns: ["*"]
2629
labels:
2730
- automation
2831
- pip-update
32+
commit-message:
33+
# Prefix all commit messages with "pip: "
34+
prefix: "pip"

.github/workflows/test-pr.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,11 @@ jobs:
7373
- name: Provision Azimuth
7474
uses: azimuth-cloud/azimuth-config/.github/actions/provision@devel
7575

76-
# # Run the tests
76+
# Run the tests
7777
- name: Run Azimuth tests
7878
uses: azimuth-cloud/azimuth-config/.github/actions/test@devel
7979

80-
# Tear down the environment
80+
# Tear down the environment
8181
- name: Destroy Azimuth
8282
uses: azimuth-cloud/azimuth-config/.github/actions/destroy@devel
8383
if: ${{ always() }}

Dockerfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ RUN python3 -m venv /venv && \
88
/venv/bin/pip install -U pip setuptools
99

1010
COPY requirements.txt /app/requirements.txt
11-
RUN /venv/bin/pip install --no-deps --requirement /app/requirements.txt
11+
RUN /venv/bin/pip install --requirement /app/requirements.txt
1212

1313
COPY . /app
14-
RUN /venv/bin/pip install --no-deps /app
14+
RUN /venv/bin/pip install /app
1515

1616

1717
FROM ubuntu:jammy

README.md

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,21 @@ metadata:
5656
5757
> **NOTE**: Any value other than `delete` means volumes will be kept.
5858

59+
### User-configurable behaviour
60+
61+
Annotations on the Kubernetes resources are only available to administrators with
62+
access to the Cluster API management cluster's Kubernetes API; therefore, the Janitor
63+
also provides an alternative user-facing mechanism for marking volumes which should
64+
not be deleted during cluster clean up. This is done by adding a property to the
65+
OpenStack volume using:
66+
67+
```
68+
openstack volume set --property janitor.capi.azimuth-cloud.com/keep='true' <volume-name-or-id>
69+
```
70+
71+
Any value other than 'true' will result in the volume being deleted when the workload
72+
cluster is deleted.
73+
5974
## How it works
6075

6176
`cluster-api-janitor-openstack` watches for `OpenStackCluster`s being created and adds its
@@ -66,7 +81,7 @@ Cluster API `Cluster`, from being removed until the finalizer is removed.
6681
(specifically, it waits for the `deletionTimestamp` to be set, indicating that a deletion
6782
has been requested), at which point it uses the credential from
6883
`OpenStackCluster.spec.identityRef` to remove any dangling resources that were created by
69-
the OCCM or Cinder CSI with the same cluster name as the cluster being deleted.
84+
the OCCM or Cinder CSI with the same cluster name as the cluster being deleted.
7085
The cluster name is determined by the `cluster.x-k8s.io/cluster-name` label on the
7186
OpenStackCluster resource, if present.
7287
If the label is not set, the name of the OpenStackCluster resource (`metadata.name`) is

capi_janitor/__init__.py

Whitespace-only changes.

capi_janitor/openstack/openstack.py

Lines changed: 14 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,36 +9,28 @@
99

1010

1111
class UnsupportedAuthenticationError(Exception):
12-
"""
13-
Raised when an unsupported authentication method is used.
14-
"""
12+
"""Raised when an unsupported authentication method is used."""
1513

1614
def __init__(self, auth_type):
1715
super().__init__(f"unsupported authentication type: {auth_type}")
1816

1917

2018
class AuthenticationError(Exception):
21-
"""
22-
Raised when an unknown authentication error is encountered.
23-
"""
19+
"""Raised when an unknown authentication error is encountered."""
2420

2521
def __init__(self, user):
2622
super().__init__(f"failed to authenticate as user: {user}")
2723

2824

2925
class CatalogError(Exception):
30-
"""
31-
Raised when an unknown catalog service type is requested.
32-
"""
26+
"""Raised when an unknown catalog service type is requested."""
3327

3428
def __init__(self, name):
3529
super().__init__(f"service type {name} not found in OpenStack service catalog")
3630

3731

3832
class Auth(httpx.Auth):
39-
"""
40-
Authenticator class for OpenStack connections.
41-
"""
33+
"""Authenticator class for OpenStack connections."""
4234

4335
def __init__(
4436
self, auth_url, application_credential_id, application_credential_secret
@@ -52,8 +44,9 @@ def __init__(
5244

5345
@contextlib.asynccontextmanager
5446
async def _refresh_token(self):
55-
"""
56-
Context manager to ensure only one request at a time triggers a token refresh.
47+
"""Context manager to ensure only one request at a time
48+
49+
triggers a token refresh.
5750
"""
5851
token = self._token
5952
async with self._lock:
@@ -95,9 +88,7 @@ async def async_auth_flow(self, request):
9588

9689

9790
class Resource(rest.Resource):
98-
"""
99-
Base resource for OpenStack APIs.
100-
"""
91+
"""Base resource for OpenStack APIs."""
10192

10293
def __init__(self, client, name, prefix=None, plural_name=None, singular_name=None):
10394
super().__init__(client, name, prefix)
@@ -140,9 +131,7 @@ def _extract_one(self, response):
140131

141132

142133
class Client(rest.AsyncClient):
143-
"""
144-
Client for OpenStack APIs.
145-
"""
134+
"""Client for OpenStack APIs."""
146135

147136
def __init__(self, /, base_url, prefix=None, **kwargs):
148137
# Extract the path part of the base_url
@@ -173,9 +162,7 @@ def resource(self, name, prefix=None, plural_name=None, singular_name=None):
173162

174163

175164
class Cloud:
176-
"""
177-
Object for interacting with OpenStack clouds.
178-
"""
165+
"""Object for interacting with OpenStack clouds."""
179166

180167
def __init__(self, auth, transport, interface, region=None):
181168
self._auth = auth
@@ -219,29 +206,21 @@ async def __aexit__(self, exc_type, exc_value, traceback):
219206

220207
@property
221208
def is_authenticated(self):
222-
"""
223-
Returns True if the cloud is authenticated, False otherwise.
224-
"""
209+
"""Returns True if the cloud is authenticated, False otherwise."""
225210
return bool(self._endpoints)
226211

227212
@property
228213
def current_user_id(self):
229-
"""
230-
The ID of the current user.
231-
"""
214+
"""The ID of the current user."""
232215
return self._auth._user_id
233216

234217
@property
235218
def apis(self):
236-
"""
237-
The APIs supported by the cloud.
238-
"""
219+
"""The APIs supported by the cloud."""
239220
return list(self._endpoints.keys())
240221

241222
def api_client(self, name, prefix=None):
242-
"""
243-
Returns a client for the named API.
244-
"""
223+
"""Returns a client for the named API."""
245224
if name not in self._clients:
246225
self._clients[name] = Client(
247226
base_url=self._endpoints[name],

0 commit comments

Comments
 (0)