Compare commits

...

31 Commits

Author SHA1 Message Date
Andrei Kvapil
6d402ecff9 Release v0.37.3 (#1566)
This PR prepares the release `v0.37.3`.
2025-11-01 03:23:25 +05:00
cozystack-bot
2cb80079d1 Prepare release v0.37.3
Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com>
2025-10-31 20:39:20 +00:00
Andrei Kvapil
b8604b8ec5 [seaweedfs] Update SeaweedFS v3.99 and deploy S3 as stacked service (#1562)
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>

<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does


### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[]
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Helm values now control ingress paths; computed cluster endpoint env
vars are injected.
  * Optional container securityContext for volume init containers added.
  * Node architecture-specific targeting disabled by default.

* **Refactor**
* Image configuration reorganized with separate registry field;
container image build simplified.

* **Bug Fixes / Behavior**
* S3-related authorization and signature handling changed; S3 gateway
toggled.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-31 21:24:13 +01:00
Andrei Kvapil
f645a5d8fc Update LINSTOR v1.32.3 (#1565)
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>

<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does


### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
Update LINSTOR v1.32.3
```
2025-10-31 21:22:30 +01:00
Timofei Larkin
31d87671a1 [system] kube-ovn: turn off enableLb (#1548)
<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does
Turns off kubeovn enableLb, kube-proxy implementation of kube-ovn.

### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[system] kube-ovn: turn off kube-proxy implementation
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Added a new load balancing configuration option to system settings
(disabled by default).

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-31 18:27:31 +01:00
Timofei Larkin
13b294c9a7 [redis-operator] Build patched operator in-tree (#1547)
## What this PR does

This patch moves the build of the Redis operator into the Cozystack
organization and patches it to prevent overwriting third-party labels on
owned resources.

### Release note

```release-note
[redis-operator] Move operator into tree and patch it to retain
third-party labels on owned resources, reducing noisy traffic to the API
server.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Implemented automated Docker image build pipeline with version
tracking and caching.
* Updated image configuration to include repository reference and digest
for reproducibility.

* **Bug Fixes**
* Improved label and annotation handling to preserve existing Kubernetes
resource metadata instead of overwriting it.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-31 18:26:31 +01:00
Andrei Kvapil
2ee2bf55ed [velero] Set defaultItemOperationTimeout=24h (#1542)
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>

<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does

This PR changes default timeout for Velero to copy single item. Default
value 4h is not enough for copying large block volumes of virtual
machines.

### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[velero] Set defaultItemOperationTimeout=24h
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Extended default operation timeout to 24 hours to provide increased
time for operations to complete.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-31 18:25:31 +01:00
Andrei Kvapil
39f51f7fba [dashboard] Update openapi-ui v1.0.3 + fixes (#1564)
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>

<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

- Update openapi-ui to v1.0.3
- Show YAML editor as readonly in YAML tab
- Remove inside link from user menu
- fix editing for tenantmodules, fixes
https://github.com/cozystack/cozystack/issues/1550
- fix editing valuesOverride, fixes
https://github.com/cozystack/cozystack/issues/1560

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[dashboard] Update openapi-ui v1.0.3 + fixes
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

* **Bug Fixes**
* Made YAML editor read-only to prevent accidental modifications in
details view
  * Fixed API request header handling to prevent stream abort issues
  * Updated resource API endpoint paths for correct data retrieval
  * Removed menu navigation item from user interface
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-31 18:21:09 +01:00
Timofei Larkin
0c50253e2c [kubernetes] Use controlPlane.replicas field (#1556)
## What this PR does

The managed Kubernetes app accepts a .controPlane.replicas field, but
this value was never used, instead being hardcoded in the
KamajiControlPlane template to 2. This patch fixes this.

### Release note

```release-note
[kubernetes] Pass the .controlPlane.replicas field into the
KamajiControlPlane template, making the replica count of the
controlplane pods user-configurable.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Control plane replica count is now configurable via Helm values,
allowing flexible deployment scaling.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-31 18:18:57 +01:00
Andrei Kvapil
cfab053c66 [mariadb-operator] Add post-delete job to remove PVCs (#1553)
<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does

[mariadb-operator] Add post-delete job to remove PVCs
This patch adds a Helm post-delete hook job that removes
PersistentVolumeClaims
left behind after Helm release deletion. The MariaDB Operator currently
does not
handle PVC cleanup, so this job ensures proper resource removal.

### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[mariadb-operator] Add a post-delete hook job to clean up PVCs left after Helm release deletion.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **New Features**
* Persistent storage volumes are now automatically cleaned up when the
MySQL application is deleted, preventing orphaned storage resources from
accumulating in your cluster.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-31 18:14:01 +01:00
Andrei Kvapil
67a8fa91e8 [seaweedfs] Allow users to discover their buckets (#1528)
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>

<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does

This PR enables building of `seaweedfs` image.
Also backports patch from upstream
https://github.com/seaweedfs/seaweedfs/pull/7335

### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[seaweedfs] Allow users to discover their buckets
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* S3 signature handling adjusted so signature verification focuses on
authentication; permission checks are evaluated afterward.

* **Chores**
* Build process now discovers and uses remote release versions
dynamically.
* Introduced an optimized multi-stage container build with improved
tagging and registry caching.
* Added configurable image settings (global image name and image tag)
for deployment.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-31 18:13:31 +01:00
Timofei Larkin
5703e16a80 [monitoring] add settings alert for slack (#1545)
**What this PR does**
This PR adds configuration for sending alerts from Alerta to Slack.

**Key changes**
Added Slack integration configuration in Alerta settings.
2025-10-31 18:12:37 +01:00
Andrei Kvapil
297ddf853b [Backport release-0.37] [kamaji] Respect 3rd party labels (#1534)
# Description
Backport of #1531 to `release-0.37`.
2025-10-21 15:05:55 +02:00
Timofei Larkin
62f80f85b4 [kamaji] Respect 3rd party labels
The Kamaji controller overwrites labels on many of the resources it owns
(clastix/kamaji#991). This change applies PR clastix/kamaji#992 to
Cozystack's build of Kamaji, so the lineage webhook doesn't fight the
Kamaji controller, causing a non-stop reconciliation loop.

```release-note
[kamaji] Do not clobber third party labels on resources controlled by
Kamaji.
```

Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
(cherry picked from commit b858745cdd)
2025-10-17 15:49:14 +00:00
Timofei Larkin
a5cdaddbb4 [lineage] Check for nil chart in HelmRelease (#1525)
## What this PR does

Some HelmReleases use `chartRef` instead of `chart`. If the lineage
webhook finds such a HelmRelease, a nil pointer dereference happens.
This patch adds a nil check to guard against this.

### Release note

```release-note
[lineage] Add a nil check to guard against HelmReleases with a nil
.spec.chart field when traversing the ownership tree.
```

(cherry picked from commit d57f9acc7a)
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
2025-10-16 17:19:19 +03:00
Timofei Larkin
0e4fe7a33e [dashboard] Show service LB IP (#1524)
Fix an incorrect JSON path that prevented Service LoadBalancer IPs from
rendering in the table view.

(cherry picked from commit 466f0fed52)
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
2025-10-16 17:19:13 +03:00
Timofei Larkin
ee95353342 [apps] Make VM service user facing (#1523)
(cherry picked from commit c1edc5d711)
Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
2025-10-16 17:19:04 +03:00
Andrei Kvapil
9506c58926 Release v0.37.2 (#1520)
This PR prepares the release `v0.37.2`.
2025-10-15 14:08:07 +02:00
cozystack-bot
ffcc55c588 Prepare release v0.37.2
Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com>
2025-10-15 10:56:27 +00:00
Andrei Kvapil
cbf67cd30e [Backport release-0.37] [platform] Better migration for 0.36.2->0.37.2+ (#1522)
# Description
Backport of #1521 to `release-0.37`.
2025-10-15 12:50:36 +02:00
Timofei Larkin
1b46ff3f6b [platform] Better migration for 0.36.2->0.37.2+
For users upgrading from 0.36.2 directly to 0.37.2+, where the
lineage-controller-webhook is broken out of the Cozystack controller
into a separate daemonset, the existing migration script of 0.36->0.37.0
is insufficient. This patch ensures the presence of the new version of
the lineage webhook and fixes a bug in the migration script where the
readiness of the webhook was not appropriately verified.

```release-note
[platform] Improved migration script when skipping versions 0.37.0 and
0.37.1 during upgrades.
```

Signed-off-by: Timofei Larkin <lllamnyp@gmail.com>
(cherry picked from commit bf1ece5f7c)
2025-10-15 10:50:02 +00:00
Timofei Larkin
674b3963a7 [lineage] Separate webhook from cozy controller (#1515)
## What this PR does

The lineage-controller-webhook makes a lot of outgoing API calls for
every event it handles, contributing to a high API server latency,
increasing the number of in-flight requests and generally degrading
performance. This patch remedies this by separating the lineage
component from the cozystack-controller and deploying it as a separate
component on all control-plane nodes. Additionally, a new internal label
is introduced to track if a resource has already been handled by the
webhook. This label is used to exclude such resources from
consideration. Addresses #1513.

### Release note

```release-note
[lineage] Break webhook out into a separate daemonset. Reduce
unnecessary webhook calls by marking handled resources and excluding
them from consideration by the webhook's object selector.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Standalone Lineage Controller Webhook deployed as its own DaemonSet
with a dedicated Helm chart and image build targets.
  - Dedicated TLS provisioning for the webhook via chart-managed certs.

- **Changes**
  - Main controller no longer hosts webhook endpoints or certificates.
- Webhook now excludes already-managed resources to reduce unnecessary
invocations.
  - Platform bundles updated to include the new webhook release.

- **Documentation**
  - Changelog updated to reflect the separation and optimization.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-15 12:49:02 +02:00
Andrei Kvapil
f71f914fe6 [Backport release-0.37] [api] Fix listing tenantnamespaces for non-oidc users (#1519)
# Description
Backport of #1517 to `release-0.37`.
2025-10-15 10:10:46 +02:00
Andrei Kvapil
a09ed799e9 [api] Fix listing tenantnamespaces for non-oidc users
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>
(cherry picked from commit 671e13df70)
2025-10-15 08:10:29 +00:00
Andrei Kvapil
8e35d6ae4e Release v0.37.1 (#1512)
This PR prepares the release `v0.37.1`.
2025-10-13 16:04:33 +02:00
cozystack-bot
2f8c6b72fe Prepare release v0.37.1
Signed-off-by: cozystack-bot <217169706+cozystack-bot@users.noreply.github.com>
2025-10-13 13:29:01 +00:00
Andrei Kvapil
5a679e12ad [api] Fix RBAC for listing of TenantNamespaces and handle system:masters (#1511)
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>

<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does

Fix regression introduced by
https://github.com/cozystack/cozystack/pull/1507

### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[api] Fix RBAC for listing of TenantNamespaces and handle system:masters
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- New Features
- System-wide administrators now see all tenant namespaces without
filtering.
- Expanded read access for role bindings to improve visibility of access
configurations.

- Bug Fixes
- Resolved cases where some authorized admins could not view all tenant
namespaces due to RBAC filtering.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-13 15:21:05 +02:00
Andrei Kvapil
0176ba5e95 [dashboard] Fix logout (#1510)
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>

<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does


### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[dashboard] Fix logout
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **New Features**
* Enhanced OIDC logout flow: backend logout is now supported, improving
reliability of signing out across services.
* Whitelisted the identity provider domain to enable seamless redirects
during authentication and logout journeys.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-13 15:02:47 +02:00
Andrei Kvapil
b474c07c80 Add addtional check to wait for lineage-webhook (#1506)
Signed-off-by: Andrei Kvapil <kvapss@gmail.com>

<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does


### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[]
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Chores**
* Added a timeout-based step that repeatedly attempts server-side
dry-run creation of a Kubernetes Service (headless) between controller
upgrade and subsequent waits.
* Inserts this validation step without altering existing flow or other
behaviors.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-13 15:02:35 +02:00
Andrei Kvapil
5dbdd0eafa [api] Efficient listing of TenantNamespaces (#1507)
## What this PR does

The Cozystack API server lists TenantNamespaces by running a
SubjectAccessReview against every single requested namespace to see if
the user can create a WorkloadMonitor there. Will this is robust in
terms of permissions, delegating the authorization decision to the k8s
API, this is incredibly inefficient and has caused high latency to the
API. This patch simplifies the logic by instead getting the user's
groups and checking if the namespace contains a rolebinding for that
group. That way listing TenantNamespaces is reduced to a list call to
the k8s API for namespaces and another list call for rolebindings across
all namespaces, while authorization is done on the Cozystack API server
instead of making further calls to the k8s API.

### Release note

```release-note
[api] Optimize listing of TenantNamespaces, fixes a bug causing very
high latency to the k8s API.
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- Bug Fixes
- TenantNamespace visibility now consistently reflects RBAC role
bindings. Cluster administrators see all namespaces; users only see
namespaces they’re permitted to access.

- Refactor
- Access evaluation simplified to rely on role/rolebinding membership,
removing per-namespace authorization calls and improving listing
performance.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-13 15:02:29 +02:00
Andrei Kvapil
21715c02bc The Cozystack Kubernetes tests are now POSIX-compatible (#1509)
This patch replaces bash-specific [[ ... ]] expressions in the
run_kubernetes_test function with POSIX-compliant case and test
constructs. It ensures that the Kubernetes version on each worker node
is verified correctly and that required components (CoreDNS, Cilium,
ingress-nginx, vsnap-crd) are ready before proceeding. Now the tests
work reliably even when executed with /bin/sh, such as in Bats.

```release-note
[tests] Make Kubernetes tests POSIX-compliant and more reliable:
verify worker node versions and ensure required releases (CoreDNS,
Cilium, ingress-nginx, vsnap-crd) are installed and ready.
```

<!-- Thank you for making a contribution! Here are some tips for you:
- Start the PR title with the [label] of Cozystack component:
- For system components: [platform], [system], [linstor], [cilium],
[kube-ovn], [dashboard], [cluster-api], etc.
- For managed apps: [apps], [tenant], [kubernetes], [postgres],
[virtual-machine] etc.
- For development and maintenance: [tests], [ci], [docs], [maintenance].
- If it's a work in progress, consider creating this PR as a draft.
- Don't hesistate to ask for opinion and review in the community chats,
even if it's still a draft.
- Add the label `backport` if it's a bugfix that needs to be backported
to a previous version.
-->

## What this PR does


### Release note

<!--  Write a release note:
- Explain what has changed internally and for users.
- Start with the same [label] as in the PR title
- Follow the guidelines at
https://github.com/kubernetes/community/blob/master/contributors/guide/release-notes.md.
-->

```release-note
[]
```

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Improved Kubernetes version detection to correctly handle 1.32
variants.
* Made node readiness checks more reliable to reduce false failures
during runs.

* **Refactor**
* Streamlined version matching logic for clearer, more predictable
behavior across releases.

* **Style**
  * Minor formatting cleanups with no functional impact.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-10-13 15:02:18 +02:00
87 changed files with 1403 additions and 723 deletions

View File

@@ -15,6 +15,7 @@ build: build-deps
make -C packages/extra/monitoring image
make -C packages/system/cozystack-api image
make -C packages/system/cozystack-controller image
make -C packages/system/lineage-controller-webhook image
make -C packages/system/cilium image
make -C packages/system/kubeovn image
make -C packages/system/kubeovn-webhook image

View File

@@ -39,7 +39,6 @@ import (
cozystackiov1alpha1 "github.com/cozystack/cozystack/api/v1alpha1"
"github.com/cozystack/cozystack/internal/controller"
"github.com/cozystack/cozystack/internal/controller/dashboard"
lcw "github.com/cozystack/cozystack/internal/lineagecontrollerwebhook"
"github.com/cozystack/cozystack/internal/telemetry"
helmv2 "github.com/fluxcd/helm-controller/api/v2"
@@ -222,20 +221,6 @@ func main() {
os.Exit(1)
}
// special one that's both a webhook and a reconciler
lineageControllerWebhook := &lcw.LineageControllerWebhook{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
}
if err := lineageControllerWebhook.SetupWithManagerAsController(mgr); err != nil {
setupLog.Error(err, "unable to setup controller", "controller", "LineageController")
os.Exit(1)
}
if err := lineageControllerWebhook.SetupWithManagerAsWebhook(mgr); err != nil {
setupLog.Error(err, "unable to setup webhook", "webhook", "LineageWebhook")
os.Exit(1)
}
// +kubebuilder:scaffold:builder
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {

View File

@@ -0,0 +1,179 @@
/*
Copyright 2025.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"crypto/tls"
"flag"
"os"
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
_ "k8s.io/client-go/plugin/pkg/client/auth"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/metrics/filters"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"sigs.k8s.io/controller-runtime/pkg/webhook"
cozystackiov1alpha1 "github.com/cozystack/cozystack/api/v1alpha1"
lcw "github.com/cozystack/cozystack/internal/lineagecontrollerwebhook"
// +kubebuilder:scaffold:imports
)
var (
scheme = runtime.NewScheme()
setupLog = ctrl.Log.WithName("setup")
)
func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(cozystackiov1alpha1.AddToScheme(scheme))
// +kubebuilder:scaffold:scheme
}
func main() {
var metricsAddr string
var enableLeaderElection bool
var probeAddr string
var secureMetrics bool
var enableHTTP2 bool
var tlsOpts []func(*tls.Config)
flag.StringVar(&metricsAddr, "metrics-bind-address", "0", "The address the metrics endpoint binds to. "+
"Use :8443 for HTTPS or :8080 for HTTP, or leave as 0 to disable the metrics service.")
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
"Enable leader election for controller manager. "+
"Enabling this will ensure there is only one active controller manager.")
flag.BoolVar(&secureMetrics, "metrics-secure", true,
"If set, the metrics endpoint is served securely via HTTPS. Use --metrics-secure=false to use HTTP instead.")
flag.BoolVar(&enableHTTP2, "enable-http2", false,
"If set, HTTP/2 will be enabled for the metrics and webhook servers")
opts := zap.Options{
Development: false,
}
opts.BindFlags(flag.CommandLine)
flag.Parse()
ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
// if the enable-http2 flag is false (the default), http/2 should be disabled
// due to its vulnerabilities. More specifically, disabling http/2 will
// prevent from being vulnerable to the HTTP/2 Stream Cancellation and
// Rapid Reset CVEs. For more information see:
// - https://github.com/advisories/GHSA-qppj-fm5r-hxr3
// - https://github.com/advisories/GHSA-4374-p667-p6c8
disableHTTP2 := func(c *tls.Config) {
setupLog.Info("disabling http/2")
c.NextProtos = []string{"http/1.1"}
}
if !enableHTTP2 {
tlsOpts = append(tlsOpts, disableHTTP2)
}
webhookServer := webhook.NewServer(webhook.Options{
TLSOpts: tlsOpts,
})
// Metrics endpoint is enabled in 'config/default/kustomization.yaml'. The Metrics options configure the server.
// More info:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.1/pkg/metrics/server
// - https://book.kubebuilder.io/reference/metrics.html
metricsServerOptions := metricsserver.Options{
BindAddress: metricsAddr,
SecureServing: secureMetrics,
TLSOpts: tlsOpts,
}
if secureMetrics {
// FilterProvider is used to protect the metrics endpoint with authn/authz.
// These configurations ensure that only authorized users and service accounts
// can access the metrics endpoint. The RBAC are configured in 'config/rbac/kustomization.yaml'. More info:
// https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.19.1/pkg/metrics/filters#WithAuthenticationAndAuthorization
metricsServerOptions.FilterProvider = filters.WithAuthenticationAndAuthorization
// TODO(user): If CertDir, CertName, and KeyName are not specified, controller-runtime will automatically
// generate self-signed certificates for the metrics server. While convenient for development and testing,
// this setup is not recommended for production.
}
// Configure rate limiting for the Kubernetes client
config := ctrl.GetConfigOrDie()
config.QPS = 50.0 // Increased from default 5.0
config.Burst = 100 // Increased from default 10
mgr, err := ctrl.NewManager(config, ctrl.Options{
Scheme: scheme,
Metrics: metricsServerOptions,
WebhookServer: webhookServer,
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "8796f12d.cozystack.io",
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
// when the Manager ends. This requires the binary to immediately end when the
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
// speeds up voluntary leader transitions as the new leader don't have to wait
// LeaseDuration time first.
//
// In the default scaffold provided, the program ends immediately after
// the manager stops, so would be fine to enable this option. However,
// if you are doing or is intended to do any operation such as perform cleanups
// after the manager stops then its usage might be unsafe.
// LeaderElectionReleaseOnCancel: true,
})
if err != nil {
setupLog.Error(err, "unable to start manager")
os.Exit(1)
}
lineageControllerWebhook := &lcw.LineageControllerWebhook{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
}
if err := lineageControllerWebhook.SetupWithManagerAsController(mgr); err != nil {
setupLog.Error(err, "unable to setup controller", "controller", "LineageController")
os.Exit(1)
}
if err := lineageControllerWebhook.SetupWithManagerAsWebhook(mgr); err != nil {
setupLog.Error(err, "unable to setup webhook", "webhook", "LineageWebhook")
os.Exit(1)
}
// +kubebuilder:scaffold:builder
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up health check")
os.Exit(1)
}
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
setupLog.Error(err, "unable to set up ready check")
os.Exit(1)
}
setupLog.Info("starting manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
os.Exit(1)
}
}

View File

@@ -0,0 +1,3 @@
# Changes after v0.37.0
* [lineage] Break webhook out into a separate daemonset. Reduce unnecessary webhook calls by marking handled resources and excluding them from consideration by the webhook's object selector (@lllamnyp in #1515).

View File

@@ -64,19 +64,19 @@ spec:
EOF
# Wait for the tenant-test namespace to be active
kubectl wait namespace tenant-test --timeout=20s --for=jsonpath='{.status.phase}'=Active
# Wait for the Kamaji control plane to be created (retry for up to 10 seconds)
timeout 10 sh -ec 'until kubectl get kamajicontrolplane -n tenant-test kubernetes-'"${test_name}"'; do sleep 1; done'
# Wait for the tenant control plane to be fully created (timeout after 4 minutes)
kubectl wait --for=condition=TenantControlPlaneCreated kamajicontrolplane -n tenant-test kubernetes-${test_name} --timeout=4m
# Wait for Kubernetes resources to be ready (timeout after 2 minutes)
kubectl wait tcp -n tenant-test kubernetes-${test_name} --timeout=2m --for=jsonpath='{.status.kubernetesResources.version.status}'=Ready
# Wait for all required deployments to be available (timeout after 4 minutes)
kubectl wait deploy --timeout=4m --for=condition=available -n tenant-test kubernetes-${test_name} kubernetes-${test_name}-cluster-autoscaler kubernetes-${test_name}-kccm kubernetes-${test_name}-kcsi-controller
# Wait for the machine deployment to scale to 2 replicas (timeout after 1 minute)
kubectl wait machinedeployment kubernetes-${test_name}-md0 -n tenant-test --timeout=1m --for=jsonpath='{.status.replicas}'=2
# Get the admin kubeconfig and save it to a file
@@ -105,9 +105,11 @@ EOF
versions=$(kubectl --kubeconfig tenantkubeconfig get nodes -o jsonpath='{.items[*].status.nodeInfo.kubeletVersion}')
node_ok=true
if [[ "$k8s_version" == v1.32* ]]; then
echo "⚠️ TODO: Temporary stub — allowing nodes with v1.33 while k8s_version is v1.32"
fi
case "$k8s_version" in
v1.32*)
echo "⚠️ TODO: Temporary stub — allowing nodes with v1.33 while k8s_version is v1.32"
;;
esac
for v in $versions; do
case "$k8s_version" in
@@ -134,7 +136,7 @@ EOF
esac
done
if ! $node_ok; then
if [ "$node_ok" != true ]; then
echo "Kubelet versions did not match expected ${k8s_version}" >&2
exit 1
fi

View File

@@ -324,6 +324,7 @@ func yamlTab(plural string) map[string]any {
"type": "builtin",
"typeName": plural,
"prefillValuesRequestIndex": float64(0),
"readOnly": true,
"substractHeight": float64(400),
},
},

View File

@@ -142,7 +142,7 @@ func CreateAllCustomColumnsOverrides() []*dashboardv1alpha1.CustomColumnsOverrid
createCustomColumnsOverride("stock-namespace-/v1/services", []any{
createCustomColumnWithJsonPath("Name", ".metadata.name", "S", "service", getColorForType("service"), "/openapi-ui/{2}/{reqsJsonPath[0]['.metadata.namespace']['-']}/factory/kube-service-details/{reqsJsonPath[0]['.metadata.name']['-']}"),
createStringColumn("ClusterIP", ".spec.clusterIP"),
createStringColumn("LoadbalancerIP", ".spec.loadBalancerIP"),
createStringColumn("LoadbalancerIP", ".status.loadBalancer.ingress[0].ip"),
createTimestampColumn("Created", ".metadata.creationTimestamp"),
}),
@@ -796,6 +796,7 @@ func CreateAllFactories() []*dashboardv1alpha1.Factory {
"substractHeight": float64(400),
"type": "builtin",
"typeName": "secrets",
"readOnly": true,
},
},
},

View File

@@ -38,6 +38,9 @@ func (l *LineageControllerWebhook) Map(hr *helmv2.HelmRelease) (string, string,
if !ok {
return "", "", "", fmt.Errorf("failed to load chart-app mapping from config")
}
if hr.Spec.Chart == nil {
return "", "", "", fmt.Errorf("cannot map helm release %s/%s to dynamic app", hr.Namespace, hr.Name)
}
s := hr.Spec.Chart.Spec
val, ok := cfg.chartAppMap[chartRef{s.SourceRef.Name, s.Chart}]
if !ok {

View File

@@ -26,6 +26,13 @@ var (
AncestryAmbiguous = fmt.Errorf("object ancestry is ambiguous")
)
const (
ManagedObjectKey = "internal.cozystack.io/managed-by-cozystack"
ManagerGroupKey = "apps.cozystack.io/application.group"
ManagerKindKey = "apps.cozystack.io/application.kind"
ManagerNameKey = "apps.cozystack.io/application.name"
)
// getResourceSelectors returns the appropriate CozystackResourceDefinitionResources for a given GroupKind
func (h *LineageControllerWebhook) getResourceSelectors(gk schema.GroupKind, crd *cozyv1alpha1.CozystackResourceDefinition) *cozyv1alpha1.CozystackResourceDefinitionResources {
switch {
@@ -91,7 +98,7 @@ func (h *LineageControllerWebhook) Handle(ctx context.Context, req admission.Req
labels, err := h.computeLabels(ctx, obj)
for {
if err != nil && errors.Is(err, NoAncestors) {
return admission.Allowed("object not managed by app")
break // not a problem, mark object as unmanaged
}
if err != nil && errors.Is(err, AncestryAmbiguous) {
warn = append(warn, "object ancestry ambiguous, using first ancestor found")
@@ -119,7 +126,7 @@ func (h *LineageControllerWebhook) Handle(ctx context.Context, req admission.Req
func (h *LineageControllerWebhook) computeLabels(ctx context.Context, o *unstructured.Unstructured) (map[string]string, error) {
owners := lineage.WalkOwnershipGraph(ctx, h.dynClient, h.mapper, h, o)
if len(owners) == 0 {
return nil, NoAncestors
return map[string]string{ManagedObjectKey: "false"}, NoAncestors
}
obj, err := owners[0].GetUnstructured(ctx, h.dynClient, h.mapper)
if err != nil {
@@ -135,7 +142,8 @@ func (h *LineageControllerWebhook) computeLabels(ctx context.Context, o *unstruc
}
labels := map[string]string{
// truncate apigroup to first 63 chars
"apps.cozystack.io/application.group": func(s string) string {
ManagedObjectKey: "true",
ManagerGroupKey: func(s string) string {
if len(s) < 63 {
return s
}
@@ -145,8 +153,8 @@ func (h *LineageControllerWebhook) computeLabels(ctx context.Context, o *unstruc
}
return s
}(gv.Group),
"apps.cozystack.io/application.kind": obj.GetKind(),
"apps.cozystack.io/application.name": obj.GetName(),
ManagerKindKey: obj.GetKind(),
ManagerNameKey: obj.GetName(),
}
templateLabels := map[string]string{
"kind": strings.ToLower(obj.GetKind()),

View File

@@ -1 +1 @@
ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:c8b08084a86251cdd18e237de89b695bca0e4f7eb1f1f6ddc2b903b4d74ea5ff
ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:10a265bde566618c801882bb16cd5c6da24314b342bba178c78785364ef53d5f

View File

@@ -147,7 +147,7 @@ spec:
podAdditionalMetadata:
labels:
policy.cozystack.io/allow-to-etcd: "true"
replicas: 2
replicas: {{ .Values.controlPlane.replicas }}
version: {{ include "kubernetes.versionMap" $ }}
---
apiVersion: cozystack.io/v1alpha1

View File

@@ -0,0 +1,74 @@
---
apiVersion: batch/v1
kind: Job
metadata:
name: {{ .Release.Name }}-cleanup
labels:
app.kubernetes.io/instance: {{ .Release.Name }}
annotations:
"helm.sh/hook": post-delete
"helm.sh/hook-weight": "10"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
spec:
template:
metadata:
labels:
app.kubernetes.io/instance: {{ .Release.Name }}
policy.cozystack.io/allow-to-apiserver: "true"
spec:
serviceAccountName: {{ .Release.Name }}-cleanup
restartPolicy: Never
containers:
- name: cleanup
image: docker.io/clastix/kubectl:v1.32
command:
- /bin/sh
- -c
- |
echo "Deleting orphaned PVCs for {{ .Release.Name }}..."
kubectl delete pvc -n {{ .Release.Namespace }} -l app.kubernetes.io/instance={{ .Release.Name }} || true
echo "PVC cleanup complete."
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ .Release.Name }}-cleanup
labels:
app.kubernetes.io/instance: {{ .Release.Name }}
annotations:
"helm.sh/hook": post-delete
helm.sh/hook-weight: "0"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ .Release.Name }}-cleanup
labels:
app.kubernetes.io/instance: {{ .Release.Name }}
annotations:
"helm.sh/hook": post-delete
"helm.sh/hook-weight": "5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
rules:
- apiGroups: [""]
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ .Release.Name }}-cleanup
labels:
app.kubernetes.io/instance: {{ .Release.Name }}
annotations:
"helm.sh/hook": post-delete
helm.sh/hook-weight: "5"
"helm.sh/hook-delete-policy": before-hook-creation,hook-succeeded
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ .Release.Name }}-cleanup
subjects:
- kind: ServiceAccount
name: {{ .Release.Name }}-cleanup

View File

@@ -1,2 +1,2 @@
cozystack:
image: ghcr.io/cozystack/cozystack/installer:v0.37.0@sha256:256c5a0f0ae2fc3ad6865b9fda74c42945b38a5384240fa29554617185b60556
image: ghcr.io/cozystack/cozystack/installer:v0.37.3@sha256:f89f7085d16fa10c933b12568a390f92bcd6b942a7efbe3c2ea94316730b5052

View File

@@ -68,6 +68,12 @@ releases:
disableTelemetry: true
{{- end }}
- name: lineage-controller-webhook
releaseName: lineage-controller-webhook
chart: cozy-lineage-controller-webhook
namespace: cozy-system
dependsOn: [cozystack-controller,cilium,cert-manager]
- name: cert-manager
releaseName: cert-manager
chart: cozy-cert-manager

View File

@@ -36,6 +36,12 @@ releases:
disableTelemetry: true
{{- end }}
- name: lineage-controller-webhook
releaseName: lineage-controller-webhook
chart: cozy-lineage-controller-webhook
namespace: cozy-system
dependsOn: [cozystack-controller,cert-manager]
- name: cert-manager
releaseName: cert-manager
chart: cozy-cert-manager

View File

@@ -105,6 +105,12 @@ releases:
disableTelemetry: true
{{- end }}
- name: lineage-controller-webhook
releaseName: lineage-controller-webhook
chart: cozy-lineage-controller-webhook
namespace: cozy-system
dependsOn: [cozystack-controller,cilium,kubeovn,cert-manager]
- name: cozystack-resource-definition-crd
releaseName: cozystack-resource-definition-crd
chart: cozystack-resource-definition-crd

View File

@@ -52,6 +52,12 @@ releases:
disableTelemetry: true
{{- end }}
- name: lineage-controller-webhook
releaseName: lineage-controller-webhook
chart: cozy-lineage-controller-webhook
namespace: cozy-system
dependsOn: [cozystack-controller,cert-manager]
- name: cozystack-resource-definition-crd
releaseName: cozystack-resource-definition-crd
chart: cozystack-resource-definition-crd

View File

@@ -1,2 +1,2 @@
e2e:
image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.37.0@sha256:10afd0a6c39248ec41d0e59ff1bc6c29bd0075b7cc9a512b01cf603ef39c33ea
image: ghcr.io/cozystack/cozystack/e2e-sandbox:v0.37.3@sha256:01e2e18cf5255091863199a66f35a1acebc2e28a935c9ac747ceb3b3af9c3cf3

View File

@@ -1 +1 @@
ghcr.io/cozystack/cozystack/matchbox:v0.37.0@sha256:5cca5f56b755285aefa11b1052fe55e1aa83b25bae34aef80cdb77ff63091044
ghcr.io/cozystack/cozystack/matchbox:v0.37.3@sha256:27f64c3bbc8a440cc820247aff6d93a3bbe2f42a27560436749d6fd5e662a583

View File

@@ -72,6 +72,8 @@
| `alerta.alerts.telegram.token` | Telegram token for your bot | `string` | `""` |
| `alerta.alerts.telegram.chatID` | Specify multiple ID's separated by comma. Get yours in https://t.me/chatid_echo_bot | `string` | `""` |
| `alerta.alerts.telegram.disabledSeverity` | List of severity without alerts, separated by comma like: "informational,warning" | `string` | `""` |
| `alerta.alerts.slack` | Configuration for Slack alerts | `*object` | `null` |
| `alerta.alerts.slack.url` | Configuration uri for Slack alerts | `*string` | `""` |
### Grafana configuration

View File

@@ -109,9 +109,20 @@ spec:
- name: AUTH_REQUIRED
value: "True"
{{- $plugins := list }}
{{- if and .Values.alerta.alerts.telegram.chatID .Values.alerta.alerts.telegram.token }}
{{- $plugins = append $plugins "telegram" }}
{{- end }}
{{- if .Values.alerta.alerts.slack.url }}
{{- $plugins = append $plugins "slack" }}
{{- end }}
{{- if gt (len $plugins) 0 }}
- name: "PLUGINS"
value: "telegram"
value: "{{ default "" (join "," $plugins) }}"
{{- end }}
{{- if and .Values.alerta.alerts.telegram.chatID .Values.alerta.alerts.telegram.token }}
- name: TELEGRAM_CHAT_ID
value: "{{ .Values.alerta.alerts.telegram.chatID }}"
- name: TELEGRAM_TOKEN
@@ -122,6 +133,11 @@ spec:
value: "{{ .Values.alerta.alerts.telegram.disabledSeverity }}"
{{- end }}
{{- if .Values.alerta.alerts.slack.url }}
- name: "SLACK_WEBHOOK_URL"
value: "{{ .Values.alerta.alerts.slack.url }}"
{{- end }}
ports:
- name: http
containerPort: 8080

View File

@@ -12,6 +12,17 @@
"type": "object",
"default": {},
"properties": {
"slack": {
"description": "Configuration for Slack alerts",
"type": "object",
"default": {},
"properties": {
"url": {
"description": "Configuration uri for Slack alerts",
"type": "string"
}
}
},
"telegram": {
"description": "Configuration for Telegram alerts",
"type": "object",

View File

@@ -90,6 +90,8 @@ logsStorages:
## @field telegramAlerts.token {string} Telegram token for your bot
## @field telegramAlerts.chatID {string} Specify multiple ID's separated by comma. Get yours in https://t.me/chatid_echo_bot
## @field telegramAlerts.disabledSeverity {string} List of severity without alerts, separated by comma like: "informational,warning"
## @field alerts.slack {*slackAlerts} Configuration for Slack alerts
## @field slackAlerts.url {*string} Configuration uri for Slack alerts
alerta:
storage: 10Gi
storageClassName: ""
@@ -112,6 +114,9 @@ alerta:
chatID: ""
disabledSeverity: ""
slack:
url: ""
## @section Grafana configuration
## @param grafana {grafana} Configuration for Grafana

View File

@@ -1 +1 @@
ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.37.0@sha256:f166f09cdc9cdbb758209883819ab8261a3793bc1d7a6b6685efd5a2b2930847
ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.37.3@sha256:9d5cf652534f9e59ad181740f146439ef04ed20ffee958141d66897fc192604f

View File

@@ -1 +1 @@
ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:7348bec610f08bd902c88c9a9f28fdd644727e2728a1e4103f88f0c99febd5e7
ghcr.io/cozystack/cozystack/s3manager:v0.5.0@sha256:2b00d2357ae507fabf19ed0b01d707b503195983c8063515aabafbe1cb267877

View File

@@ -6,6 +6,9 @@ rules:
- apiGroups: [""]
resources: ["namespaces", "secrets"]
verbs: ["get", "watch", "list"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["get", "watch", "list"]
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "update", "patch", "delete"]

View File

@@ -1,2 +1,2 @@
cozystackAPI:
image: ghcr.io/cozystack/cozystack/cozystack-api:v0.37.0@sha256:19d89e8afb90ce38ab7e42ecedfc28402f7c0b56f30957db957c5415132ff6ca
image: ghcr.io/cozystack/cozystack/cozystack-api:v0.37.3@sha256:bf366c6ad4d71246160a59519409554e817ccb397c7f28eac514ea5838c17c76

View File

@@ -1,45 +0,0 @@
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: cozystack-controller-webhook-selfsigned
namespace: {{ .Release.Namespace }}
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cozystack-controller-webhook-ca
namespace: {{ .Release.Namespace }}
spec:
secretName: cozystack-controller-webhook-ca
duration: 43800h # 5 years
commonName: cozystack-controller-webhook-ca
issuerRef:
name: cozystack-controller-webhook-selfsigned
isCA: true
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: cozystack-controller-webhook-ca
namespace: {{ .Release.Namespace }}
spec:
ca:
secretName: cozystack-controller-webhook-ca
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cozystack-controller-webhook
namespace: {{ .Release.Namespace }}
spec:
secretName: cozystack-controller-webhook-cert
duration: 8760h
renewBefore: 720h
issuerRef:
name: cozystack-controller-webhook-ca
commonName: cozystack-controller
dnsNames:
- cozystack-controller
- cozystack-controller.{{ .Release.Namespace }}.svc

View File

@@ -28,15 +28,3 @@ spec:
{{- if .Values.cozystackController.disableTelemetry }}
- --disable-telemetry
{{- end }}
ports:
- name: webhook
containerPort: 9443
volumeMounts:
- name: webhook-certs
mountPath: /tmp/k8s-webhook-server/serving-certs
readOnly: true
volumes:
- name: webhook-certs
secret:
secretName: cozystack-controller-webhook-cert
defaultMode: 0400

View File

@@ -1,5 +1,5 @@
cozystackController:
image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.37.0@sha256:845b8e68cbc277c2303080bcd55597e4334610d396dad258ad56fd906530acc3
image: ghcr.io/cozystack/cozystack/cozystack-controller:v0.37.3@sha256:d32e84565abcf91297afd98f0fd36578ccfe7c6ae56b982c1ba8934fedf5a33f
debug: false
disableTelemetry: false
cozystackVersion: "v0.37.0"
cozystackVersion: "v0.37.3"

File diff suppressed because one or more lines are too long

View File

@@ -32,3 +32,8 @@ spec:
secrets:
exclude: []
include: []
services:
exclude: []
include:
- resourceNames:
- virtual-machine-{{ .name }}

View File

@@ -4,7 +4,7 @@ FROM node:${NODE_VERSION}-alpine AS builder
RUN apk add git
WORKDIR /src
ARG COMMIT_REF=22f9143f5109fb90332651c857d70b51bffccd9b
ARG COMMIT_REF=88531ed6881b4ce4808e56c00905951d7ba8031c
RUN wget -O- https://github.com/PRO-Robotech/openapi-ui-k8s-bff/archive/${COMMIT_REF}.tar.gz | tar xzf - --strip-components=1
COPY patches /patches

View File

@@ -1,7 +1,7 @@
diff --git a/src/endpoints/forms/formPrepare/formPrepare.ts b/src/endpoints/forms/formPrepare/formPrepare.ts
diff --git a/src/endpoints/forms/prepareFormProps/prepareFormProps.ts b/src/endpoints/forms/prepareFormProps/prepareFormProps.ts
index 7e437db..90c40f6 100644
--- a/src/endpoints/forms/formPrepare/formPrepare.ts
+++ b/src/endpoints/forms/formPrepare/formPrepare.ts
--- a/src/endpoints/forms/prepareFormProps/prepareFormProps.ts
+++ b/src/endpoints/forms/prepareFormProps/prepareFormProps.ts
@@ -15,6 +15,7 @@ export const prepareFormProps: RequestHandler = async (req: TPrepareFormReq, res
const filteredHeaders = { ...req.headers }

View File

@@ -3,9 +3,14 @@ ARG NODE_VERSION=20.18.1
# openapi-k8s-toolkit
# imported from https://github.com/cozystack/openapi-k8s-toolkit
FROM node:${NODE_VERSION}-alpine AS openapi-k8s-toolkit-builder
RUN apk add git
WORKDIR /src
ARG COMMIT=4f57ab295b2a886eb294b0b987554194fbe67dcd
ARG COMMIT=e5f16b45de19f892de269cc4ef27e74aa62f4c92
RUN wget -O- https://github.com/cozystack/openapi-k8s-toolkit/archive/${COMMIT}.tar.gz | tar -xzvf- --strip-components=1
COPY openapi-k8s-toolkit/patches /patches
RUN git apply /patches/*.diff
RUN npm install
RUN npm install --build-from-source @swc/core
RUN npm run build
@@ -17,10 +22,10 @@ FROM node:${NODE_VERSION}-alpine AS builder
RUN apk add git
WORKDIR /src
ARG COMMIT_REF=65e7fa8b3dc530a36e94c8435622bb09961aef97
ARG COMMIT_REF=9ce4367657f49c0032d8016b1d9491f8abbd2b15
RUN wget -O- https://github.com/PRO-Robotech/openapi-ui/archive/${COMMIT_REF}.tar.gz | tar xzf - --strip-components=1
COPY patches /patches
COPY openapi-ui/patches /patches
RUN git apply /patches/*.diff
ENV PATH=/src/node_modules/.bin:$PATH

View File

@@ -0,0 +1,50 @@
diff --git a/src/components/molecules/EnrichedTable/organisms/EnrichedTable/utils.tsx b/src/components/molecules/EnrichedTable/organisms/EnrichedTable/utils.tsx
index 8bcef4d..2551e92 100644
--- a/src/components/molecules/EnrichedTable/organisms/EnrichedTable/utils.tsx
+++ b/src/components/molecules/EnrichedTable/organisms/EnrichedTable/utils.tsx
@@ -22,6 +22,15 @@ import { TableFactory } from '../../molecules'
import { ShortenedTextWithTooltip, FilterDropdown, TrimmedTags, TextAlignContainer, TinyButton } from './atoms'
import { TInternalDataForControls } from './types'
+const getPluralForm = (singular: string): string => {
+ // If already ends with 's', add 'es'
+ if (singular.endsWith('s')) {
+ return `${singular}es`
+ }
+ // Otherwise just add 's'
+ return `${singular}s`
+}
+
export const getCellRender = ({
value,
record,
@@ -255,7 +264,7 @@ export const getEnrichedColumnsWithControls = ({
key: 'controls',
className: 'controls',
width: 60,
- render: (value: TInternalDataForControls) => {
+ render: (value: TInternalDataForControls, record: unknown) => {
return (
// <TextAlignContainer $align="right" className="hideable">
<TextAlignContainer $align="center">
@@ -279,10 +288,19 @@ export const getEnrichedColumnsWithControls = ({
domEvent.stopPropagation()
domEvent.preventDefault()
if (key === 'edit') {
+ // Special case: redirect tenantmodules from core.cozystack.io to apps.cozystack.io with plural form
+ let apiGroupAndVersion = value.apiGroupAndVersion
+ let typeName = value.typeName
+ if (apiGroupAndVersion?.startsWith('core.cozystack.io/') && typeName === 'tenantmodules') {
+ const appsApiVersion = apiGroupAndVersion.replace('core.cozystack.io/', 'apps.cozystack.io/')
+ const pluralTypeName = getPluralForm(value.entryName)
+ apiGroupAndVersion = appsApiVersion
+ typeName = pluralTypeName
+ }
navigate(
`${baseprefix}/${value.cluster}${value.namespace ? `/${value.namespace}` : ''}${
value.syntheticProject ? `/${value.syntheticProject}` : ''
- }/${value.pathPrefix}/${value.apiGroupAndVersion}/${value.typeName}/${value.entryName}?backlink=${
+ }/${value.pathPrefix}/${apiGroupAndVersion}/${typeName}/${value.entryName}?backlink=${
value.backlink
}`,
)

View File

@@ -1,5 +1,5 @@
diff --git a/src/components/organisms/ListInsideClusterAndNs/ListInsideClusterAndNs.tsx b/src/components/organisms/ListInsideClusterAndNs/ListInsideClusterAndNs.tsx
index 577ba0f..018df9c 100644
index b6fb99f..965bac0 100644
--- a/src/components/organisms/ListInsideClusterAndNs/ListInsideClusterAndNs.tsx
+++ b/src/components/organisms/ListInsideClusterAndNs/ListInsideClusterAndNs.tsx
@@ -1,11 +1,16 @@
@@ -26,16 +26,16 @@ index 577ba0f..018df9c 100644
- const namespacesData = useBuiltinResources({
+ const namespacesData = useApiResources({
clusterName: cluster,
clusterName: selectedCluster || '',
- typeName: 'namespaces',
+ apiGroup: BASE_PROJECTS_API_GROUP,
+ apiVersion: BASE_PROJECTS_VERSION,
+ typeName: BASE_PROJECTS_RESOURCE_NAME,
limit: null,
isEnabled: selectedCluster !== undefined,
})
diff --git a/src/hooks/useNavSelectorInside.ts b/src/hooks/useNavSelectorInside.ts
index d69405e..5adbd5d 100644
index 5736e2b..1ec0f71 100644
--- a/src/hooks/useNavSelectorInside.ts
+++ b/src/hooks/useNavSelectorInside.ts
@@ -1,6 +1,11 @@
@@ -63,8 +63,8 @@ index d69405e..5adbd5d 100644
+ apiVersion: BASE_PROJECTS_VERSION,
+ typeName: BASE_PROJECTS_RESOURCE_NAME,
limit: null,
isEnabled: Boolean(clusterName),
})
diff --git a/src/utils/getBacklink.ts b/src/utils/getBacklink.ts
index a862354..f24e2bc 100644
--- a/src/utils/getBacklink.ts

View File

@@ -0,0 +1,15 @@
diff --git a/src/components/organisms/Header/organisms/User/User.tsx b/src/components/organisms/Header/organisms/User/User.tsx
index efe7ac3..80b715c 100644
--- a/src/components/organisms/Header/organisms/User/User.tsx
+++ b/src/components/organisms/Header/organisms/User/User.tsx
@@ -23,10 +23,6 @@ export const User: FC = () => {
// key: '1',
// label: <ThemeSelector />,
// },
- {
- key: '2',
- label: <div onClick={() => navigate(`${baseprefix}/inside/clusters`)}>Inside</div>,
- },
{
key: '3',
label: (

View File

@@ -1,6 +1,6 @@
{{- $brandingConfig:= lookup "v1" "ConfigMap" "cozy-system" "cozystack-branding" }}
{{- $tenantText := "v0.37.0" }}
{{- $tenantText := "v0.37.3" }}
{{- $footerText := "Cozystack" }}
{{- $titleText := "Cozystack Dashboard" }}
{{- $logoText := "false" }}

View File

@@ -55,6 +55,8 @@ spec:
- --http-address=0.0.0.0:8000
- --redirect-url=https://dashboard.{{ $host }}/oauth2/callback
- --oidc-issuer-url=https://keycloak.{{ $host }}/realms/cozy
- --backend-logout-url=https://keycloak.{{ $host }}/realms/cozy/protocol/openid-connect/logout?id_token_hint={id_token}
- --whitelist-domain=keycloak.{{ $host }}
- --email-domain=*
- --pass-access-token=true
- --pass-authorization-header=true

View File

@@ -1,6 +1,6 @@
openapiUI:
image: ghcr.io/cozystack/cozystack/openapi-ui:v0.37.0@sha256:13f38cf56830e899eb5e3d9dc8184965dd8dba9f8cd3c5ca10df0970355842d6
image: ghcr.io/cozystack/cozystack/openapi-ui:v0.37.3@sha256:5a7d4ce1f1a7d9b712c92d80a91d02b4783c2a2a0caa8096e8d92efa07a0f905
openapiUIK8sBff:
image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.37.0@sha256:2b626dbbf87241e8621ac5b0285f402edbc2c2069ba254ca2ace2dd5c9248ac8
image: ghcr.io/cozystack/cozystack/openapi-ui-k8s-bff:v0.37.3@sha256:fc53077fdfdc3340b169758b88ec6501405388f3aa9d483c14afeffb645100d6
tokenProxy:
image: ghcr.io/cozystack/cozystack/token-proxy:v0.37.0@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b
image: ghcr.io/cozystack/cozystack/token-proxy:v0.37.3@sha256:fad27112617bb17816702571e1f39d0ac3fe5283468d25eb12f79906cdab566b

View File

@@ -0,0 +1,156 @@
diff --git a/internal/resources/api_server_certificate.go b/internal/resources/api_server_certificate.go
index 436cdf9..4702b6c 100644
--- a/internal/resources/api_server_certificate.go
+++ b/internal/resources/api_server_certificate.go
@@ -108,6 +108,7 @@ func (r *APIServerCertificate) mutate(ctx context.Context, tenantControlPlane *k
}
r.resource.SetLabels(utilities.MergeMaps(
+ r.resource.GetLabels(),
utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()),
map[string]string{
constants.ControllerLabelResource: "x509",
diff --git a/internal/resources/api_server_kubelet_client_certificate.go b/internal/resources/api_server_kubelet_client_certificate.go
index 85b4d42..da18db4 100644
--- a/internal/resources/api_server_kubelet_client_certificate.go
+++ b/internal/resources/api_server_kubelet_client_certificate.go
@@ -95,6 +95,7 @@ func (r *APIServerKubeletClientCertificate) mutate(ctx context.Context, tenantCo
}
r.resource.SetLabels(utilities.MergeMaps(
+ r.resource.GetLabels(),
utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()),
map[string]string{
constants.ControllerLabelResource: "x509",
diff --git a/internal/resources/ca_certificate.go b/internal/resources/ca_certificate.go
index 5425b0b..625273f 100644
--- a/internal/resources/ca_certificate.go
+++ b/internal/resources/ca_certificate.go
@@ -137,7 +137,7 @@ func (r *CACertificate) mutate(ctx context.Context, tenantControlPlane *kamajiv1
corev1.TLSPrivateKeyKey: ca.PrivateKey,
}
- r.resource.SetLabels(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()))
+ r.resource.SetLabels(utilities.MergeMaps(r.resource.GetLabels(), utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName())))
utilities.SetObjectChecksum(r.resource, r.resource.Data)
diff --git a/internal/resources/datastore/datastore_certificate.go b/internal/resources/datastore/datastore_certificate.go
index dea45ae..8492a5e 100644
--- a/internal/resources/datastore/datastore_certificate.go
+++ b/internal/resources/datastore/datastore_certificate.go
@@ -94,6 +94,7 @@ func (r *Certificate) mutate(ctx context.Context, tenantControlPlane *kamajiv1al
r.resource.Data["ca.crt"] = ca
r.resource.SetLabels(utilities.MergeMaps(
+ r.resource.GetLabels(),
utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()),
map[string]string{
constants.ControllerLabelResource: "x509",
diff --git a/internal/resources/datastore/datastore_storage_config.go b/internal/resources/datastore/datastore_storage_config.go
index 7d03420..4ea9e64 100644
--- a/internal/resources/datastore/datastore_storage_config.go
+++ b/internal/resources/datastore/datastore_storage_config.go
@@ -181,7 +181,7 @@ func (r *Config) mutate(ctx context.Context, tenantControlPlane *kamajiv1alpha1.
utilities.SetObjectChecksum(r.resource, r.resource.Data)
- r.resource.SetLabels(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()))
+ r.resource.SetLabels(utilities.MergeMaps(r.resource.GetLabels(), utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName())))
return ctrl.SetControllerReference(tenantControlPlane, r.resource, r.Client.Scheme())
}
diff --git a/internal/resources/front-proxy-client-certificate.go b/internal/resources/front-proxy-client-certificate.go
index f5ed67c..2dd4eda 100644
--- a/internal/resources/front-proxy-client-certificate.go
+++ b/internal/resources/front-proxy-client-certificate.go
@@ -95,6 +95,7 @@ func (r *FrontProxyClientCertificate) mutate(ctx context.Context, tenantControlP
}
r.resource.SetLabels(utilities.MergeMaps(
+ r.resource.GetLabels(),
utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()),
map[string]string{
constants.ControllerLabelResource: "x509",
diff --git a/internal/resources/front_proxy_ca_certificate.go b/internal/resources/front_proxy_ca_certificate.go
index d410720..ccadc70 100644
--- a/internal/resources/front_proxy_ca_certificate.go
+++ b/internal/resources/front_proxy_ca_certificate.go
@@ -114,7 +114,7 @@ func (r *FrontProxyCACertificate) mutate(ctx context.Context, tenantControlPlane
kubeadmconstants.FrontProxyCAKeyName: ca.PrivateKey,
}
- r.resource.SetLabels(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()))
+ r.resource.SetLabels(utilities.MergeMaps(r.resource.GetLabels(), utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName())))
utilities.SetObjectChecksum(r.resource, r.resource.Data)
diff --git a/internal/resources/k8s_ingress_resource.go b/internal/resources/k8s_ingress_resource.go
index f2e014f..e1aef59 100644
--- a/internal/resources/k8s_ingress_resource.go
+++ b/internal/resources/k8s_ingress_resource.go
@@ -147,7 +147,7 @@ func (r *KubernetesIngressResource) Define(_ context.Context, tenantControlPlane
func (r *KubernetesIngressResource) mutate(tenantControlPlane *kamajiv1alpha1.TenantControlPlane) controllerutil.MutateFn {
return func() error {
- labels := utilities.MergeMaps(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()), tenantControlPlane.Spec.ControlPlane.Ingress.AdditionalMetadata.Labels)
+ labels := utilities.MergeMaps(r.resource.GetLabels(), utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()), tenantControlPlane.Spec.ControlPlane.Ingress.AdditionalMetadata.Labels)
r.resource.SetLabels(labels)
annotations := utilities.MergeMaps(r.resource.GetAnnotations(), tenantControlPlane.Spec.ControlPlane.Ingress.AdditionalMetadata.Annotations)
diff --git a/internal/resources/k8s_service_resource.go b/internal/resources/k8s_service_resource.go
index 7e7f11f..9c30145 100644
--- a/internal/resources/k8s_service_resource.go
+++ b/internal/resources/k8s_service_resource.go
@@ -76,7 +76,12 @@ func (r *KubernetesServiceResource) mutate(ctx context.Context, tenantControlPla
address, _ := tenantControlPlane.DeclaredControlPlaneAddress(ctx, r.Client)
return func() error {
- labels := utilities.MergeMaps(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()), tenantControlPlane.Spec.ControlPlane.Service.AdditionalMetadata.Labels)
+ labels := utilities.MergeMaps(
+ r.resource.GetLabels(),
+ utilities.KamajiLabels(
+ tenantControlPlane.GetName(), r.GetName()),
+ tenantControlPlane.Spec.ControlPlane.Service.AdditionalMetadata.Labels,
+ )
r.resource.SetLabels(labels)
annotations := utilities.MergeMaps(r.resource.GetAnnotations(), tenantControlPlane.Spec.ControlPlane.Service.AdditionalMetadata.Annotations)
diff --git a/internal/resources/kubeadm_config.go b/internal/resources/kubeadm_config.go
index ae4cfc0..98dc36d 100644
--- a/internal/resources/kubeadm_config.go
+++ b/internal/resources/kubeadm_config.go
@@ -89,7 +89,7 @@ func (r *KubeadmConfigResource) mutate(ctx context.Context, tenantControlPlane *
return err
}
- r.resource.SetLabels(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()))
+ r.resource.SetLabels(utilities.MergeMaps(r.resource.GetLabels(), utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName())))
params := kubeadm.Parameters{
TenantControlPlaneAddress: address,
diff --git a/internal/resources/kubeconfig.go b/internal/resources/kubeconfig.go
index a87da7f..bd77676 100644
--- a/internal/resources/kubeconfig.go
+++ b/internal/resources/kubeconfig.go
@@ -163,6 +163,7 @@ func (r *KubeconfigResource) mutate(ctx context.Context, tenantControlPlane *kam
}
r.resource.SetLabels(utilities.MergeMaps(
+ r.resource.GetLabels(),
utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()),
map[string]string{
constants.ControllerLabelResource: "kubeconfig",
diff --git a/internal/resources/sa_certificate.go b/internal/resources/sa_certificate.go
index b53c7b0..4001eca 100644
--- a/internal/resources/sa_certificate.go
+++ b/internal/resources/sa_certificate.go
@@ -113,7 +113,7 @@ func (r *SACertificate) mutate(ctx context.Context, tenantControlPlane *kamajiv1
kubeadmconstants.ServiceAccountPrivateKeyName: sa.PrivateKey,
}
- r.resource.SetLabels(utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName()))
+ r.resource.SetLabels(utilities.MergeMaps(r.resource.GetLabels(), utilities.KamajiLabels(tenantControlPlane.GetName(), r.GetName())))
utilities.SetObjectChecksum(r.resource, r.resource.Data)

View File

@@ -3,7 +3,7 @@ kamaji:
deploy: false
image:
pullPolicy: IfNotPresent
tag: v0.37.0@sha256:9f4fd5045ede2909fbaf2572e4138fcbd8921071ecf8f08446257fddd0e6f655
tag: v0.37.3@sha256:a879979f0defcd21c8c26c0276496f25c06adae674bb0057c30dec35dd18c2b1
repository: ghcr.io/cozystack/cozystack/kamaji
resources:
limits:
@@ -13,4 +13,4 @@ kamaji:
cpu: 100m
memory: 100Mi
extraArgs:
- --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.37.0@sha256:9f4fd5045ede2909fbaf2572e4138fcbd8921071ecf8f08446257fddd0e6f655
- --migrate-image=ghcr.io/cozystack/cozystack/kamaji:v0.37.3@sha256:a879979f0defcd21c8c26c0276496f25c06adae674bb0057c30dec35dd18c2b1

View File

@@ -1,4 +1,4 @@
portSecurity: true
routes: ""
image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.37.0@sha256:9950614571ea77a55925eba0839b6b12c8e5a7a30b8858031a8c6050f261af1a
image: ghcr.io/cozystack/cozystack/kubeovn-plunger:v0.37.3@sha256:c57607c12bb03d2d644a51dab46c0f488f5dc81c9fb84403b4f688e73114e7c2
ovnCentralName: ovn-central

View File

@@ -1,3 +1,3 @@
portSecurity: true
routes: ""
image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.37.0@sha256:7e63205708e607ce2cedfe2a2cafd323ca51e3ebc71244a21ff6f9016c6c87bc
image: ghcr.io/cozystack/cozystack/kubeovn-webhook:v0.37.3@sha256:c0490a48b715f30c606ec4f237043da04f79239ff1afe3f7b3c6ef7a71154274

View File

@@ -2,6 +2,7 @@ kube-ovn:
namespace: cozy-kubeovn
func:
ENABLE_NP: false
ENABLE_LB: false
ipv4:
POD_CIDR: "10.244.0.0/16"
POD_GATEWAY: "10.244.0.1"
@@ -64,4 +65,4 @@ global:
images:
kubeovn:
repository: kubeovn
tag: v1.14.5@sha256:af10da442a0c6dc7df47a0ef752e2eb5c247bb0b43069fdfcb2aa51511185ea2
tag: v1.14.5@sha256:706824bb883de73a7949f1909ed5963084b4ff144426ddc759b67a6fee3b2cb7

View File

@@ -1,3 +1,3 @@
storageClass: replicated
csiDriver:
image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:c8b08084a86251cdd18e237de89b695bca0e4f7eb1f1f6ddc2b903b4d74ea5ff
image: ghcr.io/cozystack/cozystack/kubevirt-csi-driver:0.0.0@sha256:10a265bde566618c801882bb16cd5c6da24314b342bba178c78785364ef53d5f

View File

@@ -0,0 +1,27 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
bin/*
Dockerfile.cross
# Test binary, built with `go test -c`
*.test
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
# Go workspace file
go.work
# Kubernetes Generated files - skip generated files, except for vendored files
!vendor/**/zz_generated.*
# editor and IDE paraphernalia
.idea
.vscode
*.swp
*.swo
*~

View File

@@ -0,0 +1,3 @@
apiVersion: v2
name: cozy-lineage-controller-webhook
version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process

View File

@@ -0,0 +1,18 @@
NAME=lineage-controller-webhook
NAMESPACE=cozy-system
include ../../../scripts/common-envs.mk
include ../../../scripts/package.mk
image: image-lineage-controller-webhook
image-lineage-controller-webhook:
docker buildx build -f images/lineage-controller-webhook/Dockerfile ../../.. \
--tag $(REGISTRY)/lineage-controller-webhook:$(call settag,$(TAG)) \
--cache-from type=registry,ref=$(REGISTRY)/lineage-controller-webhook:latest \
--cache-to type=inline \
--metadata-file images/lineage-controller-webhook.json \
$(BUILDX_ARGS)
IMAGE="$(REGISTRY)/lineage-controller-webhook:$(call settag,$(TAG))@$$(yq e '."containerimage.digest"' images/lineage-controller-webhook.json -o json -r)" \
yq -i '.lineageControllerWebhook.image = strenv(IMAGE)' values.yaml
rm -f images/lineage-controller-webhook.json

View File

@@ -0,0 +1,23 @@
FROM golang:1.24-alpine AS builder
ARG TARGETOS
ARG TARGETARCH
WORKDIR /workspace
COPY go.mod go.sum ./
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH go mod download
COPY api api/
COPY pkg pkg/
COPY cmd cmd/
COPY internal internal/
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH CGO_ENABLED=0 go build -ldflags="-extldflags=-static" -o /lineage-controller-webhook cmd/lineage-controller-webhook/main.go
FROM scratch
COPY --from=builder /lineage-controller-webhook /lineage-controller-webhook
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
ENTRYPOINT ["/lineage-controller-webhook"]

View File

@@ -0,0 +1,45 @@
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: lineage-controller-webhook-selfsigned
namespace: {{ .Release.Namespace }}
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: lineage-controller-webhook-ca
namespace: {{ .Release.Namespace }}
spec:
secretName: lineage-controller-webhook-ca
duration: 43800h # 5 years
commonName: lineage-controller-webhook-ca
issuerRef:
name: lineage-controller-webhook-selfsigned
isCA: true
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: lineage-controller-webhook-ca
namespace: {{ .Release.Namespace }}
spec:
ca:
secretName: lineage-controller-webhook-ca
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: lineage-controller-webhook
namespace: {{ .Release.Namespace }}
spec:
secretName: lineage-controller-webhook-cert
duration: 8760h
renewBefore: 720h
issuerRef:
name: lineage-controller-webhook-ca
commonName: lineage-controller-webhook
dnsNames:
- lineage-controller-webhook
- lineage-controller-webhook.{{ .Release.Namespace }}.svc

View File

@@ -0,0 +1,46 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: lineage-controller-webhook
labels:
app: lineage-controller-webhook
spec:
selector:
matchLabels:
app: lineage-controller-webhook
template:
metadata:
labels:
app: lineage-controller-webhook
spec:
nodeSelector:
node-role.kubernetes.io/control-plane: ""
tolerations:
- key: "node-role.kubernetes.io/control-plane"
operator: "Exists"
effect: "NoSchedule"
- key: "node-role.kubernetes.io/master"
operator: "Exists"
effect: "NoSchedule"
serviceAccountName: lineage-controller-webhook
containers:
- name: lineage-controller-webhook
image: "{{ .Values.lineageControllerWebhook.image }}"
args:
{{- if .Values.lineageControllerWebhook.debug }}
- --zap-log-level=debug
{{- else }}
- --zap-log-level=info
{{- end }}
ports:
- name: webhook
containerPort: 9443
volumeMounts:
- name: webhook-certs
mountPath: /tmp/k8s-webhook-server/serving-certs
readOnly: true
volumes:
- name: webhook-certs
secret:
secretName: lineage-controller-webhook-cert
defaultMode: 0400

View File

@@ -3,7 +3,7 @@ kind: MutatingWebhookConfiguration
metadata:
name: lineage
annotations:
cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/cozystack-controller-webhook
cert-manager.io/inject-ca-from: {{ .Release.Namespace }}/lineage-controller-webhook
labels:
app: cozystack-controller
webhooks:
@@ -12,7 +12,7 @@ webhooks:
sideEffects: None
clientConfig:
service:
name: cozystack-controller
name: lineage-controller-webhook
namespace: {{ .Release.Namespace }}
path: /mutate-lineage
rules:
@@ -40,3 +40,7 @@ webhooks:
values:
- kube-system
- default
objectSelector:
matchExpressions:
- key: internal.cozystack.io/managed-by-cozystack
operator: DoesNotExist

View File

@@ -0,0 +1,12 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: lineage-controller-webhook
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: lineage-controller-webhook
subjects:
- kind: ServiceAccount
name: lineage-controller-webhook
namespace: {{ .Release.Namespace }}

View File

@@ -0,0 +1,8 @@
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: lineage-controller-webhook
rules:
- apiGroups: ['*']
resources: ['*']
verbs: ["get", "list", "watch"]

View File

@@ -0,0 +1,4 @@
kind: ServiceAccount
apiVersion: v1
metadata:
name: lineage-controller-webhook

View File

@@ -1,10 +1,11 @@
apiVersion: v1
kind: Service
metadata:
name: cozystack-controller
name: lineage-controller-webhook
labels:
app: cozystack-controller
app: lineage-controller-webhook
spec:
internalTrafficPolicy: Local
type: ClusterIP
ports:
- port: 443
@@ -12,4 +13,4 @@ spec:
protocol: TCP
name: webhook
selector:
app: cozystack-controller
app: lineage-controller-webhook

View File

@@ -0,0 +1,3 @@
lineageControllerWebhook:
image: ghcr.io/cozystack/cozystack/lineage-controller-webhook:v0.37.3@sha256:794ec4cf3d5ea86e5cbc7d22d94acbba7560f4434f7b3c808a81a4352ec80fcc
debug: false

View File

@@ -1,3 +1,3 @@
objectstorage:
controller:
image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.37.0@sha256:5f2eed05d19ba971806374834cb16ca49282aac76130194c00b213c79ce3e10d"
image: "ghcr.io/cozystack/cozystack/objectstorage-controller:v0.37.3@sha256:5511b39fc4000f538f474d849c506dc7d2dd22561ea92256ea5bde1e84b82eca"

View File

@@ -3,8 +3,8 @@ name: piraeus
description: |
The Piraeus Operator manages software defined storage clusters using LINSTOR in Kubernetes.
type: application
version: 2.9.0
appVersion: "v2.9.0"
version: 2.9.1
appVersion: "v2.9.1"
maintainers:
- name: Piraeus Datastore
url: https://piraeus.io

View File

@@ -1,4 +1,4 @@
# DO NOT EDIT; Automatically created by hack/copy-image-config-to-chart.sh
# DO NOT EDIT; Automatically created by tools/copy-image-config-to-chart.sh
apiVersion: v1
kind: ConfigMap
metadata:
@@ -17,16 +17,16 @@ data:
# quay.io/piraeusdatastore/piraeus-server:v1.24.2
components:
linstor-controller:
tag: v1.31.3
tag: v1.32.3
image: piraeus-server
linstor-satellite:
tag: v1.31.3
tag: v1.32.3
image: piraeus-server
linstor-csi:
tag: v1.8.0
tag: v1.9.0
image: piraeus-csi
drbd-reactor:
tag: v1.8.0
tag: v1.9.0
image: drbd-reactor
ha-controller:
tag: v1.3.0
@@ -35,45 +35,45 @@ data:
tag: v1.0.0
image: drbd-shutdown-guard
ktls-utils:
tag: v1.1.0
tag: v1.2.1
image: ktls-utils
drbd-module-loader:
tag: v9.2.14
tag: v9.2.15
# The special "match" attribute is used to select an image based on the node's reported OS.
# The operator will first check the k8s node's ".status.nodeInfo.osImage" field, and compare it against the list
# here. If one matches, that specific image name will be used instead of the fallback image.
image: drbd9-noble # Fallback image: chose a recent kernel, which can hopefully compile whatever config is actually in use
match:
- osImage: Red Hat Enterprise Linux Server 7\.
image: drbd9-centos7
- osImage: Red Hat Enterprise Linux 8\.
image: drbd9-almalinux8
- osImage: Red Hat Enterprise Linux 9\.
image: drbd9-almalinux9
- osImage: Red Hat Enterprise Linux 10\.
image: drbd9-almalinux10
- osImage: "Red Hat Enterprise Linux CoreOS 41[3-9]"
image: drbd9-almalinux9
- osImage: Red Hat Enterprise Linux CoreOS
image: drbd9-almalinux8
- osImage: CentOS Linux 7
image: drbd9-centos7
- osImage: CentOS Linux 8
image: drbd9-almalinux8
- osImage: AlmaLinux 8
image: drbd9-almalinux8
- osImage: AlmaLinux 9
image: drbd9-almalinux9
- osImage: AlmaLinux 10
image: drbd9-almalinux10
- osImage: Oracle Linux Server 8\.
image: drbd9-almalinux8
- osImage: Oracle Linux Server 9\.
image: drbd9-almalinux9
- osImage: Oracle Linux Server 10\.
image: drbd9-almalinux10
- osImage: Rocky Linux 8
image: drbd9-almalinux8
- osImage: Rocky Linux 9
image: drbd9-almalinux9
- osImage: Ubuntu 18\.04
image: drbd9-bionic
- osImage: Ubuntu 20\.04
image: drbd9-focal
- osImage: Rocky Linux 10
image: drbd9-almalinux10
- osImage: Ubuntu 22\.04
image: drbd9-jammy
- osImage: Ubuntu 24\.04
@@ -82,32 +82,30 @@ data:
image: drbd9-bookworm
- osImage: Debian GNU/Linux 11
image: drbd9-bullseye
- osImage: Debian GNU/Linux 10
image: drbd9-buster
0_sig_storage_images.yaml: |
---
base: registry.k8s.io/sig-storage
components:
csi-attacher:
tag: v4.9.0
tag: v4.10.0
image: csi-attacher
csi-livenessprobe:
tag: v2.16.0
tag: v2.17.0
image: livenessprobe
csi-provisioner:
tag: v5.3.0
image: csi-provisioner
csi-snapshotter:
tag: v8.2.1
tag: v8.3.0
image: csi-snapshotter
csi-resizer:
tag: v1.13.2
tag: v1.14.0
image: csi-resizer
csi-external-health-monitor-controller:
tag: v0.15.0
tag: v0.16.0
image: csi-external-health-monitor-controller
csi-node-driver-registrar:
tag: v2.14.0
tag: v2.15.0
image: csi-node-driver-registrar
{{- range $idx, $value := .Values.imageConfigOverride }}
{{ add $idx 1 }}_helm_override.yaml: |

View File

@@ -1,11 +1,5 @@
{{ if .Values.serviceAccount.create }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "piraeus-operator.serviceAccountName" . }}
labels:
{{- include "piraeus-operator.labels" . | nindent 4 }}
# DO NOT EDIT; Automatically created by tools/copy-rbac-config-to-chart.sh
{{ if .Values.rbac.create }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
@@ -14,448 +8,288 @@ metadata:
labels:
{{- include "piraeus-operator.labels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- configmaps
- events
- persistentvolumes
- secrets
- serviceaccounts
- services
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- configmaps
- pods
- secrets
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- nodes
verbs:
- get
- list
- watch
- apiGroups:
- ""
resources:
- nodes
- persistentvolumeclaims
verbs:
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- persistentvolumeclaims/status
verbs:
- patch
- apiGroups:
- ""
resources:
- pods
verbs:
- delete
- list
- watch
- apiGroups:
- ""
resources:
- pods/eviction
verbs:
- create
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- apps
resources:
- daemonsets
- deployments
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- apps
resources:
- replicasets
verbs:
- get
- apiGroups:
- cert-manager.io
resources:
- certificates
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- events.k8s.io
resources:
- events
verbs:
- create
- get
- list
- patch
- update
- watch
- apiGroups:
- internal.linstor.linbit.com
resources:
- '*'
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- piraeus.io
resources:
- linstorclusters
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- piraeus.io
resources:
- linstorclusters/finalizers
verbs:
- update
- apiGroups:
- piraeus.io
resources:
- linstorclusters/status
verbs:
- get
- patch
- update
- apiGroups:
- piraeus.io
resources:
- linstornodeconnections
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- piraeus.io
resources:
- linstornodeconnections/finalizers
verbs:
- update
- apiGroups:
- piraeus.io
resources:
- linstornodeconnections/status
verbs:
- get
- patch
- update
- apiGroups:
- piraeus.io
resources:
- linstorsatelliteconfigurations
verbs:
- get
- list
- watch
- apiGroups:
- piraeus.io
resources:
- linstorsatelliteconfigurations/status
verbs:
- get
- patch
- update
- apiGroups:
- piraeus.io
resources:
- linstorsatellites
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- piraeus.io
resources:
- linstorsatellites/finalizers
verbs:
- update
- apiGroups:
- piraeus.io
resources:
- linstorsatellites/status
verbs:
- get
- patch
- update
- apiGroups:
- rbac.authorization.k8s.io
resources:
- clusterrolebindings
- clusterroles
- rolebindings
- roles
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- security.openshift.io
resourceNames:
- privileged
resources:
- securitycontextconstraints
verbs:
- use
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshotclasses
- volumesnapshots
verbs:
- get
- list
- watch
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshotcontents
verbs:
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshotcontents/status
verbs:
- patch
- update
- apiGroups:
- storage.k8s.io
resources:
- csidrivers
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- storage.k8s.io
resources:
- csinodes
verbs:
- get
- list
- patch
- watch
- apiGroups:
- storage.k8s.io
resources:
- csistoragecapacities
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- storage.k8s.io
resources:
- storageclasses
verbs:
- get
- list
- watch
- apiGroups:
- storage.k8s.io
resources:
- volumeattachments
verbs:
- delete
- get
- list
- patch
- watch
- apiGroups:
- storage.k8s.io
resources:
- volumeattachments/status
verbs:
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "piraeus-operator.fullname" . }}-manager-rolebinding
labels:
{{- include "piraeus-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: '{{ include "piraeus-operator.fullname" . }}-controller-manager'
subjects:
- kind: ServiceAccount
name: '{{ include "piraeus-operator.serviceAccountName" . }}'
namespace: '{{ .Release.Namespace }}'
{{ end }}
{{ if.Values.rbac.create }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "piraeus-operator.fullname" . }}-proxy-role
labels:
{{- include "piraeus-operator.labels" . | nindent 4 }}
rules:
- apiGroups:
- authentication.k8s.io
resources:
- tokenreviews
verbs:
- create
- apiGroups:
- authorization.k8s.io
resources:
- subjectaccessreviews
verbs:
- create
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "piraeus-operator.fullname" . }}-proxy-rolebinding
labels:
{{- include "piraeus-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: '{{ include "piraeus-operator.fullname" . }}-proxy-role'
subjects:
- kind: ServiceAccount
name: {{ include "piraeus-operator.serviceAccountName" . }}
namespace: '{{ .Release.Namespace }}'
- apiGroups:
- ""
resources:
- configmaps
- events
- persistentvolumes
- pods
- secrets
- serviceaccounts
- services
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- nodes
- persistentvolumeclaims
verbs:
- get
- list
- patch
- update
- watch
- apiGroups:
- ""
resources:
- persistentvolumeclaims/status
verbs:
- patch
- apiGroups:
- ""
resources:
- pods/eviction
verbs:
- create
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- apps
resources:
- daemonsets
- deployments
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- apps
resources:
- replicasets
verbs:
- get
- apiGroups:
- cert-manager.io
resources:
- certificates
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- events.k8s.io
resources:
- events
verbs:
- create
- get
- list
- patch
- update
- watch
- apiGroups:
- internal.linstor.linbit.com
resources:
- '*'
verbs:
- create
- delete
- deletecollection
- get
- list
- patch
- update
- watch
- apiGroups:
- piraeus.io
resources:
- linstorclusters
- linstornodeconnections
- linstorsatellites
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- piraeus.io
resources:
- linstorclusters/finalizers
- linstornodeconnections/finalizers
- linstorsatellites/finalizers
verbs:
- update
- apiGroups:
- piraeus.io
resources:
- linstorclusters/status
- linstornodeconnections/status
- linstorsatelliteconfigurations/status
- linstorsatellites/status
verbs:
- get
- patch
- update
- apiGroups:
- piraeus.io
resources:
- linstorsatelliteconfigurations
verbs:
- get
- list
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
- clusterrolebindings
- clusterroles
- rolebindings
- roles
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- security.openshift.io
resourceNames:
- privileged
resources:
- securitycontextconstraints
verbs:
- use
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshotclasses
- volumesnapshots
verbs:
- get
- list
- watch
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshotcontents
verbs:
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- snapshot.storage.k8s.io
resources:
- volumesnapshotcontents/status
verbs:
- patch
- update
- apiGroups:
- storage.k8s.io
resources:
- csidrivers
- csistoragecapacities
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- storage.k8s.io
resources:
- csinodes
verbs:
- get
- list
- patch
- watch
- apiGroups:
- storage.k8s.io
resources:
- storageclasses
verbs:
- get
- list
- watch
- apiGroups:
- storage.k8s.io
resources:
- volumeattachments
verbs:
- delete
- get
- list
- patch
- watch
- apiGroups:
- storage.k8s.io
resources:
- volumeattachments/status
verbs:
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "piraeus-operator.fullname" . }}-leader-election-role
name: {{ include "piraeus-operator.fullname" . }}-leader-election
labels:
{{- include "piraeus-operator.labels" . | nindent 4 }}
rules:
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "piraeus-operator.fullname" . }}-leader-election-rolebinding
labels:
{{- include "piraeus-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: '{{ include "piraeus-operator.fullname" . }}-leader-election-role'
subjects:
- kind: ServiceAccount
name: {{ include "piraeus-operator.serviceAccountName" . }}
namespace: '{{ .Release.Namespace }}'
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- coordination.k8s.io
resources:
- leases
verbs:
- get
- list
- watch
- create
- update
- patch
- delete
- apiGroups:
- ""
resources:
- events
verbs:
- create
- patch
{{ end }}

View File

@@ -0,0 +1,33 @@
{{ if .Values.rbac.create }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "piraeus-operator.fullname" . }}-leader-election
namespace: {{ .Release.Namespace }}
labels:
{{- include "piraeus-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: {{ include "piraeus-operator.fullname" . }}-leader-election
subjects:
- kind: ServiceAccount
name: {{ include "piraeus-operator.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "piraeus-operator.fullname" . }}-controller-manager
labels:
{{- include "piraeus-operator.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "piraeus-operator.fullname" . }}-controller-manager
subjects:
- kind: ServiceAccount
name: {{ include "piraeus-operator.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{ end }}

View File

@@ -0,0 +1,9 @@
{{ if .Values.serviceAccount.create }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "piraeus-operator.serviceAccountName" . }}
labels:
{{- include "piraeus-operator.labels" . | nindent 4 }}
{{ end }}

View File

@@ -1,6 +1,8 @@
REDIS_OPERATOR_TAG=$(shell grep -F 'ARG VERSION=' images/redis-operator/Dockerfile | cut -f2 -d=)
export NAME=redis-operator
export NAMESPACE=cozy-$(NAME)
include ../../../scripts/common-envs.mk
include ../../../scripts/package.mk
update:
@@ -9,3 +11,16 @@ update:
helm repo update redis-operator
helm pull redis-operator/redis-operator --untar --untardir charts
sed -i '/{{/d' charts/redis-operator/crds/databases.spotahome.com_redisfailovers.yaml
image:
docker buildx build images/redis-operator \
--tag $(REGISTRY)/redis-operator:$(REDIS_OPERATOR_TAG) \
--cache-from type=registry,ref=$(REGISTRY)/redis-operator:latest \
--cache-to type=inline \
--metadata-file images/redis-operator.json \
$(BUILDX_ARGS)
REPOSITORY="$(REGISTRY)/redis-operator" \
yq -i '.redis-operator.image.repository = strenv(REPOSITORY)' values.yaml
TAG=$(REDIS_OPERATOR_TAG)@$$(yq e '."containerimage.digest"' images/redis-operator.json -o json -r) \
yq -i '.redis-operator.image.tag = strenv(TAG)' values.yaml
rm -f images/redis-operator.json

View File

@@ -0,0 +1,27 @@
FROM golang:1.20 AS builder
ARG VERSION=v1.3.0-rc1
ARG TARGETOS
ARG TARGETARCH
WORKDIR /workspace
RUN curl -sSL https://github.com/spotahome/redis-operator/archive/refs/tags/${VERSION}.tar.gz | tar -xzvf- --strip=1
COPY patches /patches
RUN git apply /patches/*.diff
RUN GOOS=$TARGETOS GOARCH=$TARGETARCH VERSION=$VERSION ./scripts/build.sh
FROM alpine:latest
RUN apk --no-cache add \
ca-certificates
COPY --from=builder /workspace/bin/redis-operator /usr/local/bin
RUN addgroup -g 1000 rf && \
adduser -D -u 1000 -G rf rf && \
chown rf:rf /usr/local/bin/redis-operator
USER rf
ENTRYPOINT ["/usr/local/bin/redis-operator"]

View File

@@ -0,0 +1,23 @@
diff --git a/service/k8s/service.go b/service/k8s/service.go
index 712cc4c0..e84afc92 100644
--- a/service/k8s/service.go
+++ b/service/k8s/service.go
@@ -10,6 +10,7 @@ import (
"github.com/spotahome/redis-operator/log"
"github.com/spotahome/redis-operator/metrics"
+ "github.com/spotahome/redis-operator/operator/redisfailover/util"
)
// Service the ServiceAccount service that knows how to interact with k8s to manage them
@@ -95,6 +96,10 @@ func (s *ServiceService) CreateOrUpdateService(namespace string, service *corev1
// namespace is our spec(https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#concurrency-control-and-consistency),
// we will replace the current namespace state.
service.ResourceVersion = storedService.ResourceVersion
+ newLabels := util.MergeLabels(storedService.GetLabels(), service.GetLabels())
+ newAnnotations := util.MergeAnnotations(storedService.GetAnnotations(), service.GetAnnotations())
+ service.SetLabels(newLabels)
+ service.SetAnnotations(newAnnotations)
return s.UpdateService(namespace, service)
}

View File

@@ -1,3 +1,4 @@
redis-operator:
image:
tag: v1.3.0-rc1
repository: ghcr.io/cozystack/cozystack/redis-operator
tag: v1.3.0-rc1@sha256:a4012e6a1b5daaedb57cc27edfdbff52124de4164b5ec0ee53c5ce5710ef4c25

View File

@@ -1,12 +1,29 @@
NAME=seaweedfs-system
export NAME=seaweedfs-system
include ../../../scripts/common-envs.mk
include ../../../scripts/package.mk
update:
rm -rf charts
mkdir -p charts
curl -sSL https://github.com/seaweedfs/seaweedfs/archive/refs/heads/master.tar.gz | \
tar xzvf - --strip 3 -C charts seaweedfs-master/k8s/charts/seaweedfs
version=$$(git ls-remote --tags --sort="v:refname" https://github.com/seaweedfs/seaweedfs | grep -v '\^{}' | grep 'refs/tags/[0-9]' | awk -F'/' 'END{print $$3}') && \
curl -sSL https://github.com/seaweedfs/seaweedfs/archive/refs/tags/$${version}.tar.gz | \
tar xzvf - --strip 3 -C charts seaweedfs-$${version}/k8s/charts/seaweedfs && \
sed -i.bak "/ARG VERSION/ s|=.*|=$${version}|g" images/seaweedfs/Dockerfile && \
rm -f images/seaweedfs/Dockerfile.bak
patch --no-backup-if-mismatch -p4 < patches/resize-api-server-annotation.diff
patch --no-backup-if-mismatch -p4 < patches/fix-volume-servicemonitor.patch
#patch --no-backup-if-mismatch -p4 < patches/retention-policy-delete.yaml
image:
docker buildx build images/seaweedfs \
--tag $(REGISTRY)/seaweedfs:$(call settag,$(TAG)) \
--cache-from type=registry,ref=$(REGISTRY)/seaweedfs:latest \
--cache-to type=inline \
--metadata-file images/seaweedfs.json \
$(BUILDX_ARGS)
REGISTRY="$(REGISTRY)" \
yq -i '.seaweedfs.image.registry = strenv(REGISTRY)' values.yaml
TAG=$(TAG)@$$(yq e '."containerimage.digest"' images/seaweedfs.json -o json -r) \
yq -i '.seaweedfs.image.tag = strenv(TAG)' values.yaml
yq -i '.global.imageName = "seaweedfs"' values.yaml
rm -f images/seaweedfs.json

View File

@@ -1,6 +1,6 @@
apiVersion: v1
description: SeaweedFS
name: seaweedfs
appVersion: "3.97"
appVersion: "3.99"
# Dev note: Trigger a helm chart release by `git tag -a helm-<version>`
version: 4.0.397
version: 4.0.399

View File

@@ -79,6 +79,12 @@ spec:
image: {{ template "master.image" . }}
imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }}
env:
{{- /* Determine default cluster alias and the corresponding env var keys to avoid conflicts */}}
{{- $envMerged := merge (.Values.global.extraEnvironmentVars | default dict) (.Values.allInOne.extraEnvironmentVars | default dict) }}
{{- $clusterDefault := default "sw" (index $envMerged "WEED_CLUSTER_DEFAULT") }}
{{- $clusterUpper := upper $clusterDefault }}
{{- $clusterMasterKey := printf "WEED_CLUSTER_%s_MASTER" $clusterUpper }}
{{- $clusterFilerKey := printf "WEED_CLUSTER_%s_FILER" $clusterUpper }}
- name: POD_IP
valueFrom:
fieldRef:
@@ -95,6 +101,7 @@ spec:
value: "{{ template "seaweedfs.name" . }}"
{{- if .Values.allInOne.extraEnvironmentVars }}
{{- range $key, $value := .Values.allInOne.extraEnvironmentVars }}
{{- if and (ne $key $clusterMasterKey) (ne $key $clusterFilerKey) }}
- name: {{ $key }}
{{- if kindIs "string" $value }}
value: {{ $value | quote }}
@@ -104,8 +111,10 @@ spec:
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.global.extraEnvironmentVars }}
{{- range $key, $value := .Values.global.extraEnvironmentVars }}
{{- if and (ne $key $clusterMasterKey) (ne $key $clusterFilerKey) }}
- name: {{ $key }}
{{- if kindIs "string" $value }}
value: {{ $value | quote }}
@@ -115,6 +124,12 @@ spec:
{{- end }}
{{- end }}
{{- end }}
{{- end }}
# Inject computed cluster endpoints for the default cluster
- name: {{ $clusterMasterKey }}
value: {{ include "seaweedfs.cluster.masterAddress" . | quote }}
- name: {{ $clusterFilerKey }}
value: {{ include "seaweedfs.cluster.filerAddress" . | quote }}
command:
- "/bin/sh"
- "-ec"

View File

@@ -15,7 +15,6 @@ spec:
selector:
matchLabels:
app.kubernetes.io/name: {{ template "seaweedfs.name" . }}
helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/component: objectstorage-provisioner
template:

View File

@@ -28,8 +28,8 @@ spec:
rules:
- http:
paths:
- path: /sw-filer/?(.*)
pathType: ImplementationSpecific
- path: {{ .Values.filer.ingress.path | quote }}
pathType: {{ .Values.filer.ingress.pathType | quote }}
backend:
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
service:

View File

@@ -28,8 +28,8 @@ spec:
rules:
- http:
paths:
- path: /sw-master/?(.*)
pathType: ImplementationSpecific
- path: {{ .Values.master.ingress.path | quote }}
pathType: {{ .Values.master.ingress.pathType | quote }}
backend:
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
service:

View File

@@ -27,8 +27,8 @@ spec:
rules:
- http:
paths:
- path: /
pathType: ImplementationSpecific
- path: {{ .Values.s3.ingress.path | quote }}
pathType: {{ .Values.s3.ingress.pathType | quote }}
backend:
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }}
service:

View File

@@ -96,13 +96,16 @@ Inject extra environment vars in the format key:value, if populated
{{/* Computes the container image name for all components (if they are not overridden) */}}
{{- define "common.image" -}}
{{- $registryName := default .Values.image.registry .Values.global.registry | toString -}}
{{- $repositoryName := .Values.image.repository | toString -}}
{{- $repositoryName := default .Values.image.repository .Values.global.repository | toString -}}
{{- $name := .Values.global.imageName | toString -}}
{{- $tag := default .Chart.AppVersion .Values.image.tag | toString -}}
{{- if $repositoryName -}}
{{- $name = printf "%s/%s" (trimSuffix "/" $repositoryName) (base $name) -}}
{{- end -}}
{{- if $registryName -}}
{{- printf "%s/%s%s:%s" $registryName $repositoryName $name $tag -}}
{{- printf "%s/%s:%s" $registryName $name $tag -}}
{{- else -}}
{{- printf "%s%s:%s" $repositoryName $name $tag -}}
{{- printf "%s:%s" $name $tag -}}
{{- end -}}
{{- end -}}
@@ -219,3 +222,27 @@ or generate a new random password if it doesn't exist.
{{- randAlphaNum $length -}}
{{- end -}}
{{- end -}}
{{/*
Compute the master service address to be used in cluster env vars.
If allInOne is enabled, point to the all-in-one service; otherwise, point to the master service.
*/}}
{{- define "seaweedfs.cluster.masterAddress" -}}
{{- $serviceNameSuffix := "-master" -}}
{{- if .Values.allInOne.enabled -}}
{{- $serviceNameSuffix = "-all-in-one" -}}
{{- end -}}
{{- printf "%s%s.%s:%d" (include "seaweedfs.name" .) $serviceNameSuffix .Release.Namespace (int .Values.master.port) -}}
{{- end -}}
{{/*
Compute the filer service address to be used in cluster env vars.
If allInOne is enabled, point to the all-in-one service; otherwise, point to the filer-client service.
*/}}
{{- define "seaweedfs.cluster.filerAddress" -}}
{{- $serviceNameSuffix := "-filer-client" -}}
{{- if .Values.allInOne.enabled -}}
{{- $serviceNameSuffix = "-all-in-one" -}}
{{- end -}}
{{- printf "%s%s.%s:%d" (include "seaweedfs.name" .) $serviceNameSuffix .Release.Namespace (int .Values.filer.port) -}}
{{- end -}}

View File

@@ -21,9 +21,9 @@ metadata:
{{- with $.Values.global.monitoring.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if $.Values.volume.annotations }}
{{- with $volume.annotations }}
annotations:
{{- toYaml $.Values.volume.annotations | nindent 4 }}
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
endpoints:

View File

@@ -88,6 +88,9 @@ spec:
- name: {{ $dir.name }}
mountPath: /{{ $dir.name }}
{{- end }}
{{- if $volume.containerSecurityContext.enabled }}
securityContext: {{- omit $volume.containerSecurityContext "enabled" | toYaml | nindent 12 }}
{{- end }}
{{- end }}
{{- if $volume.initContainers }}
{{ tpl (printf "{{ $volumeName := \"%s\" }}%s" $volumeName $volume.initContainers) $ | indent 8 | trim }}

View File

@@ -3,6 +3,7 @@
global:
createClusterRole: true
registry: ""
# if repository is set, it overrides the namespace part of imageName
repository: ""
imageName: chrislusf/seaweedfs
imagePullPolicy: IfNotPresent
@@ -201,8 +202,7 @@ master:
# nodeSelector labels for master pod assignment, formatted as a muli-line string.
# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
# Example:
nodeSelector: |
kubernetes.io/arch: amd64
nodeSelector: ""
# nodeSelector: |
# sw-backend: "true"
@@ -238,6 +238,8 @@ master:
className: "nginx"
# host: false for "*" hostname
host: "master.seaweedfs.local"
path: "/sw-master/?(.*)"
pathType: ImplementationSpecific
annotations:
nginx.ingress.kubernetes.io/auth-type: "basic"
nginx.ingress.kubernetes.io/auth-secret: "default/ingress-basic-auth-secret"
@@ -478,8 +480,7 @@ volume:
# nodeSelector labels for server pod assignment, formatted as a muli-line string.
# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
# Example:
nodeSelector: |
kubernetes.io/arch: amd64
nodeSelector: ""
# nodeSelector: |
# sw-volume: "true"
@@ -735,8 +736,7 @@ filer:
# nodeSelector labels for server pod assignment, formatted as a muli-line string.
# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
# Example:
nodeSelector: |
kubernetes.io/arch: amd64
nodeSelector: ""
# nodeSelector: |
# sw-backend: "true"
@@ -772,6 +772,8 @@ filer:
className: "nginx"
# host: false for "*" hostname
host: "seaweedfs.cluster.local"
path: "/sw-filer/?(.*)"
pathType: ImplementationSpecific
annotations:
nginx.ingress.kubernetes.io/backend-protocol: GRPC
nginx.ingress.kubernetes.io/auth-type: "basic"
@@ -871,7 +873,7 @@ filer:
# anonymousRead: false
s3:
enabled: false
enabled: true
imageOverride: null
restartPolicy: null
replicas: 1
@@ -932,8 +934,7 @@ s3:
# nodeSelector labels for server pod assignment, formatted as a muli-line string.
# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
# Example:
nodeSelector: |
kubernetes.io/arch: amd64
nodeSelector: ""
# nodeSelector: |
# sw-backend: "true"
@@ -975,6 +976,11 @@ s3:
extraEnvironmentVars:
# Custom command line arguments to add to the s3 command
# Example to fix connection idle seconds:
extraArgs: ["-idleTimeout=30"]
# extraArgs: []
# used to configure livenessProbe on s3 containers
#
livenessProbe:
@@ -1006,6 +1012,8 @@ s3:
className: "nginx"
# host: false for "*" hostname
host: "seaweedfs.cluster.local"
path: "/"
pathType: Prefix
# additional ingress annotations for the s3 endpoint
annotations: {}
tls: []
@@ -1051,8 +1059,7 @@ sftp:
annotations: {}
resources: {}
tolerations: ""
nodeSelector: |
kubernetes.io/arch: amd64
nodeSelector: ""
priorityClassName: ""
serviceAccountName: ""
podSecurityContext: {}
@@ -1179,8 +1186,7 @@ allInOne:
# nodeSelector labels for master pod assignment, formatted as a muli-line string.
# ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector
nodeSelector: |
kubernetes.io/arch: amd64
nodeSelector: ""
# Used to assign priority to master pods
# ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/

View File

@@ -0,0 +1,2 @@
ARG VERSION=3.99
FROM chrislusf/seaweedfs:${VERSION}

View File

@@ -1,15 +0,0 @@
diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-servicemonitor.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-servicemonitor.yaml
--- a/packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-servicemonitor.yaml (revision 8951bc13d7d02b5e6982a239570ed58ed7cb025a)
+++ b/packages/system/seaweedfs/charts/seaweedfs/templates/volume/volume-servicemonitor.yaml (revision fa4fff2292c4b79a92db5cd654a3c6bf590252a6)
@@ -21,9 +21,9 @@
{{- with $.Values.global.monitoring.additionalLabels }}
{{- toYaml . | nindent 4 }}
{{- end }}
-{{- if .Values.volume.annotations }}
+{{- if $.Values.volume.annotations }}
annotations:
- {{- toYaml .Values.volume.annotations | nindent 4 }}
+ {{- toYaml $.Values.volume.annotations | nindent 4 }}
{{- end }}
spec:
endpoints:

View File

@@ -1,12 +1,16 @@
global:
enableSecurity: true
serviceAccountName: "tenant-foo-seaweedfs"
imageName: "seaweedfs"
extraEnvironmentVars:
WEED_CLUSTER_SW_MASTER: "seaweedfs-master:9333"
WEED_CLUSTER_SW_FILER: "seaweedfs-filer-client:8888"
monitoring:
enabled: true
seaweedfs:
image:
tag: "latest@sha256:944e9bff98b088773847270238b63ce57dc5291054814d08e0226a139b3affb2"
registry: ghcr.io/cozystack/cozystack
master:
volumeSizeLimitMB: 30000
replicas: 3
@@ -83,7 +87,7 @@ seaweedfs:
existingConfigSecret: null
auditLogConfig: {}
s3:
enabled: true
enabled: false
extraArgs:
- -idleTimeout=60
enableAuth: false
@@ -120,7 +124,7 @@ seaweedfs:
bucketClassName: "seaweedfs"
region: ""
sidecar:
image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.37.0@sha256:f166f09cdc9cdbb758209883819ab8261a3793bc1d7a6b6685efd5a2b2930847"
image: "ghcr.io/cozystack/cozystack/objectstorage-sidecar:v0.37.3@sha256:9d5cf652534f9e59ad181740f146439ef04ed20ffee958141d66897fc192604f"
certificates:
commonName: "SeaweedFS CA"
ipAddresses: []

View File

@@ -13,3 +13,6 @@ velero:
volumeSnapshotLocation: null
namespace: cozy-velero
features: EnableCSI
# Increase timeout for item operations to 24 hours to prevent timeouts
# during backups of very large volumes. The Velero default is 4 hours.
defaultItemOperationTimeout: 24h

View File

@@ -138,8 +138,7 @@ func (c completedConfig) New() (*CozyServer, error) {
coreV1alpha1Storage["tenantnamespaces"] = cozyregistry.RESTInPeace(
tenantnamespacestorage.NewREST(
clientset.CoreV1(),
clientset.AuthorizationV1(),
20,
clientset.RbacV1(),
),
)
coreV1alpha1Storage["tenantsecrets"] = cozyregistry.RESTInPeace(

View File

@@ -7,13 +7,10 @@ package tenantnamespace
import (
"context"
"fmt"
"math"
"net/http"
"strings"
"sync"
"time"
authorizationv1 "k8s.io/api/authorization/v1"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metainternal "k8s.io/apimachinery/pkg/apis/meta/internalversion"
@@ -24,9 +21,8 @@ import (
"k8s.io/apimachinery/pkg/watch"
"k8s.io/apiserver/pkg/endpoints/request"
"k8s.io/apiserver/pkg/registry/rest"
authorizationv1client "k8s.io/client-go/kubernetes/typed/authorization/v1"
corev1client "k8s.io/client-go/kubernetes/typed/core/v1"
"k8s.io/klog/v2"
rbacv1client "k8s.io/client-go/kubernetes/typed/rbac/v1"
corev1alpha1 "github.com/cozystack/cozystack/pkg/apis/core/v1alpha1"
)
@@ -50,21 +46,18 @@ var (
)
type REST struct {
core corev1client.CoreV1Interface
authClient authorizationv1client.AuthorizationV1Interface
maxWorkers int
gvr schema.GroupVersionResource
core corev1client.CoreV1Interface
rbac rbacv1client.RbacV1Interface
gvr schema.GroupVersionResource
}
func NewREST(
coreCli corev1client.CoreV1Interface,
authCli authorizationv1client.AuthorizationV1Interface,
maxWorkers int,
rbacCli rbacv1client.RbacV1Interface,
) *REST {
return &REST{
core: coreCli,
authClient: authCli,
maxWorkers: maxWorkers,
core: coreCli,
rbac: rbacCli,
gvr: schema.GroupVersionResource{
Group: corev1alpha1.GroupName,
Version: "v1alpha1",
@@ -271,76 +264,65 @@ func (r *REST) filterAccessible(
ctx context.Context,
names []string,
) ([]string, error) {
workers := int(math.Min(float64(r.maxWorkers), float64(len(names))))
type job struct{ name string }
type res struct {
name string
allowed bool
err error
u, ok := request.UserFrom(ctx)
if !ok {
return []string{}, fmt.Errorf("user missing in context")
}
jobs := make(chan job, workers)
out := make(chan res, workers)
var wg sync.WaitGroup
for i := 0; i < workers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
for j := range jobs {
ok, err := r.sar(ctx, j.name)
out <- res{j.name, ok, err}
}
}()
groups := make(map[string]struct{})
for _, group := range u.GetGroups() {
groups[group] = struct{}{}
}
go func() { wg.Wait(); close(out) }()
go func() {
for _, n := range names {
jobs <- job{n}
}
close(jobs)
}()
var allowed []string
for r := range out {
if r.err != nil {
klog.Errorf("SAR failed for %s: %v", r.name, r.err)
if _, ok = groups["system:masters"]; ok {
return names, nil
}
if _, ok = groups["cozystack-cluster-admin"]; ok {
return names, nil
}
nameSet := make(map[string]struct{})
for _, name := range names {
nameSet[name] = struct{}{}
}
rbs, err := r.rbac.RoleBindings("").List(ctx, metav1.ListOptions{})
if err != nil {
return []string{}, fmt.Errorf("failed to list rolebindings")
}
allowedNameSet := make(map[string]struct{})
for i := range rbs.Items {
if _, ok := allowedNameSet[rbs.Items[i].Namespace]; ok {
continue
}
if r.allowed {
allowed = append(allowed, r.name)
if _, ok := nameSet[rbs.Items[i].Namespace]; !ok {
continue
}
subjectLoop:
for j := range rbs.Items[i].Subjects {
subj := rbs.Items[i].Subjects[j]
switch subj.Kind {
case "Group":
if _, ok = groups[subj.Name]; ok {
allowedNameSet[rbs.Items[i].Namespace] = struct{}{}
break subjectLoop
}
case "User":
if subj.Name == u.GetName() {
allowedNameSet[rbs.Items[i].Namespace] = struct{}{}
break subjectLoop
}
case "ServiceAccount":
if u.GetName() == fmt.Sprintf("system:serviceaccount:%s:%s", subj.Namespace, subj.Name) {
allowedNameSet[rbs.Items[i].Namespace] = struct{}{}
break subjectLoop
}
}
}
}
allowed := make([]string, 0, len(allowedNameSet))
for name := range allowedNameSet {
allowed = append(allowed, name)
}
return allowed, nil
}
func (r *REST) sar(ctx context.Context, ns string) (bool, error) {
u, ok := request.UserFrom(ctx)
if !ok || u == nil {
return false, fmt.Errorf("user missing in context")
}
sar := &authorizationv1.SubjectAccessReview{
Spec: authorizationv1.SubjectAccessReviewSpec{
User: u.GetName(),
Groups: u.GetGroups(),
ResourceAttributes: &authorizationv1.ResourceAttributes{
Group: "cozystack.io",
Resource: "workloadmonitors",
Verb: "get",
Namespace: ns,
},
},
}
rsp, err := r.authClient.SubjectAccessReviews().
Create(ctx, sar, metav1.CreateOptions{})
if err != nil {
return false, err
}
return rsp.Status.Allowed, nil
}
// -----------------------------------------------------------------------------
// Boiler-plate
// -----------------------------------------------------------------------------

View File

@@ -26,8 +26,17 @@ cozypkg -n cozy-system -C packages/system/cozystack-resource-definition-crd appl
cozypkg -n cozy-system -C packages/system/cozystack-resource-definitions apply cozystack-resource-definitions --plain
cozypkg -n cozy-system -C packages/system/cozystack-api apply cozystack-api --plain
helm upgrade --install -n cozy-system cozystack-controller ./packages/system/cozystack-controller/ --take-ownership
helm upgrade --install -n cozy-system lineage-controller-webhook ./packages/system/lineage-controller-webhook/ --take-ownership
sleep 5
kubectl delete ns cozy-lineage-webhook-test --ignore-not-found && kubectl create ns cozy-lineage-webhook-test
cleanup_test_ns() {
kubectl delete ns cozy-lineage-webhook-test --ignore-not-found
}
trap cleanup_test_ns ERR
timeout 60 sh -c 'until kubectl -n cozy-lineage-webhook-test create service clusterip lineage-webhook-test --clusterip="None" --dry-run=server; do sleep 1; done'
cleanup_test_ns
kubectl wait deployment/cozystack-api -n cozy-system --timeout=4m --for=condition=available || exit 1
kubectl wait deployment/cozystack-controller -n cozy-system --timeout=4m --for=condition=available || exit 1