Compare commits
16 Commits
897ce79223
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| dc90b67880 | |||
| 539755e05f | |||
| cda03ae37d | |||
| 36e11b342b | |||
| 39f027d416 | |||
| 14463a5dbe | |||
| da5d944430 | |||
|
|
66f38d90ee | ||
|
|
2c32bd6a56 | ||
|
|
953d03b3e1 | ||
|
|
84d4ace0a7 | ||
|
|
bbb9ab2eee | ||
|
|
094f11cf29 | ||
|
|
e171db7e71 | ||
|
|
b374e79755 | ||
|
|
6c884db44c |
79
.gitea/workflows/build-and-publish.yaml
Normal file
79
.gitea/workflows/build-and-publish.yaml
Normal file
@@ -0,0 +1,79 @@
|
||||
name: Build and Publish
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
env:
|
||||
CHART_NAME: ${{ github.event.repository.name }}
|
||||
IMAGE_NAME: ${{ github.event.repository.name }}
|
||||
jobs:
|
||||
build-release:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- uses: DeterminateSystems/determinate-nix-action@v3
|
||||
|
||||
- uses: DeterminateSystems/flake-checker-action@main
|
||||
with:
|
||||
flake-lock-path: ./build/flake.lock
|
||||
|
||||
- name: Setup Attic cache
|
||||
uses: ryanccn/attic-action@v0
|
||||
with:
|
||||
endpoint: ${{ secrets.ATTIC_ENDPOINT }}
|
||||
cache: ${{ secrets.ATTIC_CACHE }}
|
||||
token: ${{ secrets.ATTIC_TOKEN }}
|
||||
|
||||
- name: Build Docker Image via Nix Flake
|
||||
run: |
|
||||
nix build ./build#dockerImage --print-build-logs
|
||||
docker load < result
|
||||
|
||||
- name: Log in to Gitea Container Registry
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ github.server_url }}
|
||||
username: ${{ secrets.CI_USER }}
|
||||
password: ${{ secrets.CI_PASSWORD }}
|
||||
|
||||
- name: Tag and Push Docker Image
|
||||
run: |
|
||||
VERSION=${{ github.run_number }}
|
||||
|
||||
# Strip https from server URL
|
||||
REGISTRY=${GITHUB_SERVER_URL#https://}
|
||||
|
||||
TARGET_IMAGE=$REGISTRY/${{ github.repository_owner }}/${{ env.IMAGE_NAME }}
|
||||
|
||||
# Auto-detect the built image name (better version)
|
||||
SOURCE_IMAGE=$(docker load < result | awk '{print $3}')
|
||||
|
||||
docker tag $SOURCE_IMAGE $TARGET_IMAGE:$VERSION
|
||||
docker tag $SOURCE_IMAGE $TARGET_IMAGE:latest
|
||||
docker push $TARGET_IMAGE:$VERSION
|
||||
docker push $TARGET_IMAGE:latest
|
||||
|
||||
- name: Setup Helm
|
||||
uses: azure/setup-helm@v4
|
||||
with:
|
||||
version: v3.14.0
|
||||
|
||||
- name: Package Helm Chart
|
||||
run: |
|
||||
VERSION=${{ github.run_number }}
|
||||
helm package ops/chart --version $VERSION --app-version $VERSION
|
||||
|
||||
- name: Push Helm Chart to Gitea Registry
|
||||
run: |
|
||||
VERSION=${{ github.run_number }}
|
||||
CHART_FILE=${{ env.CHART_NAME }}-${VERSION}.tgz
|
||||
|
||||
curl -f --user "${{ secrets.CI_USER }}:${{ secrets.CI_PASSWORD }}" \
|
||||
-X POST \
|
||||
--upload-file ./$CHART_FILE \
|
||||
"${{ github.server_url }}/api/packages/${{ github.repository_owner }}/helm/api/charts"
|
||||
@@ -28,8 +28,8 @@ BUNDLE_METADATA_OPTS ?= $(BUNDLE_CHANNELS) $(BUNDLE_DEFAULT_CHANNEL)
|
||||
# This variable is used to construct full image tags for bundle and catalog images.
|
||||
#
|
||||
# For example, running 'make bundle-build bundle-push catalog-build catalog-push' will build and push both
|
||||
# topmanage.com/src-bundle:$VERSION and topmanage.com/src-catalog:$VERSION.
|
||||
IMAGE_TAG_BASE ?= topmanage.com/src
|
||||
# github.com/src-bundle:$VERSION and github.com/src-catalog:$VERSION.
|
||||
IMAGE_TAG_BASE ?= github.com/src
|
||||
|
||||
# BUNDLE_IMG defines the image:tag used for the bundle.
|
||||
# You can use it as an arg. (E.g make bundle-build BUNDLE_IMG=<some-registry>/<project-name-bundle>:<tag>)
|
||||
32
PROJECT
Normal file
32
PROJECT
Normal file
@@ -0,0 +1,32 @@
|
||||
# Code generated by tool. DO NOT EDIT.
|
||||
# This file is used to track the info used to scaffold your project
|
||||
# and allow the plugins properly work.
|
||||
# More info: https://book.kubebuilder.io/reference/project-config.html
|
||||
domain: github.com
|
||||
layout:
|
||||
- go.kubebuilder.io/v4
|
||||
plugins:
|
||||
manifests.sdk.operatorframework.io/v2: {}
|
||||
scorecard.sdk.operatorframework.io/v2: {}
|
||||
projectName: src
|
||||
repo: gitea.corredorconect.com/software-engineering/zitadel-k8s-operator
|
||||
resources:
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: github.com
|
||||
group: zitadel
|
||||
kind: Cluster
|
||||
path: gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1
|
||||
version: v1alpha1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: github.com
|
||||
group: zitadel
|
||||
kind: Instance
|
||||
path: gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1
|
||||
version: v1alpha1
|
||||
version: "3"
|
||||
@@ -1,4 +1,4 @@
|
||||
# src
|
||||
# zitadel K8S operator
|
||||
// TODO(user): Add simple overview of use/purpose
|
||||
|
||||
## Description
|
||||
@@ -22,18 +22,18 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
// Image defines the container image name and tag.
|
||||
type Image struct {
|
||||
Name string `json:"name"`
|
||||
Tag string `json:"tag"`
|
||||
}
|
||||
|
||||
// Password holds a reference to a Kubernetes Secret key containing a password.
|
||||
type Password struct {
|
||||
SecretKeyRef corev1.SecretKeySelector `json:"secretRef"`
|
||||
}
|
||||
|
||||
// SMTPConfig configures an SMTP provider.
|
||||
type SMTPConfig struct {
|
||||
SenderAddress string `json:"senderAddress"`
|
||||
SenderName string `json:"senderName"`
|
||||
@@ -45,6 +45,7 @@ type SMTPConfig struct {
|
||||
ReplyToAddress *string `json:"replyToAddress,omitempty"`
|
||||
}
|
||||
|
||||
// DomainSettings configures domain-related behaviour.
|
||||
type DomainSettings struct {
|
||||
// +kubebuilder:default=true
|
||||
UserLoginMustBeDomain bool `json:"userLoginMustBeDomain"`
|
||||
@@ -54,61 +55,65 @@ type DomainSettings struct {
|
||||
SMTPSenderAddressMatchesInstanceDomain bool `json:"smtpSenderAddressMatchesInstanceDomain"`
|
||||
}
|
||||
|
||||
// ZitadelClusterSpec defines the desired state of ZitadelCluster
|
||||
type ZitadelClusterSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// +kubebuilder:default="DEFAULT"
|
||||
FirstOrgName string `json:"firstOrgName"`
|
||||
DomainSettings DomainSettings `json:"domainSettings"`
|
||||
SMTPConfig SMTPConfig `json:"smtpConfig"`
|
||||
// ClusterSpec defines the desired state of Cluster.
|
||||
type ClusterSpec struct {
|
||||
// Host is the external hostname used to reach Zitadel.
|
||||
Host string `json:"host"`
|
||||
|
||||
// ExternalPort is the port exposed externally.
|
||||
// +kubebuilder:default=443
|
||||
ExternalPort int64 `json:"externalPort"`
|
||||
|
||||
// ExternalSecure indicates whether TLS is used on the external endpoint.
|
||||
// +kubebuilder:default=true
|
||||
ExternalSecure bool `json:"externalSecure"`
|
||||
|
||||
// Image is the Zitadel container image to deploy.
|
||||
Image Image `json:"image"`
|
||||
|
||||
// Resources defines compute resource requests and limits for the Zitadel pods.
|
||||
Resources corev1.ResourceRequirements `json:"resources"`
|
||||
|
||||
// PostgreSQLClusterRef references the backing PostgreSQL cluster.
|
||||
PostgreSQLClusterRef PostgreSQLClusterRef `json:"postgresClusterRef"`
|
||||
// +kubebuilder:validation:Enum=demo;trial;staging;productive;testing
|
||||
Purpose string `json:"purpose"`
|
||||
// PodAnnotations to add to the Pods metadata.
|
||||
|
||||
// Replicas is the desired number of Zitadel pods.
|
||||
// +kubebuilder:default=3
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podCount"}
|
||||
Replicas int32 `json:"replicas,omitempty"`
|
||||
|
||||
// PodAnnotations are extra annotations added to each Zitadel Pod.
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
PodAnnotations map[string]string `json:"podAnnotations,omitempty"`
|
||||
// ServiceAnnotations to add to the service metadata.
|
||||
|
||||
// ServiceAnnotations are extra annotations added to the Zitadel Service.
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
ServiceAnnotations map[string]string `json:"serviceAnnotations,omitempty"`
|
||||
// +kubebuilder:default=3
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podCount"}
|
||||
Replicas int32 `json:"replicas,omitempty"`
|
||||
RootTLSSecret corev1.SecretReference `json:"rootTLSSecret"`
|
||||
}
|
||||
|
||||
// ZitadelClusterStatus defines the observed state of ZitadelCluster
|
||||
type ZitadelClusterStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// ClusterStatus defines the observed state of Cluster.
|
||||
type ClusterStatus struct {
|
||||
// Conditions store the status conditions of the Cluster.
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
|
||||
// Replicas is the current number of running Zitadel pods.
|
||||
// +kubebuilder:default=3
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podCount"}
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podCount"}
|
||||
Replicas int32 `json:"replicas,omitempty"`
|
||||
// +kubebuilder:default=""
|
||||
DefaultInstanceId string `json:"defaultInstanceId"`
|
||||
// +kubebuilder:default=""
|
||||
SMTPProviderId string `json:"smtpProviderId"`
|
||||
}
|
||||
|
||||
// SetCondition sets a status condition
|
||||
func (s *ZitadelClusterStatus) SetCondition(condition metav1.Condition) {
|
||||
// SetCondition sets a status condition on the Cluster.
|
||||
func (s *ClusterStatus) SetCondition(condition metav1.Condition) {
|
||||
if s.Conditions == nil {
|
||||
s.Conditions = make([]metav1.Condition, 0)
|
||||
}
|
||||
meta.SetStatusCondition(&s.Conditions, condition)
|
||||
}
|
||||
|
||||
func (s *ZitadelClusterStatus) IsReady() bool {
|
||||
// IsReady returns true when the cluster has reached the Ready condition.
|
||||
func (s *ClusterStatus) IsReady() bool {
|
||||
for _, c := range s.Conditions {
|
||||
if c.Type == ConditionTypeReady && c.Status == metav1.ConditionTrue {
|
||||
return true
|
||||
@@ -117,35 +122,40 @@ func (s *ZitadelClusterStatus) IsReady() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (s *ZitadelClusterStatus) FillWithDefaults(zitadel *ZitadelCluster) {
|
||||
// FillWithDefaults populates default values on the Cluster status.
|
||||
func (s *ClusterStatus) FillWithDefaults(_ *Cluster) {
|
||||
// (Haim ;^D): No defaults yet
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
//+kubebuilder:printcolumn:name="Replicas",type=integer,JSONPath=`.status.replicas`
|
||||
//+kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status`
|
||||
//+kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
|
||||
// ZitadelCluster is the Schema for the zitadelclusters API
|
||||
type ZitadelCluster struct {
|
||||
// Cluster is the Schema for the clusters API.
|
||||
type Cluster struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ZitadelClusterSpec `json:"spec,omitempty"`
|
||||
Status ZitadelClusterStatus `json:"status,omitempty"`
|
||||
Spec ClusterSpec `json:"spec,omitempty"`
|
||||
Status ClusterStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (m *ZitadelCluster) SetDefaults() {
|
||||
// SetDefaults populates default values on the Cluster spec.
|
||||
func (m *Cluster) SetDefaults() {
|
||||
// (Haim ;^D): No defaults yet
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// ZitadelClusterList contains a list of ZitadelCluster
|
||||
type ZitadelClusterList struct {
|
||||
// ClusterList contains a list of Cluster.
|
||||
type ClusterList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []ZitadelCluster `json:"items"`
|
||||
Items []Cluster `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&ZitadelCluster{}, &ZitadelClusterList{})
|
||||
SchemeBuilder.Register(&Cluster{}, &ClusterList{})
|
||||
}
|
||||
@@ -16,7 +16,7 @@ limitations under the License.
|
||||
|
||||
// Package v1alpha1 contains API Schema definitions for the zitadel v1alpha1 API group
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=zitadel.topmanage.com
|
||||
// +groupName=zitadel.github.com
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
@@ -26,7 +26,7 @@ import (
|
||||
|
||||
var (
|
||||
// GroupVersion is group version used to register these objects
|
||||
GroupVersion = schema.GroupVersion{Group: "zitadel.topmanage.com", Version: "v1alpha1"}
|
||||
GroupVersion = schema.GroupVersion{Group: "zitadel.github.com", Version: "v1alpha1"}
|
||||
|
||||
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
180
api/v1alpha1/instance_types.go
Normal file
180
api/v1alpha1/instance_types.go
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
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 v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// AccessTokenType defines the token format issued to the machine user.
|
||||
// +kubebuilder:validation:Enum=ACCESS_TOKEN_TYPE_BEARER;ACCESS_TOKEN_TYPE_JWT
|
||||
type AccessTokenType string
|
||||
|
||||
const (
|
||||
AccessTokenTypeBearer AccessTokenType = "ACCESS_TOKEN_TYPE_BEARER"
|
||||
AccessTokenTypeJWT AccessTokenType = "ACCESS_TOKEN_TYPE_JWT"
|
||||
)
|
||||
|
||||
// FirstOrg defines the first organisation and its IAM_OWNER machine user.
|
||||
type FirstOrg struct {
|
||||
// Name of the first organization.
|
||||
// +kubebuilder:default="DEFAULT"
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type LoginUIImage struct {
|
||||
// +kubebuilder:default="ghcr.io/zitadel/zitadel-login"
|
||||
Name string `json:"name"`
|
||||
// if empty it uses the same tag as zitadel cluster
|
||||
Tag *string `json:"tag,omitempty"`
|
||||
}
|
||||
|
||||
type LoginUI struct {
|
||||
Image LoginUIImage `json:"image"`
|
||||
|
||||
Resources corev1.ResourceRequirements `json:"resources"`
|
||||
}
|
||||
|
||||
// InstanceSpec defines the desired state of Instance.
|
||||
// Fields map directly to POST /instances/_create (CreateInstance) in the Zitadel System API.
|
||||
type InstanceSpec struct {
|
||||
// ClusterRef references the Cluster this instance will be provisioned on.
|
||||
// +kubebuilder:validation:Required
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
ClusterRef ClusterRef `json:"clusterRef"`
|
||||
|
||||
// InstanceName is the display name of the Zitadel instance.
|
||||
// +kubebuilder:validation:Required
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
InstanceName string `json:"instanceName"`
|
||||
|
||||
// DefaultLanguage is the BCP-47 language tag used as the instance default (e.g. "en").
|
||||
// +kubebuilder:default="en"
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
DefaultLanguage string `json:"defaultLanguage,omitempty"`
|
||||
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
CustomDomain string `json:"customDomain"`
|
||||
|
||||
// Org configures the first organisation and its initial IAM_OWNER machine user.
|
||||
// +kubebuilder:validation:Required
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
Org FirstOrg `json:"org"`
|
||||
|
||||
// +kubebuilder:default={image: {name: "ghcr.io/zitadel/zitadel-login"}, resources: {}}
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
LoginUI LoginUI `json:"loginUI"`
|
||||
}
|
||||
|
||||
// InstanceStatus defines the observed state of Instance.
|
||||
type InstanceStatus struct {
|
||||
// Conditions store the status conditions of the Instance.
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=status
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
|
||||
// InstanceId is the instance ID returned by Zitadel after successful provisioning.
|
||||
InstanceId *string `json:"instanceId,omitempty"`
|
||||
}
|
||||
|
||||
// SetCondition sets a status condition on the Instance.
|
||||
func (s *InstanceStatus) SetCondition(condition metav1.Condition) {
|
||||
if s.Conditions == nil {
|
||||
s.Conditions = make([]metav1.Condition, 0)
|
||||
}
|
||||
meta.SetStatusCondition(&s.Conditions, condition)
|
||||
}
|
||||
|
||||
// IsReady returns true when the instance has reached the Ready condition.
|
||||
func (s *Instance) IsReady() bool {
|
||||
return meta.IsStatusConditionTrue(s.Status.Conditions, ConditionTypeReady)
|
||||
}
|
||||
|
||||
func (d *Instance) IsBeingDeleted() bool {
|
||||
return !d.DeletionTimestamp.IsZero()
|
||||
}
|
||||
|
||||
func (s *Instance) ClusterRef(_ context.Context, _ *RefResolver) (*ClusterRef, error) {
|
||||
return &s.Spec.ClusterRef, nil
|
||||
}
|
||||
|
||||
// FillWithDefaults populates default values on the Instance status.
|
||||
func (s *InstanceStatus) FillWithDefaults(_ *Instance) {
|
||||
// (Haim ;^D): No defaults yet
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
//+kubebuilder:printcolumn:name="Instance",type=string,JSONPath=`.spec.instanceName`
|
||||
//+kubebuilder:printcolumn:name="Cluster",type=string,JSONPath=`.spec.clusterRef.name`
|
||||
//+kubebuilder:printcolumn:name="Domain",type=string,JSONPath=`.spec.customDomain`
|
||||
//+kubebuilder:printcolumn:name="Ready",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status`
|
||||
//+kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`
|
||||
|
||||
// Instance is the Schema for the instances API.
|
||||
type Instance struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec InstanceSpec `json:"spec,omitempty"`
|
||||
Status InstanceStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// SetDefaults populates default values on the Instance spec.
|
||||
func (m *Instance) SetDefaults() {
|
||||
// (Haim ;^D): No defaults yet
|
||||
}
|
||||
|
||||
func (m *Instance) MachineUserName() string {
|
||||
return "k8s-operator"
|
||||
}
|
||||
|
||||
func (m *Instance) MachineName() string {
|
||||
return "K8S OPERATOR"
|
||||
}
|
||||
|
||||
func (m *Instance) MachineSecretName() string {
|
||||
return m.Name + "-owner-machine-secret"
|
||||
}
|
||||
|
||||
func (m *Instance) LoginMachineUserName() string {
|
||||
return m.Name + "-login-ui"
|
||||
}
|
||||
|
||||
func (m *Instance) FirstOrgObjectName() string {
|
||||
return m.Name + "-" + m.Spec.Org.Name
|
||||
}
|
||||
|
||||
func (m *Instance) ConnectionObjectName() string {
|
||||
return m.Name + "-connection"
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// InstanceList contains a list of Instance.
|
||||
type InstanceList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Instance `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Instance{}, &InstanceList{})
|
||||
}
|
||||
23
api/v1alpha1/ref_types.go
Normal file
23
api/v1alpha1/ref_types.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
type PostgreSQLClusterRef struct {
|
||||
// ObjectReference is a reference to a object.
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
}
|
||||
|
||||
type InstanceRef struct {
|
||||
// ObjectReference is a reference to a object.
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
}
|
||||
|
||||
type ClusterRef struct {
|
||||
// ObjectReference is a reference to a object.
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
}
|
||||
@@ -22,9 +22,9 @@ func NewRefResolver(client client.Client) *RefResolver {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *RefResolver) ZitadelCluster(ctx context.Context, ref *ZitadelClusterRef,
|
||||
namespace string) (*ZitadelCluster, error) {
|
||||
if ref.Kind != "" && ref.Kind != "ZitadelCluster" {
|
||||
func (r *RefResolver) Instance(ctx context.Context, ref *InstanceRef,
|
||||
namespace string) (*Instance, error) {
|
||||
if ref.Kind != "" && ref.Kind != "Instance" {
|
||||
return nil, fmt.Errorf("Unsupported reference kind: '%s'", ref.Kind)
|
||||
}
|
||||
|
||||
@@ -36,16 +36,16 @@ func (r *RefResolver) ZitadelCluster(ctx context.Context, ref *ZitadelClusterRef
|
||||
key.Namespace = ref.Namespace
|
||||
}
|
||||
|
||||
var zitadel ZitadelCluster
|
||||
var zitadel Instance
|
||||
if err := r.client.Get(ctx, key, &zitadel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &zitadel, nil
|
||||
}
|
||||
|
||||
func (r *RefResolver) OIDCAppRef(ctx context.Context, ref *OIDCAppRef,
|
||||
namespace string) (*OIDCApp, error) {
|
||||
if ref.Kind != "" && ref.Kind != "OIDCApp" {
|
||||
func (r *RefResolver) Cluster(ctx context.Context, ref *ClusterRef,
|
||||
namespace string) (*Cluster, error) {
|
||||
if ref.Kind != "" && ref.Kind != "Cluster" {
|
||||
return nil, fmt.Errorf("Unsupported reference kind: '%s'", ref.Kind)
|
||||
}
|
||||
|
||||
@@ -57,70 +57,7 @@ func (r *RefResolver) OIDCAppRef(ctx context.Context, ref *OIDCAppRef,
|
||||
key.Namespace = ref.Namespace
|
||||
}
|
||||
|
||||
var zitadel OIDCApp
|
||||
if err := r.client.Get(ctx, key, &zitadel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &zitadel, nil
|
||||
}
|
||||
|
||||
func (r *RefResolver) ActionRef(ctx context.Context, ref *ActionRef,
|
||||
namespace string) (*Action, error) {
|
||||
if ref.Kind != "" && ref.Kind != "Action" {
|
||||
return nil, fmt.Errorf("Unsupported reference kind: '%s'", ref.Kind)
|
||||
}
|
||||
|
||||
key := types.NamespacedName{
|
||||
Name: ref.Name,
|
||||
Namespace: namespace,
|
||||
}
|
||||
if ref.Namespace != "" {
|
||||
key.Namespace = ref.Namespace
|
||||
}
|
||||
|
||||
var zitadel Action
|
||||
if err := r.client.Get(ctx, key, &zitadel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &zitadel, nil
|
||||
}
|
||||
|
||||
func (r *RefResolver) ProjectRef(ctx context.Context, ref *ProjectRef,
|
||||
namespace string) (*Project, error) {
|
||||
if ref.Kind != "" && ref.Kind != "Project" {
|
||||
return nil, fmt.Errorf("Unsupported reference kind: '%s'", ref.Kind)
|
||||
}
|
||||
|
||||
key := types.NamespacedName{
|
||||
Name: ref.Name,
|
||||
Namespace: namespace,
|
||||
}
|
||||
if ref.Namespace != "" {
|
||||
key.Namespace = ref.Namespace
|
||||
}
|
||||
|
||||
var zitadel Project
|
||||
if err := r.client.Get(ctx, key, &zitadel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &zitadel, nil
|
||||
}
|
||||
|
||||
func (r *RefResolver) OrganizationRef(ctx context.Context, ref *OrganizationRef,
|
||||
namespace string) (*Organization, error) {
|
||||
if ref.Kind != "" && ref.Kind != "Organization" {
|
||||
return nil, fmt.Errorf("Unsupported reference kind: '%s'", ref.Kind)
|
||||
}
|
||||
|
||||
key := types.NamespacedName{
|
||||
Name: ref.Name,
|
||||
Namespace: namespace,
|
||||
}
|
||||
if ref.Namespace != "" {
|
||||
key.Namespace = ref.Namespace
|
||||
}
|
||||
|
||||
var zitadel Organization
|
||||
var zitadel Cluster
|
||||
if err := r.client.Get(ctx, key, &zitadel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
419
api/v1alpha1/zz_generated.deepcopy.go
Normal file
419
api/v1alpha1/zz_generated.deepcopy.go
Normal file
@@ -0,0 +1,419 @@
|
||||
//go:build !ignore_autogenerated
|
||||
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Cluster) DeepCopyInto(out *Cluster) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Cluster.
|
||||
func (in *Cluster) DeepCopy() *Cluster {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Cluster)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Cluster) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterList) DeepCopyInto(out *ClusterList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Cluster, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterList.
|
||||
func (in *ClusterList) DeepCopy() *ClusterList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *ClusterList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterRef) DeepCopyInto(out *ClusterRef) {
|
||||
*out = *in
|
||||
out.ObjectReference = in.ObjectReference
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterRef.
|
||||
func (in *ClusterRef) DeepCopy() *ClusterRef {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterRef)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
||||
*out = *in
|
||||
out.Image = in.Image
|
||||
in.Resources.DeepCopyInto(&out.Resources)
|
||||
out.PostgreSQLClusterRef = in.PostgreSQLClusterRef
|
||||
if in.PodAnnotations != nil {
|
||||
in, out := &in.PodAnnotations, &out.PodAnnotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.ServiceAnnotations != nil {
|
||||
in, out := &in.ServiceAnnotations, &out.ServiceAnnotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterSpec.
|
||||
func (in *ClusterSpec) DeepCopy() *ClusterSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterStatus) DeepCopyInto(out *ClusterStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]v1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterStatus.
|
||||
func (in *ClusterStatus) DeepCopy() *ClusterStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DomainSettings) DeepCopyInto(out *DomainSettings) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DomainSettings.
|
||||
func (in *DomainSettings) DeepCopy() *DomainSettings {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DomainSettings)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FirstOrg) DeepCopyInto(out *FirstOrg) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FirstOrg.
|
||||
func (in *FirstOrg) DeepCopy() *FirstOrg {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FirstOrg)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Image) DeepCopyInto(out *Image) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Image.
|
||||
func (in *Image) DeepCopy() *Image {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Image)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Instance) DeepCopyInto(out *Instance) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Instance.
|
||||
func (in *Instance) DeepCopy() *Instance {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Instance)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Instance) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InstanceList) DeepCopyInto(out *InstanceList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Instance, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceList.
|
||||
func (in *InstanceList) DeepCopy() *InstanceList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InstanceList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *InstanceList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InstanceRef) DeepCopyInto(out *InstanceRef) {
|
||||
*out = *in
|
||||
out.ObjectReference = in.ObjectReference
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceRef.
|
||||
func (in *InstanceRef) DeepCopy() *InstanceRef {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InstanceRef)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InstanceSpec) DeepCopyInto(out *InstanceSpec) {
|
||||
*out = *in
|
||||
out.ClusterRef = in.ClusterRef
|
||||
out.Org = in.Org
|
||||
in.LoginUI.DeepCopyInto(&out.LoginUI)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceSpec.
|
||||
func (in *InstanceSpec) DeepCopy() *InstanceSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InstanceSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *InstanceStatus) DeepCopyInto(out *InstanceStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]v1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.InstanceId != nil {
|
||||
in, out := &in.InstanceId, &out.InstanceId
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstanceStatus.
|
||||
func (in *InstanceStatus) DeepCopy() *InstanceStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(InstanceStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LoginUI) DeepCopyInto(out *LoginUI) {
|
||||
*out = *in
|
||||
in.Image.DeepCopyInto(&out.Image)
|
||||
in.Resources.DeepCopyInto(&out.Resources)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoginUI.
|
||||
func (in *LoginUI) DeepCopy() *LoginUI {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LoginUI)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *LoginUIImage) DeepCopyInto(out *LoginUIImage) {
|
||||
*out = *in
|
||||
if in.Tag != nil {
|
||||
in, out := &in.Tag, &out.Tag
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoginUIImage.
|
||||
func (in *LoginUIImage) DeepCopy() *LoginUIImage {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(LoginUIImage)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Password) DeepCopyInto(out *Password) {
|
||||
*out = *in
|
||||
in.SecretKeyRef.DeepCopyInto(&out.SecretKeyRef)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Password.
|
||||
func (in *Password) DeepCopy() *Password {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Password)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PostgreSQLClusterRef) DeepCopyInto(out *PostgreSQLClusterRef) {
|
||||
*out = *in
|
||||
out.ObjectReference = in.ObjectReference
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostgreSQLClusterRef.
|
||||
func (in *PostgreSQLClusterRef) DeepCopy() *PostgreSQLClusterRef {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PostgreSQLClusterRef)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *SMTPConfig) DeepCopyInto(out *SMTPConfig) {
|
||||
*out = *in
|
||||
if in.User != nil {
|
||||
in, out := &in.User, &out.User
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Password != nil {
|
||||
in, out := &in.Password, &out.Password
|
||||
*out = new(Password)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.ReplyToAddress != nil {
|
||||
in, out := &in.ReplyToAddress, &out.ReplyToAddress
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SMTPConfig.
|
||||
func (in *SMTPConfig) DeepCopy() *SMTPConfig {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(SMTPConfig)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
@@ -1,183 +0,0 @@
|
||||
definitions:
|
||||
steps:
|
||||
- step: &test
|
||||
name: "Test"
|
||||
runs-on:
|
||||
- "linux"
|
||||
- "self.hosted"
|
||||
script:
|
||||
- echo please create tests
|
||||
|
||||
- step: &build
|
||||
name: "Build"
|
||||
runs-on:
|
||||
- "nixrunner"
|
||||
- "linux.shell"
|
||||
- "self.hosted"
|
||||
script:
|
||||
- mkdir -p images
|
||||
- (umask 077 ; echo -n $SSHKEY | base64 -d > ./id_rsa)
|
||||
- nix build --print-build-logs ./build/#dockerImage
|
||||
- cp $(readlink ./result) images/
|
||||
artifacts:
|
||||
- images/*
|
||||
|
||||
- step: &package-dev
|
||||
name: "Package Chart for Dev"
|
||||
runs-on:
|
||||
- "nixrunner"
|
||||
- "linux.shell"
|
||||
- "self.hosted"
|
||||
script:
|
||||
- mkdir -p charts
|
||||
- export VERSION="$BITBUCKET_BUILD_NUMBER"
|
||||
- export REPOSITORY="$K8S_ARES_DEV_DOCKERREGISTRY_URL/$BITBUCKET_REPO_SLUG"
|
||||
- nix-shell -p yq-go --run 'yq -i ".controllerManager.manager.image.tag = env(VERSION)" ./ops/chart/values.yaml'
|
||||
- nix-shell -p yq-go --run 'yq -i ".controllerManager.manager.image.repository = env(REPOSITORY)" ./ops/chart/values.yaml'
|
||||
- nix-shell -p kubernetes-helm --run 'helm repo add base "$K8S_ARES_DEV_CHARTMUSEUM_ENDPOINT" --username "$K8S_ARES_DEV_CHARTMUSEUM_USERNAME" --password "$K8S_ARES_DEV_CHARTMUSEUM_PASSWORD" --insecure-skip-tls-verify --force-update && helm dependency build ./ops/chart && helm package ./ops/chart -d result --app-version "$VERSION" --version "$VERSION"'
|
||||
- cp -a ./result/. charts/
|
||||
artifacts:
|
||||
- charts/*
|
||||
|
||||
- step: &package-qa
|
||||
name: "Package Chart for QA"
|
||||
runs-on:
|
||||
- "nixrunner"
|
||||
- "linux.shell"
|
||||
- "self.hosted"
|
||||
script:
|
||||
- mkdir -p charts
|
||||
- export VERSION="$BITBUCKET_BUILD_NUMBER"
|
||||
- export REPOSITORY="$K8S_ARES_QA_DOCKERREGISTRY_URL/$BITBUCKET_REPO_SLUG"
|
||||
- nix-shell -p yq-go --run 'yq -i ".controllerManager.manager.image.tag = env(VERSION)" ./ops/chart/values.yaml'
|
||||
- nix-shell -p yq-go --run 'yq -i ".controllerManager.manager.image.repository = env(REPOSITORY)" ./ops/chart/values.yaml'
|
||||
- nix-shell -p kubernetes-helm --run 'helm repo add base "$K8S_ARES_QA_CHARTMUSEUM_ENDPOINT" --username "$K8S_ARES_QA_CHARTMUSEUM_USERNAME" --password "$K8S_ARES_QA_CHARTMUSEUM_PASSWORD" --insecure-skip-tls-verify --force-update && helm dependency build ./ops/chart && helm package ./ops/chart -d result --app-version "$VERSION" --version "$VERSION"'
|
||||
- cp -a ./result/. charts/
|
||||
artifacts:
|
||||
- charts/*
|
||||
|
||||
- step: &publish-dev
|
||||
name: "Publish Chart to Dev"
|
||||
runs-on:
|
||||
- "nixrunner"
|
||||
- "linux.shell"
|
||||
- "self.hosted"
|
||||
deployment: dev
|
||||
script:
|
||||
- |
|
||||
nix-shell -p cacert curl --run 'curl -k --fail --data-binary "@charts/$(ls charts | tee /dev/stderr | head -n 1)" -u "$K8S_ARES_DEV_CHARTMUSEUM_USERNAME:$K8S_ARES_DEV_CHARTMUSEUM_PASSWORD" "$K8S_ARES_DEV_CHARTMUSEUM_ENDPOINT/api/charts"'
|
||||
|
||||
- step: &push-dev
|
||||
name: "Push image to Dev"
|
||||
image: topmanage/deployment-pipeline-image:28
|
||||
runs-on:
|
||||
- "linux"
|
||||
- "self.hosted"
|
||||
# deployment: dev
|
||||
script:
|
||||
- |
|
||||
set -euo pipefail
|
||||
DOCKERREGISTRY_URL=$K8S_ARES_DEV_DOCKERREGISTRY_URL \
|
||||
DOCKERREGISTRY_CACERT=$K8S_ARES_DEV_DOCKERREGISTRY_CACERT \
|
||||
DOCKERREGISTRY_CLIENTCERT=$K8S_ARES_DEV_DOCKERREGISTRY_CLIENTCERT \
|
||||
DOCKERREGISTRY_CLIENTKEY=$K8S_ARES_DEV_DOCKERREGISTRY_CLIENTKEY \
|
||||
DOCKERREGISTRY_PASSWORD=$K8S_ARES_DEV_DOCKERREGISTRY_PASSWORD \
|
||||
./build/push-image.sh
|
||||
|
||||
- step: &publish-qa
|
||||
name: "Publish Chart to QA"
|
||||
runs-on:
|
||||
- "nixrunner"
|
||||
- "linux.shell"
|
||||
- "self.hosted"
|
||||
deployment: qa
|
||||
script:
|
||||
- |
|
||||
nix-shell -p cacert curl --run 'curl -k --fail --data-binary "@charts/$(ls charts | tee /dev/stderr | head -n 1)" -u "$K8S_ARES_QA_CHARTMUSEUM_USERNAME:$K8S_ARES_QA_CHARTMUSEUM_PASSWORD" "$K8S_ARES_QA_CHARTMUSEUM_ENDPOINT/api/charts"'
|
||||
|
||||
- step: &push-qa
|
||||
name: "Push image to QA"
|
||||
image: topmanage/deployment-pipeline-image:28
|
||||
runs-on:
|
||||
- "linux"
|
||||
- "self.hosted"
|
||||
# deployment: qa
|
||||
script:
|
||||
- |
|
||||
set -euo pipefail
|
||||
DOCKERREGISTRY_URL=$K8S_ARES_QA_DOCKERREGISTRY_URL \
|
||||
DOCKERREGISTRY_CACERT=$K8S_ARES_QA_DOCKERREGISTRY_CACERT \
|
||||
DOCKERREGISTRY_CLIENTCERT=$K8S_ARES_QA_DOCKERREGISTRY_CLIENTCERT \
|
||||
DOCKERREGISTRY_CLIENTKEY=$K8S_ARES_QA_DOCKERREGISTRY_CLIENTKEY \
|
||||
DOCKERREGISTRY_PASSWORD=$K8S_ARES_QA_DOCKERREGISTRY_PASSWORD \
|
||||
./build/push-image.sh
|
||||
|
||||
- step: &package-prod
|
||||
name: "Package Chart for Production"
|
||||
runs-on:
|
||||
- "nixrunner"
|
||||
- "linux.shell"
|
||||
- "self.hosted"
|
||||
script:
|
||||
- mkdir -p charts
|
||||
- export VERSION="$BITBUCKET_BUILD_NUMBER"
|
||||
- export REPOSITORY="$K8S_ARES_PROD_DOCKERREGISTRY_URL/$BITBUCKET_REPO_SLUG"
|
||||
- nix-shell -p yq-go --run 'yq -i ".controllerManager.manager.image.tag = env(VERSION)" ./ops/chart/values.yaml'
|
||||
- nix-shell -p yq-go --run 'yq -i ".controllerManager.manager.image.repository = env(REPOSITORY)" ./ops/chart/values.yaml'
|
||||
- nix-shell -p kubernetes-helm --run 'helm repo add base "$K8S_ARES_PROD_CHARTMUSEUM_ENDPOINT" --username "$K8S_ARES_PROD_CHARTMUSEUM_USERNAME" --password "$K8S_ARES_PROD_CHARTMUSEUM_PASSWORD" --insecure-skip-tls-verify --force-update && helm dependency build ./ops/chart && helm package ./ops/chart -d result --app-version "$VERSION" --version "$VERSION"'
|
||||
- cp -a ./result/. charts/
|
||||
artifacts:
|
||||
- charts/*
|
||||
|
||||
- step: &publish-prod
|
||||
name: "Publish Chart to Production"
|
||||
runs-on:
|
||||
- "nixrunner"
|
||||
- "linux.shell"
|
||||
- "self.hosted"
|
||||
deployment: prod
|
||||
script:
|
||||
- |
|
||||
nix-shell -p cacert curl --run 'curl -k --fail --data-binary "@charts/$(ls charts | tee /dev/stderr | head -n 1)" -u "$K8S_ARES_PROD_CHARTMUSEUM_USERNAME:$K8S_ARES_PROD_CHARTMUSEUM_PASSWORD" "$K8S_ARES_PROD_CHARTMUSEUM_ENDPOINT/api/charts"'
|
||||
|
||||
- step: &push-prod
|
||||
name: "Push image to Production"
|
||||
image: topmanage/deployment-pipeline-image:28
|
||||
runs-on:
|
||||
- "linux"
|
||||
- "self.hosted"
|
||||
# deployment: prod
|
||||
script:
|
||||
- |
|
||||
set -euo pipefail
|
||||
DOCKERREGISTRY_URL=$K8S_ARES_PROD_DOCKERREGISTRY_URL \
|
||||
DOCKERREGISTRY_CACERT=$K8S_ARES_PROD_DOCKERREGISTRY_CACERT \
|
||||
DOCKERREGISTRY_CLIENTCERT=$K8S_ARES_PROD_DOCKERREGISTRY_CLIENTCERT \
|
||||
DOCKERREGISTRY_CLIENTKEY=$K8S_ARES_PROD_DOCKERREGISTRY_CLIENTKEY \
|
||||
DOCKERREGISTRY_PASSWORD=$K8S_ARES_PROD_DOCKERREGISTRY_PASSWORD \
|
||||
./build/push-image.sh
|
||||
|
||||
pipelines:
|
||||
default:
|
||||
- parallel:
|
||||
- step: *build
|
||||
- step: *test
|
||||
- step: *package-dev
|
||||
- step: *push-dev
|
||||
- step: *publish-dev
|
||||
branches:
|
||||
master:
|
||||
- parallel:
|
||||
- step: *build
|
||||
- step: *test
|
||||
- step: *package-qa
|
||||
- step: *push-qa
|
||||
- step: *publish-qa
|
||||
tags:
|
||||
release-*:
|
||||
- parallel:
|
||||
- step: *build
|
||||
- step: *test
|
||||
- step: *package-prod
|
||||
- step: *push-prod
|
||||
- step: *publish-prod
|
||||
26
build/flake.lock
generated
26
build/flake.lock
generated
@@ -20,36 +20,24 @@
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 0,
|
||||
"narHash": "sha256-7Fu7oazPoYCbDzb9k8D/DdbKrC3aU1zlnc39Y8jy/s8=",
|
||||
"path": "/nix/store/m4wcdchjxw2fdyzjp8i6irpc613pchkr-source",
|
||||
"type": "path"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"nixpkgs-unstable": {
|
||||
"locked": {
|
||||
"lastModified": 1743448293,
|
||||
"narHash": "sha256-bmEPmSjJakAp/JojZRrUvNcDX2R5/nuX6bm+seVaGhs=",
|
||||
"lastModified": 1775710090,
|
||||
"narHash": "sha256-ar3rofg+awPB8QXDaFJhJ2jJhu+KqN/PRCXeyuXR76E=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "77b584d61ff80b4cef9245829a6f1dfad5afdfa3",
|
||||
"rev": "4c1018dae018162ec878d42fec712642d214fdfa",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"type": "indirect"
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs",
|
||||
"nixpkgs-unstable": "nixpkgs-unstable"
|
||||
"nixpkgs": "nixpkgs"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
|
||||
@@ -3,20 +3,25 @@
|
||||
|
||||
inputs = {
|
||||
flake-utils.url = "github:numtide/flake-utils";
|
||||
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, nixpkgs-unstable, flake-utils }:
|
||||
flake-utils.lib.eachDefaultSystem (system:
|
||||
outputs =
|
||||
{
|
||||
self,
|
||||
nixpkgs,
|
||||
flake-utils,
|
||||
}:
|
||||
flake-utils.lib.eachDefaultSystem (
|
||||
system:
|
||||
let
|
||||
unstable = nixpkgs-unstable.legacyPackages.${system};
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
package = unstable.buildGoModule {
|
||||
package = pkgs.buildGoModule {
|
||||
pname = "zitadel-k8s-operator";
|
||||
version = "0.0.0";
|
||||
src = ../src;
|
||||
src = ../.;
|
||||
doCheck = false;
|
||||
vendorHash = "sha256-HEXIHASdDC7chG9uF56f6pvZPVbxYs/fWFytDz6CAf4=";
|
||||
vendorHash = "sha256-Ngn1hcOFZP6NivtJfNNafbyg4u4Ti4gr+XUs6KrYgf8=";
|
||||
installPhase = ''
|
||||
runHook preInstall
|
||||
|
||||
@@ -42,11 +47,19 @@
|
||||
User = "65532:65532";
|
||||
};
|
||||
};
|
||||
in with pkgs; {
|
||||
in
|
||||
with pkgs;
|
||||
{
|
||||
packages.default = package;
|
||||
packages.dockerImage = dockerPackage;
|
||||
devShells.default = mkShell {
|
||||
buildInputs = [ nixfmt unstable.gopls operator-sdk unstable.go ];
|
||||
buildInputs = [
|
||||
nixfmt
|
||||
gopls
|
||||
operator-sdk
|
||||
go
|
||||
];
|
||||
};
|
||||
});
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -21,6 +21,8 @@ import (
|
||||
"os"
|
||||
"time"
|
||||
|
||||
// "time"
|
||||
|
||||
// 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/apimachinery/pkg/runtime"
|
||||
@@ -32,14 +34,17 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
server "sigs.k8s.io/controller-runtime/pkg/metrics/server"
|
||||
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/internal/controller"
|
||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder"
|
||||
conditions "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/condition"
|
||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/controller/configmap"
|
||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/controller/secret"
|
||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/controller/service"
|
||||
cloudnativepgv1 "github.com/cloudnative-pg/cloudnative-pg/api/v1"
|
||||
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/internal/controller"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder"
|
||||
conditions "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/condition"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/controller/configmap"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/controller/secret"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/controller/service"
|
||||
zitadelresourcesv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-resources-operator/api/v1alpha1"
|
||||
//+kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
@@ -51,6 +56,7 @@ var (
|
||||
func init() {
|
||||
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
||||
utilruntime.Must(cloudnativepgv1.AddToScheme(scheme))
|
||||
utilruntime.Must(zitadelresourcesv1alpha1.AddToScheme(scheme))
|
||||
utilruntime.Must(zitadelv1alpha1.AddToScheme(scheme))
|
||||
//+kubebuilder:scaffold:scheme
|
||||
}
|
||||
@@ -77,7 +83,7 @@ func main() {
|
||||
Metrics: server.Options{BindAddress: metricsAddr},
|
||||
HealthProbeBindAddress: probeAddr,
|
||||
LeaderElection: enableLeaderElection,
|
||||
LeaderElectionID: "88a0b43c.topmanage.com",
|
||||
LeaderElectionID: "88a0b43c.github.com",
|
||||
// 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
|
||||
@@ -103,7 +109,7 @@ func main() {
|
||||
refResolver := zitadelv1alpha1.NewRefResolver(client)
|
||||
conditionReady := conditions.NewReady()
|
||||
requeueZitadel := 5 * time.Minute
|
||||
if err = (&controller.ZitadelClusterReconciler{
|
||||
if err = (&controller.ClusterReconciler{
|
||||
Client: client,
|
||||
Scheme: scheme,
|
||||
ConditionReady: conditionReady,
|
||||
@@ -116,35 +122,41 @@ func main() {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "ZitadelCluster")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = controller.NewOrganizationReconciler(client, refResolver, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "Organization")
|
||||
|
||||
if err = controller.NewInstanceReconciler(client, refResolver, builder, conditionReady, serviceReconciler, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "Instance")
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if err = controller.NewProjectReconciler(client, refResolver, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "Project")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = controller.NewOIDCAppReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "OIDCApp")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = controller.NewMachineUserReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "MachineUser")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = controller.NewAPIAppReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "APIApp")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = controller.NewActionReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "Action")
|
||||
os.Exit(1)
|
||||
}
|
||||
if err = controller.NewFlowReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
setupLog.Error(err, "unable to create controller", "controller", "Flow")
|
||||
os.Exit(1)
|
||||
}
|
||||
// if err = controller.NewOrganizationReconciler(client, refResolver, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
// setupLog.Error(err, "unable to create controller", "controller", "Organization")
|
||||
// os.Exit(1)
|
||||
// }
|
||||
|
||||
// if err = controller.NewProjectReconciler(client, refResolver, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
// setupLog.Error(err, "unable to create controller", "controller", "Project")
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// if err = controller.NewOIDCAppReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
// setupLog.Error(err, "unable to create controller", "controller", "OIDCApp")
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// if err = controller.NewMachineUserReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
// setupLog.Error(err, "unable to create controller", "controller", "MachineUser")
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// if err = controller.NewAPIAppReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
// setupLog.Error(err, "unable to create controller", "controller", "APIApp")
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// if err = controller.NewActionReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
// setupLog.Error(err, "unable to create controller", "controller", "Action")
|
||||
// os.Exit(1)
|
||||
// }
|
||||
// if err = controller.NewFlowReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||
// setupLog.Error(err, "unable to create controller", "controller", "Flow")
|
||||
// os.Exit(1)
|
||||
// }
|
||||
//+kubebuilder:scaffold:builder
|
||||
|
||||
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
|
||||
@@ -4,20 +4,30 @@ kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: zitadelclusters.zitadel.topmanage.com
|
||||
name: clusters.zitadel.github.com
|
||||
spec:
|
||||
group: zitadel.topmanage.com
|
||||
group: zitadel.github.com
|
||||
names:
|
||||
kind: ZitadelCluster
|
||||
listKind: ZitadelClusterList
|
||||
plural: zitadelclusters
|
||||
singular: zitadelcluster
|
||||
kind: Cluster
|
||||
listKind: ClusterList
|
||||
plural: clusters
|
||||
singular: cluster
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .status.replicas
|
||||
name: Replicas
|
||||
type: integer
|
||||
- jsonPath: .status.conditions[?(@.type=="Ready")].status
|
||||
name: Ready
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: ZitadelCluster is the Schema for the zitadelclusters API
|
||||
description: Cluster is the Schema for the clusters API.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
@@ -37,40 +47,23 @@ spec:
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: ZitadelClusterSpec defines the desired state of ZitadelCluster
|
||||
description: ClusterSpec defines the desired state of Cluster.
|
||||
properties:
|
||||
domainSettings:
|
||||
properties:
|
||||
smtpSenderAddressMatchesInstanceDomain:
|
||||
default: true
|
||||
type: boolean
|
||||
userLoginMustBeDomain:
|
||||
default: true
|
||||
type: boolean
|
||||
validateOrgDomains:
|
||||
default: true
|
||||
type: boolean
|
||||
required:
|
||||
- smtpSenderAddressMatchesInstanceDomain
|
||||
- userLoginMustBeDomain
|
||||
- validateOrgDomains
|
||||
type: object
|
||||
externalPort:
|
||||
default: 443
|
||||
description: ExternalPort is the port exposed externally.
|
||||
format: int64
|
||||
type: integer
|
||||
externalSecure:
|
||||
default: true
|
||||
description: ExternalSecure indicates whether TLS is used on the external
|
||||
endpoint.
|
||||
type: boolean
|
||||
firstOrgName:
|
||||
default: DEFAULT
|
||||
description: |-
|
||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
type: string
|
||||
host:
|
||||
description: Host is the external hostname used to reach Zitadel.
|
||||
type: string
|
||||
image:
|
||||
description: Image is the Zitadel container image to deploy.
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
@@ -83,9 +76,12 @@ spec:
|
||||
podAnnotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: PodAnnotations to add to the Pods metadata.
|
||||
description: PodAnnotations are extra annotations added to each Zitadel
|
||||
Pod.
|
||||
type: object
|
||||
postgresClusterRef:
|
||||
description: PostgreSQLClusterRef references the backing PostgreSQL
|
||||
cluster.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
@@ -127,27 +123,21 @@ spec:
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
purpose:
|
||||
enum:
|
||||
- demo
|
||||
- trial
|
||||
- staging
|
||||
- productive
|
||||
- testing
|
||||
type: string
|
||||
replicas:
|
||||
default: 3
|
||||
description: Replicas is the desired number of Zitadel pods.
|
||||
format: int32
|
||||
type: integer
|
||||
resources:
|
||||
description: ResourceRequirements describes the compute resource requirements.
|
||||
description: Resources defines compute resource requests and limits
|
||||
for the Zitadel pods.
|
||||
properties:
|
||||
claims:
|
||||
description: |-
|
||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||
that are used by this container.
|
||||
|
||||
This is an alpha field and requires enabling the
|
||||
This field depends on the
|
||||
DynamicResourceAllocation feature gate.
|
||||
|
||||
This field is immutable. It can only be set for containers.
|
||||
@@ -198,96 +188,25 @@ spec:
|
||||
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
type: object
|
||||
type: object
|
||||
rootTLSSecret:
|
||||
description: |-
|
||||
SecretReference represents a Secret Reference. It has enough information to retrieve secret
|
||||
in any namespace
|
||||
properties:
|
||||
name:
|
||||
description: name is unique within a namespace to reference a
|
||||
secret resource.
|
||||
type: string
|
||||
namespace:
|
||||
description: namespace defines the space within which the secret
|
||||
name must be unique.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
serviceAnnotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: ServiceAnnotations to add to the service metadata.
|
||||
type: object
|
||||
smtpConfig:
|
||||
properties:
|
||||
host:
|
||||
type: string
|
||||
password:
|
||||
properties:
|
||||
secretRef:
|
||||
description: SecretKeySelector selects a key of a Secret.
|
||||
properties:
|
||||
key:
|
||||
description: The key of the secret to select from. Must
|
||||
be a valid secret key.
|
||||
type: string
|
||||
name:
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
optional:
|
||||
description: Specify whether the Secret or its key must
|
||||
be defined
|
||||
type: boolean
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
required:
|
||||
- secretRef
|
||||
type: object
|
||||
replyToAddress:
|
||||
type: string
|
||||
senderAddress:
|
||||
type: string
|
||||
senderName:
|
||||
type: string
|
||||
tls:
|
||||
default: true
|
||||
type: boolean
|
||||
user:
|
||||
type: string
|
||||
required:
|
||||
- host
|
||||
- senderAddress
|
||||
- senderName
|
||||
- tls
|
||||
description: ServiceAnnotations are extra annotations added to the
|
||||
Zitadel Service.
|
||||
type: object
|
||||
required:
|
||||
- domainSettings
|
||||
- externalPort
|
||||
- externalSecure
|
||||
- firstOrgName
|
||||
- host
|
||||
- image
|
||||
- postgresClusterRef
|
||||
- purpose
|
||||
- resources
|
||||
- rootTLSSecret
|
||||
- smtpConfig
|
||||
type: object
|
||||
status:
|
||||
description: ZitadelClusterStatus defines the observed state of ZitadelCluster
|
||||
description: ClusterStatus defines the observed state of Cluster.
|
||||
properties:
|
||||
conditions:
|
||||
description: |-
|
||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
description: Conditions store the status conditions of the Cluster.
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
@@ -343,19 +262,11 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
defaultInstanceId:
|
||||
default: ""
|
||||
type: string
|
||||
replicas:
|
||||
default: 3
|
||||
description: Replicas is the current number of running Zitadel pods.
|
||||
format: int32
|
||||
type: integer
|
||||
smtpProviderId:
|
||||
default: ""
|
||||
type: string
|
||||
required:
|
||||
- defaultInstanceId
|
||||
- smtpProviderId
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
@@ -4,20 +4,36 @@ kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: machineusers.zitadel.topmanage.com
|
||||
name: instances.zitadel.github.com
|
||||
spec:
|
||||
group: zitadel.topmanage.com
|
||||
group: zitadel.github.com
|
||||
names:
|
||||
kind: MachineUser
|
||||
listKind: MachineUserList
|
||||
plural: machineusers
|
||||
singular: machineuser
|
||||
kind: Instance
|
||||
listKind: InstanceList
|
||||
plural: instances
|
||||
singular: instance
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.instanceName
|
||||
name: Instance
|
||||
type: string
|
||||
- jsonPath: .spec.clusterRef.name
|
||||
name: Cluster
|
||||
type: string
|
||||
- jsonPath: .spec.customDomain
|
||||
name: Domain
|
||||
type: string
|
||||
- jsonPath: .status.conditions[?(@.type=="Ready")].status
|
||||
name: Ready
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: MachineUser is the Schema for the machineusers API
|
||||
description: Instance is the Schema for the instances API.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
@@ -37,17 +53,13 @@ spec:
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: MachineUserSpec defines the desired state of MachineUser
|
||||
properties:
|
||||
accessTokenType:
|
||||
enum:
|
||||
- ACCESS_TOKEN_TYPE_BEARER
|
||||
- ACCESS_TOKEN_TYPE_JWT
|
||||
type: string
|
||||
organizationRef:
|
||||
description: |-
|
||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
InstanceSpec defines the desired state of Instance.
|
||||
Fields map directly to POST /instances/_create (CreateInstance) in the Zitadel System API.
|
||||
properties:
|
||||
clusterRef:
|
||||
description: ClusterRef references the Cluster this instance will
|
||||
be provisioned on.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
@@ -89,70 +101,120 @@ spec:
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
userGrants:
|
||||
customDomain:
|
||||
type: string
|
||||
defaultLanguage:
|
||||
default: en
|
||||
description: DefaultLanguage is the BCP-47 language tag used as the
|
||||
instance default (e.g. "en").
|
||||
type: string
|
||||
instanceName:
|
||||
description: InstanceName is the display name of the Zitadel instance.
|
||||
type: string
|
||||
loginUI:
|
||||
default:
|
||||
image:
|
||||
name: ghcr.io/zitadel/zitadel-login
|
||||
resources: {}
|
||||
properties:
|
||||
image:
|
||||
properties:
|
||||
name:
|
||||
default: ghcr.io/zitadel/zitadel-login
|
||||
type: string
|
||||
tag:
|
||||
description: if empty it uses the same tag as zitadel cluster
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
resources:
|
||||
description: ResourceRequirements describes the compute resource
|
||||
requirements.
|
||||
properties:
|
||||
claims:
|
||||
description: |-
|
||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||
that are used by this container.
|
||||
|
||||
This field depends on the
|
||||
DynamicResourceAllocation feature gate.
|
||||
|
||||
This field is immutable. It can only be set for containers.
|
||||
items:
|
||||
description: ResourceClaim references one entry in PodSpec.ResourceClaims.
|
||||
properties:
|
||||
projectRef:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: |-
|
||||
If referring to a piece of an object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
Name must match the name of one entry in pod.spec.resourceClaims of
|
||||
the Pod where this field is used. It makes that resource available
|
||||
inside a container.
|
||||
type: string
|
||||
namespace:
|
||||
request:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
Request is the name chosen for a request in the referenced claim.
|
||||
If empty, everything from the claim is made available, otherwise
|
||||
only the result of this request.
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: |-
|
||||
Specific resourceVersion to which this reference is made, if any.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||
type: string
|
||||
uid:
|
||||
description: |-
|
||||
UID of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
roleKeys:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- projectRef
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- name
|
||||
x-kubernetes-list-type: map
|
||||
limits:
|
||||
additionalProperties:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: |-
|
||||
Limits describes the maximum amount of compute resources allowed.
|
||||
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: |-
|
||||
Requests describes the minimum amount of compute resources required.
|
||||
If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,
|
||||
otherwise to an implementation-defined value. Requests cannot exceed Limits.
|
||||
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
type: object
|
||||
type: object
|
||||
required:
|
||||
- accessTokenType
|
||||
- organizationRef
|
||||
- image
|
||||
- resources
|
||||
type: object
|
||||
org:
|
||||
description: Org configures the first organisation and its initial
|
||||
IAM_OWNER machine user.
|
||||
properties:
|
||||
name:
|
||||
default: DEFAULT
|
||||
description: Name of the first organization.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- clusterRef
|
||||
- customDomain
|
||||
- instanceName
|
||||
- loginUI
|
||||
- org
|
||||
type: object
|
||||
status:
|
||||
description: MachineUserStatus defines the observed state of MachineUser
|
||||
description: InstanceStatus defines the observed state of Instance.
|
||||
properties:
|
||||
conditions:
|
||||
description: |-
|
||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
description: Conditions store the status conditions of the Instance.
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
@@ -208,19 +270,10 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
keyId:
|
||||
default: ""
|
||||
instanceId:
|
||||
description: InstanceId is the instance ID returned by Zitadel after
|
||||
successful provisioning.
|
||||
type: string
|
||||
patId:
|
||||
default: ""
|
||||
type: string
|
||||
userId:
|
||||
default: ""
|
||||
type: string
|
||||
required:
|
||||
- keyId
|
||||
- patId
|
||||
- userId
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
@@ -2,14 +2,8 @@
|
||||
# since it depends on service name and namespace that are out of this kustomize package.
|
||||
# It should be run by config/default
|
||||
resources:
|
||||
- bases/zitadel.topmanage.com_zitadelclusters.yaml
|
||||
- bases/zitadel.topmanage.com_organizations.yaml
|
||||
- bases/zitadel.topmanage.com_projects.yaml
|
||||
- bases/zitadel.topmanage.com_oidcapps.yaml
|
||||
- bases/zitadel.topmanage.com_machineusers.yaml
|
||||
- bases/zitadel.topmanage.com_apiapps.yaml
|
||||
- bases/zitadel.topmanage.com_actions.yaml
|
||||
- bases/zitadel.topmanage.com_flows.yaml
|
||||
- bases/zitadel.github.com_clusters.yaml
|
||||
- bases/zitadel.github.com_instances.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizeresource
|
||||
|
||||
patchesStrategicMerge:
|
||||
@@ -35,6 +29,7 @@ patchesStrategicMerge:
|
||||
#- patches/cainjection_in_apiapps.yaml
|
||||
#- patches/cainjection_in_actions.yaml
|
||||
#- patches/cainjection_in_flows.yaml
|
||||
#- path: patches/cainjection_in_connections.yaml
|
||||
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
|
||||
|
||||
# the following config is for teaching kustomize how to do kustomization for CRDs.
|
||||
@@ -12,9 +12,9 @@ metadata:
|
||||
name: zitadelcluster-editor-role
|
||||
rules:
|
||||
- apiGroups:
|
||||
- zitadel.topmanage.com
|
||||
- zitadel.github.com
|
||||
resources:
|
||||
- zitadelclusters
|
||||
- clusters
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
@@ -24,8 +24,8 @@ rules:
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- zitadel.topmanage.com
|
||||
- zitadel.github.com
|
||||
resources:
|
||||
- zitadelclusters/status
|
||||
- clusters/status
|
||||
verbs:
|
||||
- get
|
||||
@@ -16,3 +16,8 @@ resources:
|
||||
- auth_proxy_role.yaml
|
||||
- auth_proxy_role_binding.yaml
|
||||
- auth_proxy_client_clusterrole.yaml
|
||||
# For each CRD, "Editor" and "Viewer" roles are scaffolded by
|
||||
# default, aiding admins in cluster management. Those roles are
|
||||
# not used by the Project itself. You can comment the following lines
|
||||
# if you do not want those helpers be installed with your Project.
|
||||
|
||||
@@ -127,17 +127,48 @@ rules:
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- apiGroups:
|
||||
- zitadel.github.com
|
||||
resources:
|
||||
- clusters
|
||||
- connections
|
||||
- instances
|
||||
- machineusers
|
||||
- organizations
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- zitadel.github.com
|
||||
resources:
|
||||
- clusters/finalizers
|
||||
- connections/finalizers
|
||||
- instances/finalizers
|
||||
- machineusers/finalizers
|
||||
- organizations/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- zitadel.github.com
|
||||
resources:
|
||||
- clusters/status
|
||||
- connections/status
|
||||
- instances/status
|
||||
- machineusers/status
|
||||
- organizations/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- zitadel.topmanage.com
|
||||
resources:
|
||||
- actions
|
||||
- apiapps
|
||||
- flows
|
||||
- machineusers
|
||||
- oidcapps
|
||||
- organizations
|
||||
- projects
|
||||
- zitadelclusters
|
||||
- instances
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
@@ -149,27 +180,13 @@ rules:
|
||||
- apiGroups:
|
||||
- zitadel.topmanage.com
|
||||
resources:
|
||||
- actions/finalizers
|
||||
- apiapps/finalizers
|
||||
- flows/finalizers
|
||||
- machineusers/finalizers
|
||||
- oidcapps/finalizers
|
||||
- organizations/finalizers
|
||||
- projects/finalizers
|
||||
- zitadelclusters/finalizers
|
||||
- instances/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- zitadel.topmanage.com
|
||||
resources:
|
||||
- actions/status
|
||||
- apiapps/status
|
||||
- flows/status
|
||||
- machineusers/status
|
||||
- oidcapps/status
|
||||
- organizations/status
|
||||
- projects/status
|
||||
- zitadelclusters/status
|
||||
- instances/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
4
config/samples/kustomization.yaml
Normal file
4
config/samples/kustomization.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
## Append samples of your project ##
|
||||
resources:
|
||||
- zitadel_v1alpha1_connection.yaml
|
||||
# +kubebuilder:scaffold:manifestskustomizesamples
|
||||
9
config/samples/zitadel_v1alpha1_connection.yaml
Normal file
9
config/samples/zitadel_v1alpha1_connection.yaml
Normal file
@@ -0,0 +1,9 @@
|
||||
apiVersion: zitadel.github.com/v1alpha1
|
||||
kind: Connection
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: src
|
||||
app.kubernetes.io/managed-by: kustomize
|
||||
name: connection-sample
|
||||
spec:
|
||||
# TODO(user): Add fields here
|
||||
106
go.mod
Normal file
106
go.mod
Normal file
@@ -0,0 +1,106 @@
|
||||
module gitea.corredorconect.com/software-engineering/zitadel-k8s-operator
|
||||
|
||||
go 1.25.8
|
||||
|
||||
require (
|
||||
gitea.corredorconect.com/software-engineering/zitadel-resources-operator v0.0.0-20260407173354-d5c3485fd29b
|
||||
github.com/cloudnative-pg/cloudnative-pg v1.25.1
|
||||
github.com/hashicorp/go-multierror v1.1.1
|
||||
github.com/onsi/ginkgo/v2 v2.27.2
|
||||
github.com/onsi/gomega v1.38.2
|
||||
github.com/sethvargo/go-password v0.3.1
|
||||
github.com/zitadel/zitadel-go/v3 v3.27.0
|
||||
google.golang.org/grpc v1.79.3
|
||||
k8s.io/api v0.35.3
|
||||
k8s.io/apimachinery v0.35.3
|
||||
k8s.io/client-go v0.35.3
|
||||
sigs.k8s.io/controller-runtime v0.20.4
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/Masterminds/semver/v3 v3.4.0 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cloudnative-pg/barman-cloud v0.1.0 // indirect
|
||||
github.com/cloudnative-pg/machinery v0.1.0 // indirect
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||
github.com/emicklei/go-restful/v3 v3.12.2 // indirect
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect
|
||||
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
|
||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 // indirect
|
||||
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
|
||||
github.com/go-logr/logr v1.4.3 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-logr/zapr v1.3.0 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||
github.com/go-openapi/jsonreference v0.21.0 // indirect
|
||||
github.com/go-openapi/swag v0.23.0 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/gnostic-models v0.7.0 // indirect
|
||||
github.com/google/go-cmp v0.7.0 // indirect
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/kubernetes-csi/external-snapshotter/client/v8 v8.2.0 // indirect
|
||||
github.com/lib/pq v1.10.9 // indirect
|
||||
github.com/mailru/easyjson v0.9.0 // indirect
|
||||
github.com/moby/spdystream v0.5.0 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect
|
||||
github.com/muhlemmer/gu v0.3.1 // indirect
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.80.1 // indirect
|
||||
github.com/prometheus/client_golang v1.21.0 // indirect
|
||||
github.com/prometheus/client_model v0.6.1 // indirect
|
||||
github.com/prometheus/common v0.62.0 // indirect
|
||||
github.com/prometheus/procfs v0.15.1 // indirect
|
||||
github.com/sirupsen/logrus v1.9.4 // indirect
|
||||
github.com/spf13/pflag v1.0.9 // indirect
|
||||
github.com/x448/float16 v0.8.4 // indirect
|
||||
github.com/zitadel/logging v0.7.0 // indirect
|
||||
github.com/zitadel/oidc/v3 v3.45.5 // indirect
|
||||
github.com/zitadel/schema v1.3.2 // indirect
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||
go.opentelemetry.io/otel v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.40.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.40.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.27.0 // indirect
|
||||
go.yaml.in/yaml/v2 v2.4.3 // indirect
|
||||
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
||||
golang.org/x/mod v0.32.0 // indirect
|
||||
golang.org/x/net v0.49.0 // indirect
|
||||
golang.org/x/oauth2 v0.35.0 // indirect
|
||||
golang.org/x/sync v0.19.0 // indirect
|
||||
golang.org/x/sys v0.40.0 // indirect
|
||||
golang.org/x/term v0.39.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
golang.org/x/time v0.9.0 // indirect
|
||||
golang.org/x/tools v0.41.0 // indirect
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.32.2 // indirect
|
||||
k8s.io/klog/v2 v2.130.1 // indirect
|
||||
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect
|
||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect
|
||||
sigs.k8s.io/randfill v1.0.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 // indirect
|
||||
sigs.k8s.io/yaml v1.6.0 // indirect
|
||||
)
|
||||
@@ -1,9 +1,13 @@
|
||||
gitea.corredorconect.com/software-engineering/zitadel-resources-operator v0.0.0-20260407173354-d5c3485fd29b h1:gtF0fMf8EUdlC+oJ1DX1oPcMA+rz24K8CfZ2jMZ84r0=
|
||||
gitea.corredorconect.com/software-engineering/zitadel-resources-operator v0.0.0-20260407173354-d5c3485fd29b/go.mod h1:DzcXKjG5j+4FIi0Wi/dye2yVD0XhAh5ukQChYwL1DMI=
|
||||
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
|
||||
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
github.com/bmatcuk/doublestar/v4 v4.8.1 h1:54Bopc5c2cAvhLRAzqOGCYHYyhcDHsFF4wWIR5wKP38=
|
||||
github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/bmatcuk/doublestar/v4 v4.10.0 h1:zU9WiOla1YA122oLM6i4EXvGW62DvKZVxIe6TYWexEs=
|
||||
github.com/bmatcuk/doublestar/v4 v4.10.0/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
||||
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
||||
github.com/cloudnative-pg/barman-cloud v0.1.0 h1:e/z52CehMBIh1LjZqNBJnncWJbS+1JYvRMBR8Js6Uiw=
|
||||
@@ -16,25 +20,31 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU=
|
||||
github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
|
||||
github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU=
|
||||
github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds=
|
||||
github.com/envoyproxy/protoc-gen-validate v1.3.3/go.mod h1:TsndJ/ngyIdQRhMcVVGDDHINPLWB7C82oDArY51KfB0=
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
|
||||
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||
github.com/evanphx/json-patch/v5 v5.9.11 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=
|
||||
github.com/evanphx/json-patch/v5 v5.9.11/go.mod h1:3j+LviiESTElxA4p3EMKAB9HXj3/XEtnUf6OZxqIQTM=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
||||
github.com/go-chi/chi/v5 v5.2.1 h1:KOIHODQj58PmL80G2Eak4WdvUzjSJSm0vG72crDCqb8=
|
||||
github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
||||
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
|
||||
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
|
||||
github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs=
|
||||
github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo=
|
||||
github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M=
|
||||
github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk=
|
||||
github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE=
|
||||
github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc=
|
||||
github.com/go-chi/chi/v5 v5.2.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
|
||||
github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
|
||||
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
|
||||
github.com/go-jose/go-jose/v4 v4.1.3/go.mod h1:x4oUasVrzR7071A4TnHLGSPpNOm2a21K9Kf04k1rs08=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
|
||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
||||
@@ -47,32 +57,31 @@ github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+Gr
|
||||
github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
|
||||
github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw=
|
||||
github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
|
||||
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
|
||||
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
|
||||
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
|
||||
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
|
||||
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
|
||||
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo=
|
||||
github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
|
||||
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
|
||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
|
||||
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/schema v1.4.1 h1:jUg5hUjCSDZpNGLuXQOgIWGdlgrIdYvgQ0wZtdK1M3E=
|
||||
github.com/gorilla/schema v1.4.1/go.mod h1:Dg5SSm5PV60mhF2NFaTV1xuYYj8tV8NOPRo4FggUMnM=
|
||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 h1:JeSE6pjso5THxAzdVpqr6/geYxZytqFMBCOtn/ujyeo=
|
||||
github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674/go.mod h1:r4w70xmWCQKmi1ONH4KIaBptdivuRPyosB9RmPlGEwA=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0/go.mod h1:JfhWUomR1baixubs02l85lZYYOm7LV6om4ceouMv45c=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||
@@ -81,6 +90,8 @@ github.com/jeremija/gosubmit v0.2.8 h1:mmSITBz9JxVtu8eqbN+zmmwX7Ij2RidQxhcwRVI4w
|
||||
github.com/jeremija/gosubmit v0.2.8/go.mod h1:Ui+HS073lCFREXBbdfrJzMB57OI/bdxTiLtrDHHhFPI=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE=
|
||||
github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
|
||||
@@ -99,13 +110,18 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
|
||||
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/mailru/easyjson v0.9.0 h1:PrnmzHw7262yW8sTBwxi1PdJA3Iw/EKBa8psRf7d9a4=
|
||||
github.com/mailru/easyjson v0.9.0/go.mod h1:1+xMtQp2MRNVL/V1bOzuP3aP8VNwRW55fQUto+XFtTU=
|
||||
github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo=
|
||||
github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg=
|
||||
github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE=
|
||||
github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A=
|
||||
github.com/moby/spdystream v0.5.0 h1:7r0J1Si3QO/kjRitvSLVVFUjxMEb/YLj6S9FF62JBCU=
|
||||
github.com/moby/spdystream v0.5.0/go.mod h1:xBAYlnt/ay+11ShkdFKNAG7LsyK/tmNBVvVOwrfMgdI=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee h1:W5t00kpgFdJifH4BDsTlE89Zl93FEloxaWZfGcifgq8=
|
||||
github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/muhlemmer/gu v0.3.1 h1:7EAqmFrW7n3hETvuAdmFmn4hS8W+z3LgKtrnow+YzNM=
|
||||
github.com/muhlemmer/gu v0.3.1/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZkrdM=
|
||||
github.com/muhlemmer/httpforwarded v0.1.0 h1:x4DLrzXdliq8mprgUMR0olDvHGkou5BJsK/vWUetyzY=
|
||||
@@ -114,10 +130,10 @@ github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq
|
||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J1GEMiLbxo1LJaP8RfCpH6pymGZus=
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0=
|
||||
github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM=
|
||||
github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU=
|
||||
github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
|
||||
github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns=
|
||||
github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo=
|
||||
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
|
||||
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
@@ -133,144 +149,153 @@ github.com/prometheus/common v0.62.0 h1:xasJaQlnWAeyHdUBeGjXmutelfJHWMRr+Fg4QszZ
|
||||
github.com/prometheus/common v0.62.0/go.mod h1:vyBcEuLSvWos9B1+CyL7JZ2up+uFzXhkqml0W5zIY1I=
|
||||
github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
||||
github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII=
|
||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
||||
github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||
github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc=
|
||||
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
|
||||
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU=
|
||||
github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
|
||||
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
|
||||
github.com/spf13/pflag v1.0.9 h1:9exaQaMOCwffKiiiYk6/BndUBv+iRViNW+4lEMi0PvY=
|
||||
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||
github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw=
|
||||
github.com/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
|
||||
github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY=
|
||||
github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
||||
github.com/x448/float16 v0.8.4/go.mod h1:14CWIYCyZA/cWjXOioeEpHeN/83MdbZDRQHoFcYsOfg=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zitadel/logging v0.6.1 h1:Vyzk1rl9Kq9RCevcpX6ujUaTYFX43aa4LkvV1TvUk+Y=
|
||||
github.com/zitadel/logging v0.6.1/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow=
|
||||
github.com/zitadel/oidc v1.13.5 h1:7jhh68NGZitLqwLiVU9Dtwa4IraJPFF1vS+4UupO93U=
|
||||
github.com/zitadel/oidc v1.13.5/go.mod h1:rHs1DhU3Sv3tnI6bQRVlFa3u0lCwtR7S21WHY+yXgPA=
|
||||
github.com/zitadel/oidc/v3 v3.36.1 h1:1AT1NqKKEqAwx4GmKJZ9fYkWH2WIn/VKMfQ46nBtRf0=
|
||||
github.com/zitadel/oidc/v3 v3.36.1/go.mod h1:dApGZLvWZTHRuxmcbQlW5d2XVjVYR3vGOdq536igmTs=
|
||||
github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0=
|
||||
github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc=
|
||||
github.com/zitadel/zitadel-go/v3 v3.5.0 h1:8LnUiOCvwhgZxwBY15tk7Yzhv5vEJF+qiM3qWJGtxCI=
|
||||
github.com/zitadel/zitadel-go/v3 v3.5.0/go.mod h1:YPfMqfpyOIuKdHNsZwWHAR/BWSIFOSIL41TyMnef/aU=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
|
||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
||||
github.com/zitadel/logging v0.7.0 h1:eugftwMM95Wgqwftsvj81isL0JK/hoScVqp/7iA2adQ=
|
||||
github.com/zitadel/logging v0.7.0/go.mod h1:9A6h9feBF/3u0IhA4uffdzSDY7mBaf7RE78H5sFMINQ=
|
||||
github.com/zitadel/oidc/v3 v3.45.5 h1:CubfcXQiqtysk+FZyIcvj1+1ayvdSV89v5xWu5asrDQ=
|
||||
github.com/zitadel/oidc/v3 v3.45.5/go.mod h1:MKHUazeiNX/jxRc6HD/Dv9qhL/wNuzrJAadBEGXiBeE=
|
||||
github.com/zitadel/schema v1.3.2 h1:gfJvt7dOMfTmxzhscZ9KkapKo3Nei3B6cAxjav+lyjI=
|
||||
github.com/zitadel/schema v1.3.2/go.mod h1:IZmdfF9Wu62Zu6tJJTH3UsArevs3Y4smfJIj3L8fzxw=
|
||||
github.com/zitadel/zitadel-go/v3 v3.27.0 h1:1BumImnIk3D9JYTq+IlVq793vZCXuMZuz1meWzeMQN4=
|
||||
github.com/zitadel/zitadel-go/v3 v3.27.0/go.mod h1:8UaWIIUR+c9jstT6bjoiknaxttxFZKNc7RYs32v03jw=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||
go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=
|
||||
go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=
|
||||
go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=
|
||||
go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||
go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=
|
||||
go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=
|
||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
||||
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
|
||||
go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
||||
go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0=
|
||||
go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8=
|
||||
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
|
||||
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
||||
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.32.0 h1:9F4d3PHLljb6x//jOyokMv3eX+YDeepZSEo3mFJy93c=
|
||||
golang.org/x/mod v0.32.0/go.mod h1:SgipZ/3h2Ci89DlEtEXWUk/HteuRin+HHhN+WbNhguU=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
|
||||
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
||||
golang.org/x/net v0.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
|
||||
golang.org/x/oauth2 v0.35.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
|
||||
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
|
||||
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
|
||||
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
|
||||
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
|
||||
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
|
||||
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
|
||||
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
|
||||
golang.org/x/tools v0.41.0/go.mod h1:XSY6eDqxVNiYgezAVqqCeihT4j1U2CCsqvH3WhQpnlg=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
|
||||
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 h1:GVIKPyP/kLIyVOgOnTwFOrvQaQUzOzGMCxgFUOEmm24=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
|
||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
||||
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
|
||||
google.golang.org/grpc v1.79.3/go.mod h1:KmT0Kjez+0dde/v2j9vzwoAScgEPx/Bw1CYChhHLrHQ=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSPG+6V4=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0 h1:czT3CmqEaQ1aanPc5SdlgQrrEIb8w/wwCvWWnfEbYzo=
|
||||
gopkg.in/evanphx/json-patch.v4 v4.13.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 h1:NGk74WTnPKBNUhNzQX7PYcTLUjoq7mzKk2OKbvwk2iI=
|
||||
gopkg.in/square/go-jose.v2 v2.6.0/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
k8s.io/api v0.32.3 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls=
|
||||
k8s.io/api v0.32.3/go.mod h1:2wEDTXADtm/HA7CCMD8D8bK4yuBUptzaRhYcYEEYA3k=
|
||||
k8s.io/api v0.35.3 h1:pA2fiBc6+N9PDf7SAiluKGEBuScsTzd2uYBkA5RzNWQ=
|
||||
k8s.io/api v0.35.3/go.mod h1:9Y9tkBcFwKNq2sxwZTQh1Njh9qHl81D0As56tu42GA4=
|
||||
k8s.io/apiextensions-apiserver v0.32.2 h1:2YMk285jWMk2188V2AERy5yDwBYrjgWYggscghPCvV4=
|
||||
k8s.io/apiextensions-apiserver v0.32.2/go.mod h1:GPwf8sph7YlJT3H6aKUWtd0E+oyShk/YHWQHf/OOgCA=
|
||||
k8s.io/apimachinery v0.32.3 h1:JmDuDarhDmA/Li7j3aPrwhpNBA94Nvk5zLeOge9HH1U=
|
||||
k8s.io/apimachinery v0.32.3/go.mod h1:GpHVgxoKlTxClKcteaeuF1Ul/lDVb74KpZcxcmLDElE=
|
||||
k8s.io/client-go v0.32.3 h1:RKPVltzopkSgHS7aS98QdscAgtgah/+zmpAogooIqVU=
|
||||
k8s.io/client-go v0.32.3/go.mod h1:3v0+3k4IcT9bXTc4V2rt+d2ZPPG700Xy6Oi0Gdl2PaY=
|
||||
k8s.io/apimachinery v0.35.3 h1:MeaUwQCV3tjKP4bcwWGgZ/cp/vpsRnQzqO6J6tJyoF8=
|
||||
k8s.io/apimachinery v0.35.3/go.mod h1:jQCgFZFR1F4Ik7hvr2g84RTJSZegBc8yHgFWKn//hns=
|
||||
k8s.io/client-go v0.35.3 h1:s1lZbpN4uI6IxeTM2cpdtrwHcSOBML1ODNTCCfsP1pg=
|
||||
k8s.io/client-go v0.35.3/go.mod h1:RzoXkc0mzpWIDvBrRnD+VlfXP+lRzqQjCmKtiwZ8Q9c=
|
||||
k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk=
|
||||
k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE=
|
||||
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8XWMxCxzQx42DY8QKYJrDLg=
|
||||
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas=
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
|
||||
k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE=
|
||||
k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ=
|
||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck=
|
||||
k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
|
||||
sigs.k8s.io/controller-runtime v0.20.4 h1:X3c+Odnxz+iPTRobG4tp092+CvBU9UK0t/bRf+n0DGU=
|
||||
sigs.k8s.io/controller-runtime v0.20.4/go.mod h1:xg2XB0K5ShQzAgsoujxuKN4LNXR2LfwwHsPj7Iaw+XY=
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
|
||||
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.5.0 h1:nbCitCK2hfnhyiKo6uf2HxUPTCodY6Qaf85SbDIaMBk=
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.5.0/go.mod h1:N8f93tFZh9U6vpxwRArLiikrE5/2tiu1w1AGfACIGE4=
|
||||
sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E=
|
||||
sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY=
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg=
|
||||
sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg=
|
||||
sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU=
|
||||
sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0 h1:jTijUJbW353oVOd9oTlifJqOGEkUw2jB/fXCbTiQEco=
|
||||
sigs.k8s.io/structured-merge-diff/v6 v6.3.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE=
|
||||
sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs=
|
||||
sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4=
|
||||
472
internal/controller/cluster_controller.go
Normal file
472
internal/controller/cluster_controller.go
Normal file
@@ -0,0 +1,472 @@
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
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 controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"encoding/base64"
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
builder "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder"
|
||||
condition "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/condition"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/configuration"
|
||||
configmap "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/controller/configmap"
|
||||
secret "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/controller/secret"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/controller/service"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/deployment"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/masterkey"
|
||||
systemapiaccount "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/systemapi"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
"k8s.io/utils/ptr"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
)
|
||||
|
||||
type reconcilePhase struct {
|
||||
Name string
|
||||
Reconcile func(context.Context, *zitadelv1alpha1.Cluster) (ctrl.Result, error)
|
||||
}
|
||||
|
||||
type patcher func(*zitadelv1alpha1.ClusterStatus) error
|
||||
|
||||
// ClusterReconciler reconciles a Cluster object
|
||||
type ClusterReconciler struct {
|
||||
client.Client
|
||||
Scheme *runtime.Scheme
|
||||
ConditionReady *condition.Ready
|
||||
Builder *builder.Builder
|
||||
SecretReconciler *secret.SecretReconciler
|
||||
ConfigMapReconciler *configmap.ConfigMapReconciler
|
||||
ServiceReconciler *service.ServiceReconciler
|
||||
RefResolver *zitadelv1alpha1.RefResolver
|
||||
}
|
||||
|
||||
// +kubebuilder:rbac:groups="",resources=configmaps,verbs=get;list;watch;create;patch
|
||||
// +kubebuilder:rbac:groups="",resources=services,verbs=list;watch;create;patch
|
||||
// +kubebuilder:rbac:groups="",resources=secrets,verbs=list;watch;create;patch
|
||||
// +kubebuilder:rbac:groups="",resources=endpoints,verbs=create;patch;get;list;watch
|
||||
// +kubebuilder:rbac:groups="",resources=endpoints/restricted,verbs=create;patch;get;list;watch
|
||||
// +kubebuilder:rbac:groups="",resources=pods,verbs=get;delete
|
||||
// +kubebuilder:rbac:groups="",resources=events,verbs=list;watch;create;patch
|
||||
// +kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=list;watch;create;patch
|
||||
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=list;watch;create;patch
|
||||
// +kubebuilder:rbac:groups=apps,resources=deployments,verbs=list;watch;create;patch
|
||||
// +kubebuilder:rbac:groups=policy,resources=poddisruptionbudgets,verbs=list;watch;create;patch
|
||||
// +kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=roles;rolebindings;clusterrolebindings,verbs=list;watch;create;patch
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=clusters,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=clusters/status,verbs=get;update;patch
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=clusters/finalizers,verbs=update
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=instances,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=instances/status,verbs=get;update;patch
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=instances/finalizers,verbs=update
|
||||
// +kubebuilder:rbac:groups=postgresql.cnpg.io,resources=clusters,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=postgresql.cnpg.io,resources=clusters/status,verbs=get;update;patch
|
||||
// +kubebuilder:rbac:groups=postgresql.cnpg.io,resources=clusters/finalizers,verbs=update
|
||||
// +kubebuilder:rbac:groups=certificates.k8s.io,resources=certificatesigningrequests,verbs=get;list;watch;create;patch;delete
|
||||
// +kubebuilder:rbac:groups=certificates.k8s.io,resources=certificatesigningrequests/status,verbs=get;update;patch
|
||||
// +kubebuilder:rbac:groups=certificates.k8s.io,resources=certificatesigningrequests/approval,verbs=update
|
||||
// +kubebuilder:rbac:groups=batch,resources=jobs,verbs=get;list;watch;create;update;patch;delete
|
||||
|
||||
func (r *ClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||
logger := log.FromContext(ctx)
|
||||
logger.Info("Starting Reconcile")
|
||||
|
||||
var zitadel zitadelv1alpha1.Cluster
|
||||
|
||||
if err := r.Get(ctx, req.NamespacedName, &zitadel); err != nil {
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
|
||||
phases := []reconcilePhase{
|
||||
{
|
||||
Name: "Spec",
|
||||
Reconcile: r.setSpecDefaults,
|
||||
},
|
||||
{
|
||||
Name: "Status",
|
||||
Reconcile: r.setStatusDefaults,
|
||||
},
|
||||
{
|
||||
Name: "MasterkeySecret",
|
||||
Reconcile: r.reconcileMasterKeySecret,
|
||||
},
|
||||
{
|
||||
Name: "ServiceAccount",
|
||||
Reconcile: r.reconcileSystemAPIUser,
|
||||
},
|
||||
{
|
||||
Name: "Configuration",
|
||||
Reconcile: r.reconcileConfig,
|
||||
},
|
||||
{
|
||||
Name: "InitJob",
|
||||
Reconcile: r.reconcileInitJob,
|
||||
},
|
||||
{
|
||||
Name: "SetupJob",
|
||||
Reconcile: r.reconcileSetupJob,
|
||||
},
|
||||
{
|
||||
Name: "Deployment",
|
||||
Reconcile: r.reconcileDeployment,
|
||||
},
|
||||
{
|
||||
Name: "Service",
|
||||
Reconcile: r.reconcileService,
|
||||
},
|
||||
}
|
||||
|
||||
for _, p := range phases {
|
||||
result, err := p.Reconcile(ctx, &zitadel)
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
continue
|
||||
}
|
||||
|
||||
var errBundle *multierror.Error
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
msg := fmt.Sprintf("Error reconciling %s: %v", p.Name, err)
|
||||
patchErr := r.patchStatus(ctx, &zitadel, func(s *zitadelv1alpha1.ClusterStatus) error {
|
||||
patcher := r.ConditionReady.PatcherFailed(msg)
|
||||
patcher(s)
|
||||
return nil
|
||||
})
|
||||
if errors.IsNotFound(patchErr) {
|
||||
errBundle = multierror.Append(errBundle, patchErr)
|
||||
}
|
||||
|
||||
if err := errBundle.ErrorOrNil(); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error reconciling %s: %v", p.Name, err)
|
||||
}
|
||||
}
|
||||
if !result.IsZero() {
|
||||
return result, err
|
||||
}
|
||||
}
|
||||
|
||||
if err := r.patchStatus(ctx, &zitadel, r.patcher(ctx, &zitadel)); err != nil && !errors.IsNotFound(err) {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
return ctrl.Result{RequeueAfter: 15 * time.Minute}, nil
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) setSpecDefaults(ctx context.Context, zitadel *zitadelv1alpha1.Cluster) (ctrl.Result, error) {
|
||||
return ctrl.Result{}, r.patch(ctx, zitadel, func(zit *zitadelv1alpha1.Cluster) {
|
||||
zit.SetDefaults()
|
||||
})
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) setStatusDefaults(ctx context.Context, zitadel *zitadelv1alpha1.Cluster) (ctrl.Result, error) {
|
||||
return ctrl.Result{}, r.patchStatus(ctx, zitadel, func(status *zitadelv1alpha1.ClusterStatus) error {
|
||||
status.FillWithDefaults(zitadel)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) reconcileMasterKeySecret(ctx context.Context, zitadel *zitadelv1alpha1.Cluster) (ctrl.Result, error) {
|
||||
secretName := masterkey.MasterKeyName(zitadel)
|
||||
key := types.NamespacedName{
|
||||
Name: secretName,
|
||||
Namespace: zitadel.Namespace,
|
||||
}
|
||||
_, err := r.SecretReconciler.ReconcileRandomPassword(ctx, key, masterkey.Key, zitadel)
|
||||
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) reconcileSystemAPIUser(ctx context.Context, zitadel *zitadelv1alpha1.Cluster) (ctrl.Result, error) {
|
||||
secretName := systemapiaccount.SystemAPIAccountName(zitadel)
|
||||
key := types.NamespacedName{
|
||||
Name: secretName,
|
||||
Namespace: zitadel.Namespace,
|
||||
}
|
||||
_, err := r.SecretReconciler.ReconcileRandomPrivateRSA(ctx, key, systemapiaccount.Key, zitadel)
|
||||
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) reconcileConfig(ctx context.Context, zitadel *zitadelv1alpha1.Cluster) (ctrl.Result, error) {
|
||||
postgres, err := r.RefResolver.PostgreSQLClusterRef(ctx, &zitadel.Spec.PostgreSQLClusterRef, zitadel.Namespace)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
configName := configuration.ConfigurationName(zitadel)
|
||||
key := types.NamespacedName{
|
||||
Name: configName,
|
||||
Namespace: zitadel.Namespace,
|
||||
}
|
||||
privateKeyData, err := r.RefResolver.SecretKeyRef(ctx, corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: systemapiaccount.SystemAPIAccountName(zitadel)}, Key: systemapiaccount.Key}, zitadel.Namespace)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
pemBlock, _ := pem.Decode([]byte(privateKeyData))
|
||||
if pemBlock == nil {
|
||||
return ctrl.Result{}, fmt.Errorf("failed to decode PEM block")
|
||||
}
|
||||
privateKey, err := x509.ParsePKCS1PrivateKey(pemBlock.Bytes)
|
||||
publicKeyBytes, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
publicKeyPem := pem.EncodeToMemory(
|
||||
&pem.Block{
|
||||
Type: "RSA PUBLIC KEY",
|
||||
Bytes: publicKeyBytes,
|
||||
},
|
||||
)
|
||||
base64key := base64.StdEncoding.EncodeToString(publicKeyPem)
|
||||
err = r.ConfigMapReconciler.ReconcileZitadelConfiguration(ctx, key, zitadel, postgres, base64key)
|
||||
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) reconcileInitJob(ctx context.Context, zitadel *zitadelv1alpha1.Cluster) (ctrl.Result, error) {
|
||||
key := client.ObjectKeyFromObject(zitadel)
|
||||
key.Name = "init-job-" + key.Name
|
||||
|
||||
// Build the desired job
|
||||
desiredInitJob, err := r.Builder.BuildInitJob(zitadel, key)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error building InitJob: %v", err)
|
||||
}
|
||||
|
||||
var existingJob batchv1.Job
|
||||
err = r.Get(ctx, key, &existingJob)
|
||||
if err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
return ctrl.Result{}, fmt.Errorf("error getting InitJob: %v", err)
|
||||
}
|
||||
// If job is not found, create the job
|
||||
if err := r.Create(ctx, desiredInitJob); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error creating InitJob: %v", err)
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// Compare the image in the existing job with the desired image
|
||||
existingImage := existingJob.Spec.Template.Spec.Containers[0].Image
|
||||
desiredImage := desiredInitJob.Spec.Template.Spec.Containers[0].Image
|
||||
|
||||
// If the images don't match, delete the existing job and wait for deletion
|
||||
if existingImage != desiredImage {
|
||||
|
||||
if err := r.Delete(ctx, &existingJob); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error deleting existing InitJob: %v", err)
|
||||
}
|
||||
|
||||
// Wait for the job to be fully deleted before creating a new one
|
||||
for {
|
||||
err := r.Get(ctx, key, &existingJob)
|
||||
if errors.IsNotFound(err) {
|
||||
break // Job has been deleted, we can proceed
|
||||
}
|
||||
if err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error checking if InitJob is deleted: %v", err)
|
||||
}
|
||||
// Sleep for a short interval to avoid tight loop
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
// Now create the new job
|
||||
if err := r.Create(ctx, desiredInitJob); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error creating new InitJob: %v", err)
|
||||
}
|
||||
}
|
||||
if err := r.Get(ctx, key, &existingJob); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error fetching existing InitJob status: %v", err)
|
||||
}
|
||||
|
||||
if existingJob.Status.Succeeded != 1 { // Replace with actual success condition
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
// If the job exists and the image matches, no action is needed
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) reconcileSetupJob(ctx context.Context, zitadel *zitadelv1alpha1.Cluster) (ctrl.Result, error) {
|
||||
key := client.ObjectKeyFromObject(zitadel)
|
||||
key.Name = "setup-job-" + key.Name
|
||||
|
||||
// Build the desired job
|
||||
desiredSetupJob, err := r.Builder.BuildSetupJob(zitadel, key)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error building SetupJob: %v", err)
|
||||
}
|
||||
|
||||
var existingJob batchv1.Job
|
||||
err = r.Get(ctx, key, &existingJob)
|
||||
if err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
return ctrl.Result{}, fmt.Errorf("error getting SetupJob: %v", err)
|
||||
}
|
||||
// If job is not found, create the job
|
||||
if err := r.Create(ctx, desiredSetupJob); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error creating SetupJob: %v", err)
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
// Compare the image in the existing job with the desired image
|
||||
existingImage := existingJob.Spec.Template.Spec.Containers[0].Image
|
||||
desiredImage := desiredSetupJob.Spec.Template.Spec.Containers[0].Image
|
||||
|
||||
// If the images don't match, delete the existing job and wait for deletion
|
||||
if existingImage != desiredImage {
|
||||
|
||||
if err := r.Delete(ctx, &existingJob); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error deleting existing SetupJob: %v", err)
|
||||
}
|
||||
|
||||
// Wait for the job to be fully deleted before creating a new one
|
||||
for {
|
||||
err := r.Get(ctx, key, &existingJob)
|
||||
if errors.IsNotFound(err) {
|
||||
break // Job has been deleted, we can proceed
|
||||
}
|
||||
if err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error checking if SetupJob is deleted: %v", err)
|
||||
}
|
||||
// Sleep for a short interval to avoid tight loop
|
||||
time.Sleep(1 * time.Second)
|
||||
}
|
||||
|
||||
// Now create the new job
|
||||
if err := r.Create(ctx, desiredSetupJob); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error creating new SetupJob: %v", err)
|
||||
}
|
||||
}
|
||||
if err := r.Get(ctx, key, &existingJob); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error fetching existing SetupJob status: %v", err)
|
||||
}
|
||||
|
||||
if existingJob.Status.Succeeded != 1 { // Replace with actual success condition
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
// If the job exists and the image matches, no action is needed
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) reconcileDeployment(ctx context.Context, zitadel *zitadelv1alpha1.Cluster) (ctrl.Result, error) {
|
||||
// TODO: Reload on config changed
|
||||
key := client.ObjectKeyFromObject(zitadel)
|
||||
desiredSts, err := r.Builder.BuildDeployment(zitadel, key)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error building Deployment: %v", err)
|
||||
}
|
||||
var existingDep appsv1.Deployment
|
||||
if err := r.Get(ctx, key, &existingDep); err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
return ctrl.Result{}, fmt.Errorf("error getting Deployment: %v", err)
|
||||
}
|
||||
if err := r.Create(ctx, desiredSts); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error creating Deployment: %v", err)
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
patch := client.MergeFrom(existingDep.DeepCopy())
|
||||
existingDep.Spec.Template = desiredSts.Spec.Template
|
||||
existingDep.Spec.Replicas = desiredSts.Spec.Replicas
|
||||
return ctrl.Result{}, r.Patch(ctx, &existingDep, patch)
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) reconcileService(ctx context.Context, zitadel *zitadelv1alpha1.Cluster) (ctrl.Result, error) {
|
||||
return ctrl.Result{}, r.reconcileDefaultService(ctx, zitadel)
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) reconcileDefaultService(ctx context.Context, zitadel *zitadelv1alpha1.Cluster) error {
|
||||
key := client.ObjectKeyFromObject(zitadel)
|
||||
opts := builder.ServiceOpts{
|
||||
Ports: []corev1.ServicePort{
|
||||
{
|
||||
Name: deployment.ZitadelName,
|
||||
Port: deployment.ZitadelPort,
|
||||
AppProtocol: ptr.To("h2c"),
|
||||
},
|
||||
},
|
||||
}
|
||||
desiredSvc, err := r.Builder.BuildService(zitadel, key, opts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building Service: %v", err)
|
||||
}
|
||||
return r.ServiceReconciler.Reconcile(ctx, desiredSvc)
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) patchStatus(ctx context.Context, zitadel *zitadelv1alpha1.Cluster,
|
||||
patcher patcher) error {
|
||||
patch := client.MergeFrom(zitadel.DeepCopy())
|
||||
if err := patcher(&zitadel.Status); err != nil {
|
||||
return err
|
||||
}
|
||||
return r.Status().Patch(ctx, zitadel, patch)
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) patcher(ctx context.Context, zitadel *zitadelv1alpha1.Cluster) patcher {
|
||||
return func(s *zitadelv1alpha1.ClusterStatus) error {
|
||||
var sts appsv1.Deployment
|
||||
if err := r.Get(ctx, client.ObjectKeyFromObject(zitadel), &sts); err != nil {
|
||||
return err
|
||||
}
|
||||
zitadel.Status.Replicas = sts.Status.ReadyReplicas
|
||||
|
||||
condition.SetReadyWithDeployment(&zitadel.Status, &sts)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ClusterReconciler) patch(ctx context.Context, zitadel *zitadelv1alpha1.Cluster,
|
||||
patcher func(*zitadelv1alpha1.Cluster)) error {
|
||||
patch := client.MergeFrom(zitadel.DeepCopy())
|
||||
patcher(zitadel)
|
||||
return r.Patch(ctx, zitadel, patch)
|
||||
}
|
||||
|
||||
// SetupWithManager sets up the controller with the Manager.
|
||||
func (r *ClusterReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
For(&zitadelv1alpha1.Cluster{}).
|
||||
Owns(&appsv1.Deployment{}).
|
||||
Owns(&corev1.Service{}).
|
||||
Owns(&corev1.ConfigMap{}).
|
||||
Owns(&corev1.Secret{}).
|
||||
WithOptions(controller.Options{RateLimiter: workqueue.NewTypedItemExponentialFailureRateLimiter[reconcile.Request](time.Millisecond*500, time.Minute*3)}).
|
||||
Complete(r)
|
||||
}
|
||||
402
internal/controller/instance_controller.go
Normal file
402
internal/controller/instance_controller.go
Normal file
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
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 controller
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
condition "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/condition"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/controller/service"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/controller/system"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/deployment"
|
||||
zitadelresourcesv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-resources-operator/api/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
ctrlClient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
systemClient "github.com/zitadel/zitadel-go/v3/pkg/client/system"
|
||||
authn "github.com/zitadel/zitadel-go/v3/pkg/client/zitadel/authn"
|
||||
pb "github.com/zitadel/zitadel-go/v3/pkg/client/zitadel/system"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
"k8s.io/apimachinery/pkg/api/errors"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/util/workqueue"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller"
|
||||
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
||||
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder"
|
||||
)
|
||||
|
||||
// InstanceReconciler reconciles a Instance object
|
||||
type InstanceReconciler struct {
|
||||
client.Client
|
||||
RefResolver *zitadelv1alpha1.RefResolver
|
||||
ConditionReady *condition.Ready
|
||||
RequeueInterval time.Duration
|
||||
Builder *builder.Builder
|
||||
ServiceReconciler *service.ServiceReconciler
|
||||
}
|
||||
|
||||
func NewInstanceReconciler(client client.Client, refResolver *zitadelv1alpha1.RefResolver,
|
||||
builder *builder.Builder,
|
||||
conditionReady *condition.Ready,
|
||||
serviceReconciler *service.ServiceReconciler,
|
||||
requeueInterval time.Duration) *InstanceReconciler {
|
||||
return &InstanceReconciler{
|
||||
Client: client,
|
||||
RefResolver: refResolver,
|
||||
ConditionReady: conditionReady,
|
||||
RequeueInterval: requeueInterval,
|
||||
ServiceReconciler: serviceReconciler,
|
||||
Builder: builder,
|
||||
}
|
||||
}
|
||||
|
||||
//+kubebuilder:rbac:groups=zitadel.topmanage.com,resources=instances,verbs=get;list;watch;create;update;patch;delete
|
||||
//+kubebuilder:rbac:groups=zitadel.topmanage.com,resources=instances/status,verbs=get;update;patch
|
||||
//+kubebuilder:rbac:groups=zitadel.topmanage.com,resources=instances/finalizers,verbs=update
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=machineusers,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=machineusers/status,verbs=get;update;patch
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=machineusers/finalizers,verbs=update
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=connections,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=connections/status,verbs=get;update;patch
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=connections/finalizers,verbs=update
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=organizations,verbs=get;list;watch;create;update;patch;delete
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=organizations/status,verbs=get;update;patch
|
||||
// +kubebuilder:rbac:groups=zitadel.github.com,resources=organizations/finalizers,verbs=update
|
||||
|
||||
// Reconcile is part of the main kubernetes reconciliation loop which aims to
|
||||
// move the current state of the cluster closer to the desired state.
|
||||
func (r *InstanceReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
|
||||
var instance zitadelv1alpha1.Instance
|
||||
if err := r.Get(ctx, req.NamespacedName, &instance); err != nil {
|
||||
return ctrl.Result{}, client.IgnoreNotFound(err)
|
||||
}
|
||||
wr := newWrappedInstanceReconciler(r.Client, r.RefResolver, r.Builder, r.ServiceReconciler, &instance)
|
||||
wf := newWrappedInstanceFinalizer(r.Client, &instance)
|
||||
tf := system.NewSystemFinalizer(r.Client, wf)
|
||||
tr := system.NewSystemReconciler(r.Client, r.ConditionReady, wr, tf, r.RequeueInterval)
|
||||
|
||||
result, err := tr.Reconcile(ctx, &instance)
|
||||
if err != nil {
|
||||
return result, fmt.Errorf("error reconciling in InstanceReconciler: %v", err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type wrappedInstanceReconciler struct {
|
||||
client.Client
|
||||
refResolver *zitadelv1alpha1.RefResolver
|
||||
instance *zitadelv1alpha1.Instance
|
||||
Builder *builder.Builder
|
||||
ServiceReconciler *service.ServiceReconciler
|
||||
}
|
||||
|
||||
func newWrappedInstanceReconciler(client client.Client, refResolver *zitadelv1alpha1.RefResolver, builder *builder.Builder,
|
||||
serviceReconciler *service.ServiceReconciler,
|
||||
instance *zitadelv1alpha1.Instance) system.WrappedSystemReconciler {
|
||||
return &wrappedInstanceReconciler{
|
||||
Client: client,
|
||||
refResolver: refResolver,
|
||||
instance: instance,
|
||||
Builder: builder,
|
||||
ServiceReconciler: serviceReconciler,
|
||||
}
|
||||
}
|
||||
|
||||
type instanceReconcilePhase struct {
|
||||
Name string
|
||||
Reconcile func(context.Context, *systemClient.Client) error
|
||||
}
|
||||
|
||||
func (wr *wrappedInstanceReconciler) Reconcile(ctx context.Context, ztdClient *systemClient.Client) error {
|
||||
phases := []instanceReconcilePhase{
|
||||
{
|
||||
Name: "instance",
|
||||
Reconcile: wr.reconcileInstance,
|
||||
},
|
||||
{
|
||||
Name: "connection",
|
||||
Reconcile: wr.reconcileConnection,
|
||||
},
|
||||
{
|
||||
Name: "organization",
|
||||
Reconcile: wr.reconcileFirstOrganization,
|
||||
},
|
||||
{
|
||||
Name: "loginUIMachineUser",
|
||||
Reconcile: wr.reconcileLoginUIMachineUser,
|
||||
},
|
||||
{
|
||||
Name: "loginUIDeployment",
|
||||
Reconcile: wr.reconcileLoginUIDeployment,
|
||||
},
|
||||
{
|
||||
Name: "loginUIService",
|
||||
Reconcile: wr.reconcileLoginUIService,
|
||||
},
|
||||
}
|
||||
for _, p := range phases {
|
||||
err := p.Reconcile(ctx, ztdClient)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wr *wrappedInstanceReconciler) reconcileInstance(ctx context.Context, ztdClient *systemClient.Client) error {
|
||||
var instanceId *string
|
||||
if wr.instance.Status.InstanceId != nil {
|
||||
getInstanceRes, err := ztdClient.GetInstance(ctx, &pb.GetInstanceRequest{InstanceId: *wr.instance.Status.InstanceId})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error getting Instance: %v", err)
|
||||
}
|
||||
if getInstanceRes.Instance != nil {
|
||||
instanceId = &getInstanceRes.Instance.Id
|
||||
}
|
||||
}
|
||||
if instanceId == nil {
|
||||
createInstanceRes, err := ztdClient.CreateInstance(ctx, &pb.CreateInstanceRequest{
|
||||
InstanceName: wr.instance.Spec.InstanceName,
|
||||
FirstOrgName: wr.instance.Spec.Org.Name,
|
||||
CustomDomain: wr.instance.Spec.CustomDomain,
|
||||
DefaultLanguage: wr.instance.Spec.DefaultLanguage,
|
||||
Owner: &pb.CreateInstanceRequest_Machine_{
|
||||
Machine: &pb.CreateInstanceRequest_Machine{
|
||||
UserName: wr.instance.MachineUserName(),
|
||||
Name: wr.instance.MachineName(),
|
||||
PersonalAccessToken: &pb.CreateInstanceRequest_PersonalAccessToken{
|
||||
ExpirationDate: nil,
|
||||
},
|
||||
MachineKey: &pb.CreateInstanceRequest_MachineKey{
|
||||
ExpirationDate: nil,
|
||||
Type: authn.KeyType_KEY_TYPE_JSON,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("Error creating Instance: %v", err)
|
||||
}
|
||||
|
||||
key := types.NamespacedName{
|
||||
Name: wr.instance.MachineSecretName(),
|
||||
Namespace: wr.instance.Namespace,
|
||||
}
|
||||
secretData := map[string][]byte{
|
||||
"pat": []byte(createInstanceRes.Pat),
|
||||
"machinekey": createInstanceRes.MachineKey,
|
||||
}
|
||||
secret, err := wr.Builder.BuildSecret(builder.SecretOpts{Key: key, Data: secretData}, wr.instance)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building instance machine Secret: %v", err)
|
||||
}
|
||||
|
||||
if err := wr.Create(ctx, secret); err != nil {
|
||||
return fmt.Errorf("error creating machinekey Secret: %v", err)
|
||||
}
|
||||
instanceId = &createInstanceRes.InstanceId
|
||||
}
|
||||
patch := ctrlClient.MergeFrom(wr.instance.DeepCopy())
|
||||
wr.instance.Status.InstanceId = instanceId
|
||||
return wr.Client.Status().Patch(ctx, wr.instance, patch)
|
||||
}
|
||||
|
||||
func (wr *wrappedInstanceReconciler) reconcileConnection(ctx context.Context, ztdClient *systemClient.Client) error {
|
||||
key := types.NamespacedName{
|
||||
Name: wr.instance.ConnectionObjectName(),
|
||||
Namespace: wr.instance.Namespace,
|
||||
}
|
||||
desiredConnection, err := wr.Builder.BuildConnection(key, wr.instance)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building Initial Connectionanization: %v", err)
|
||||
}
|
||||
|
||||
var existingConnection zitadelresourcesv1alpha1.Connection
|
||||
if err := wr.Get(ctx, key, &existingConnection); err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
return fmt.Errorf("error getting Initial Connectionanization: %v", err)
|
||||
}
|
||||
if err := wr.Create(ctx, desiredConnection); err != nil {
|
||||
return fmt.Errorf("error creating Initial Connectionanization: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
patch := client.MergeFrom(existingConnection.DeepCopy())
|
||||
existingConnection.Spec.Host = desiredConnection.Spec.Host
|
||||
existingConnection.Spec.Authentication = desiredConnection.Spec.Authentication
|
||||
return wr.Patch(ctx, &existingConnection, patch)
|
||||
}
|
||||
|
||||
func (wr *wrappedInstanceReconciler) reconcileFirstOrganization(ctx context.Context, ztdClient *systemClient.Client) error {
|
||||
key := types.NamespacedName{
|
||||
Name: wr.instance.FirstOrgObjectName(),
|
||||
Namespace: wr.instance.Namespace,
|
||||
}
|
||||
desiredOrg, err := wr.Builder.BuildOrganization(builder.OrganizationOpts{Key: key, Zitadel: wr.instance, OrganizationName: wr.instance.Spec.Org.Name}, wr.instance)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building Initial Organization: %v", err)
|
||||
}
|
||||
|
||||
var existingOrg zitadelresourcesv1alpha1.Organization
|
||||
if err := wr.Get(ctx, key, &existingOrg); err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
return fmt.Errorf("error getting Initial Organization: %v", err)
|
||||
}
|
||||
if err := wr.Create(ctx, desiredOrg); err != nil {
|
||||
return fmt.Errorf("error creating Initial Organization: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
patch := client.MergeFrom(existingOrg.DeepCopy())
|
||||
existingOrg.Spec.OrganzationName = desiredOrg.Spec.OrganzationName
|
||||
return wr.Patch(ctx, &existingOrg, patch)
|
||||
}
|
||||
|
||||
func (wr *wrappedInstanceReconciler) reconcileLoginUIMachineUser(ctx context.Context, ztdClient *systemClient.Client) error {
|
||||
key := types.NamespacedName{
|
||||
Name: wr.instance.LoginMachineUserName(),
|
||||
Namespace: wr.instance.Namespace,
|
||||
}
|
||||
|
||||
desiredMachineUser, err := wr.Builder.BuildMachineUser(key, builder.MachineUserOpts{Instance: wr.instance,
|
||||
InternalPermissions: []zitadelresourcesv1alpha1.InternalPermissions{
|
||||
{
|
||||
|
||||
Resource: zitadelresourcesv1alpha1.Resource{
|
||||
Instance: &zitadelresourcesv1alpha1.InstanceResource{},
|
||||
},
|
||||
Roles: []string{
|
||||
"IAM_LOGIN_CLIENT",
|
||||
},
|
||||
},
|
||||
},
|
||||
Username: "login-ui",
|
||||
}, wr.instance)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building LoginUI MachineUser: %v", err)
|
||||
}
|
||||
|
||||
var existingMachineUser zitadelresourcesv1alpha1.MachineUser
|
||||
if err := wr.Get(ctx, key, &existingMachineUser); err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
return fmt.Errorf("error getting MachineUser: %v", err)
|
||||
}
|
||||
if err := wr.Create(ctx, desiredMachineUser); err != nil {
|
||||
return fmt.Errorf("error creating MachineUser: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
patch := client.MergeFrom(existingMachineUser.DeepCopy())
|
||||
existingMachineUser.Spec.Authorizations = desiredMachineUser.Spec.Authorizations
|
||||
existingMachineUser.Spec.InternalPermissions = desiredMachineUser.Spec.InternalPermissions
|
||||
existingMachineUser.Spec.Metadata = desiredMachineUser.Spec.Metadata
|
||||
return wr.Patch(ctx, &existingMachineUser, patch)
|
||||
}
|
||||
|
||||
func (wr *wrappedInstanceReconciler) reconcileLoginUIDeployment(ctx context.Context, ztdClient *systemClient.Client) error {
|
||||
if wr.instance.Status.InstanceId == nil {
|
||||
return fmt.Errorf("Instance not ready...")
|
||||
}
|
||||
cluster, err := wr.refResolver.Cluster(ctx, &wr.instance.Spec.ClusterRef, wr.instance.Namespace)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key := client.ObjectKeyFromObject(wr.instance)
|
||||
key.Name = key.Name + "-login-ui"
|
||||
|
||||
instanceRes, err := ztdClient.GetInstance(ctx, &pb.GetInstanceRequest{InstanceId: *wr.instance.Status.InstanceId})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var customDomain string
|
||||
for _, d := range instanceRes.Instance.Domains {
|
||||
if d.Primary {
|
||||
customDomain = d.Domain
|
||||
break
|
||||
}
|
||||
}
|
||||
desiredSts, err := wr.Builder.BuildLoginDeployment(cluster, wr.instance, customDomain, key)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building Login UI Deployment: %v", err)
|
||||
}
|
||||
var existingDep appsv1.Deployment
|
||||
if err := wr.Get(ctx, key, &existingDep); err != nil {
|
||||
if !errors.IsNotFound(err) {
|
||||
return fmt.Errorf("error getting Login UI Deployment: %v", err)
|
||||
}
|
||||
if err := wr.Create(ctx, desiredSts); err != nil {
|
||||
return fmt.Errorf("error creating Login UI Deployment: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
patch := client.MergeFrom(existingDep.DeepCopy())
|
||||
existingDep.Spec.Template = desiredSts.Spec.Template
|
||||
existingDep.Spec.Replicas = desiredSts.Spec.Replicas
|
||||
return wr.Patch(ctx, &existingDep, patch)
|
||||
}
|
||||
|
||||
func (wr *wrappedInstanceReconciler) reconcileLoginUIService(ctx context.Context, ztdClient *systemClient.Client) error {
|
||||
key := client.ObjectKeyFromObject(wr.instance)
|
||||
key.Name = key.Name + "-login-ui"
|
||||
opts := builder.ServiceOpts{
|
||||
Ports: []corev1.ServicePort{
|
||||
{
|
||||
Name: deployment.LoginName,
|
||||
Port: deployment.LoginPort,
|
||||
},
|
||||
},
|
||||
}
|
||||
desiredSvc, err := wr.Builder.BuildLoginService(wr.instance, key, opts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error building Service: %v", err)
|
||||
}
|
||||
return wr.ServiceReconciler.Reconcile(ctx, desiredSvc)
|
||||
}
|
||||
|
||||
func (wr *wrappedInstanceReconciler) PatchStatus(ctx context.Context, patcher condition.Patcher) error {
|
||||
patch := client.MergeFrom(wr.instance.DeepCopy())
|
||||
patcher(&wr.instance.Status)
|
||||
|
||||
if err := wr.Client.Status().Patch(ctx, wr.instance, patch); err != nil {
|
||||
return fmt.Errorf("error patching Instance status: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetupWithManager sets up the controller with the Manager.
|
||||
func (r *InstanceReconciler) SetupWithManager(mgr ctrl.Manager) error {
|
||||
return ctrl.NewControllerManagedBy(mgr).
|
||||
For(&zitadelv1alpha1.Instance{}).
|
||||
Owns(&corev1.Secret{}).
|
||||
Owns(&appsv1.Deployment{}).
|
||||
Owns(&corev1.Service{}).
|
||||
Owns(&zitadelresourcesv1alpha1.Connection{}).
|
||||
Owns(&zitadelresourcesv1alpha1.Organization{}).
|
||||
Owns(&zitadelresourcesv1alpha1.MachineUser{}).
|
||||
WithOptions(controller.Options{RateLimiter: workqueue.NewTypedItemExponentialFailureRateLimiter[reconcile.Request](time.Millisecond*500, time.Minute*3)}).
|
||||
Complete(r)
|
||||
}
|
||||
74
internal/controller/instance_controller_finalizer.go
Normal file
74
internal/controller/instance_controller_finalizer.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package controller
|
||||
|
||||
import (
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/controller/system"
|
||||
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
systemClient "github.com/zitadel/zitadel-go/v3/pkg/client/system"
|
||||
pb "github.com/zitadel/zitadel-go/v3/pkg/client/zitadel/system"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
ctrlClient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
const (
|
||||
instanceFinalizerName = "instance.zitadel.github.com/instance"
|
||||
)
|
||||
|
||||
type wrappedInstanceFinalizer struct {
|
||||
client.Client
|
||||
instance *zitadelv1alpha1.Instance
|
||||
}
|
||||
|
||||
func newWrappedInstanceFinalizer(client client.Client, instance *zitadelv1alpha1.Instance) system.WrappedSystemFinalizer {
|
||||
return &wrappedInstanceFinalizer{
|
||||
Client: client,
|
||||
instance: instance,
|
||||
}
|
||||
}
|
||||
|
||||
func (wf *wrappedInstanceFinalizer) AddFinalizer(ctx context.Context) error {
|
||||
if wf.ContainsFinalizer() {
|
||||
return nil
|
||||
}
|
||||
return wf.patch(ctx, wf.instance, func(instance *zitadelv1alpha1.Instance) {
|
||||
controllerutil.AddFinalizer(instance, instanceFinalizerName)
|
||||
})
|
||||
}
|
||||
|
||||
func (wf *wrappedInstanceFinalizer) RemoveFinalizer(ctx context.Context) error {
|
||||
if !wf.ContainsFinalizer() {
|
||||
return nil
|
||||
}
|
||||
return wf.patch(ctx, wf.instance, func(instance *zitadelv1alpha1.Instance) {
|
||||
controllerutil.RemoveFinalizer(wf.instance, instanceFinalizerName)
|
||||
})
|
||||
}
|
||||
|
||||
func (wr *wrappedInstanceFinalizer) ContainsFinalizer() bool {
|
||||
return controllerutil.ContainsFinalizer(wr.instance, instanceFinalizerName)
|
||||
}
|
||||
|
||||
func (wf *wrappedInstanceFinalizer) Reconcile(ctx context.Context, ztdClient *systemClient.Client) error {
|
||||
if wf.instance.Status.InstanceId != nil {
|
||||
_, err := ztdClient.RemoveInstance(ctx, &pb.RemoveInstanceRequest{InstanceId: *wf.instance.Status.InstanceId})
|
||||
if err != nil {
|
||||
return fmt.Errorf("error removing Instance: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (wr *wrappedInstanceFinalizer) patch(ctx context.Context, instance *zitadelv1alpha1.Instance,
|
||||
patchFn func(*zitadelv1alpha1.Instance)) error {
|
||||
patch := ctrlClient.MergeFrom(instance.DeepCopy())
|
||||
patchFn(instance)
|
||||
|
||||
if err := wr.Client.Patch(ctx, instance, patch); err != nil {
|
||||
return fmt.Errorf("error patching Instance finalizer: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
//+kubebuilder:scaffold:imports
|
||||
)
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: actions.zitadel.topmanage.com
|
||||
spec:
|
||||
group: zitadel.topmanage.com
|
||||
names:
|
||||
kind: Action
|
||||
listKind: ActionList
|
||||
plural: actions
|
||||
singular: action
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Action is the Schema for the actions API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: ActionSpec defines the desired state of Action
|
||||
properties:
|
||||
allowedToFail:
|
||||
default: true
|
||||
type: boolean
|
||||
organizationRef:
|
||||
description: |-
|
||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: |-
|
||||
If referring to a piece of an object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: |-
|
||||
Specific resourceVersion to which this reference is made, if any.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||
type: string
|
||||
uid:
|
||||
description: |-
|
||||
UID of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
script:
|
||||
type: string
|
||||
timeout:
|
||||
format: duration
|
||||
type: string
|
||||
required:
|
||||
- allowedToFail
|
||||
- organizationRef
|
||||
- script
|
||||
- timeout
|
||||
type: object
|
||||
status:
|
||||
description: ActionStatus defines the observed state of Action
|
||||
properties:
|
||||
actionId:
|
||||
default: ""
|
||||
type: string
|
||||
conditions:
|
||||
description: |-
|
||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- actionId
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
|
||||
@@ -1,176 +0,0 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: apiapps.zitadel.topmanage.com
|
||||
spec:
|
||||
group: zitadel.topmanage.com
|
||||
names:
|
||||
kind: APIApp
|
||||
listKind: APIAppList
|
||||
plural: apiapps
|
||||
singular: apiapp
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: APIApp is the Schema for the apiapps API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: APIAppSpec defines the desired state of APIApp
|
||||
properties:
|
||||
authMethodType:
|
||||
enum:
|
||||
- API_AUTH_METHOD_TYPE_BASIC
|
||||
- API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT
|
||||
type: string
|
||||
projectRef:
|
||||
description: |-
|
||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: |-
|
||||
If referring to a piece of an object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: |-
|
||||
Specific resourceVersion to which this reference is made, if any.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||
type: string
|
||||
uid:
|
||||
description: |-
|
||||
UID of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
required:
|
||||
- authMethodType
|
||||
- projectRef
|
||||
type: object
|
||||
status:
|
||||
description: APIAppStatus defines the observed state of APIApp
|
||||
properties:
|
||||
appId:
|
||||
default: ""
|
||||
type: string
|
||||
clientId:
|
||||
default: ""
|
||||
type: string
|
||||
conditions:
|
||||
description: |-
|
||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
keyId:
|
||||
default: ""
|
||||
type: string
|
||||
required:
|
||||
- appId
|
||||
- clientId
|
||||
- keyId
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
|
||||
@@ -3,20 +3,30 @@ kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: zitadelclusters.zitadel.topmanage.com
|
||||
name: clusters.zitadel.github.com
|
||||
spec:
|
||||
group: zitadel.topmanage.com
|
||||
group: zitadel.github.com
|
||||
names:
|
||||
kind: ZitadelCluster
|
||||
listKind: ZitadelClusterList
|
||||
plural: zitadelclusters
|
||||
singular: zitadelcluster
|
||||
kind: Cluster
|
||||
listKind: ClusterList
|
||||
plural: clusters
|
||||
singular: cluster
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .status.replicas
|
||||
name: Replicas
|
||||
type: integer
|
||||
- jsonPath: .status.conditions[?(@.type=="Ready")].status
|
||||
name: Ready
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: ZitadelCluster is the Schema for the zitadelclusters API
|
||||
description: Cluster is the Schema for the clusters API.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
@@ -36,40 +46,23 @@ spec:
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: ZitadelClusterSpec defines the desired state of ZitadelCluster
|
||||
description: ClusterSpec defines the desired state of Cluster.
|
||||
properties:
|
||||
domainSettings:
|
||||
properties:
|
||||
smtpSenderAddressMatchesInstanceDomain:
|
||||
default: true
|
||||
type: boolean
|
||||
userLoginMustBeDomain:
|
||||
default: true
|
||||
type: boolean
|
||||
validateOrgDomains:
|
||||
default: true
|
||||
type: boolean
|
||||
required:
|
||||
- smtpSenderAddressMatchesInstanceDomain
|
||||
- userLoginMustBeDomain
|
||||
- validateOrgDomains
|
||||
type: object
|
||||
externalPort:
|
||||
default: 443
|
||||
description: ExternalPort is the port exposed externally.
|
||||
format: int64
|
||||
type: integer
|
||||
externalSecure:
|
||||
default: true
|
||||
description: ExternalSecure indicates whether TLS is used on the external
|
||||
endpoint.
|
||||
type: boolean
|
||||
firstOrgName:
|
||||
default: DEFAULT
|
||||
description: |-
|
||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
type: string
|
||||
host:
|
||||
description: Host is the external hostname used to reach Zitadel.
|
||||
type: string
|
||||
image:
|
||||
description: Image is the Zitadel container image to deploy.
|
||||
properties:
|
||||
name:
|
||||
type: string
|
||||
@@ -82,9 +75,12 @@ spec:
|
||||
podAnnotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: PodAnnotations to add to the Pods metadata.
|
||||
description: PodAnnotations are extra annotations added to each Zitadel
|
||||
Pod.
|
||||
type: object
|
||||
postgresClusterRef:
|
||||
description: PostgreSQLClusterRef references the backing PostgreSQL
|
||||
cluster.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
@@ -126,20 +122,14 @@ spec:
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
purpose:
|
||||
enum:
|
||||
- demo
|
||||
- trial
|
||||
- staging
|
||||
- productive
|
||||
- testing
|
||||
type: string
|
||||
replicas:
|
||||
default: 3
|
||||
description: Replicas is the desired number of Zitadel pods.
|
||||
format: int32
|
||||
type: integer
|
||||
resources:
|
||||
description: ResourceRequirements describes the compute resource requirements.
|
||||
description: Resources defines compute resource requests and limits
|
||||
for the Zitadel pods.
|
||||
properties:
|
||||
claims:
|
||||
description: |-
|
||||
@@ -197,96 +187,25 @@ spec:
|
||||
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
type: object
|
||||
type: object
|
||||
rootTLSSecret:
|
||||
description: |-
|
||||
SecretReference represents a Secret Reference. It has enough information to retrieve secret
|
||||
in any namespace
|
||||
properties:
|
||||
name:
|
||||
description: name is unique within a namespace to reference a
|
||||
secret resource.
|
||||
type: string
|
||||
namespace:
|
||||
description: namespace defines the space within which the secret
|
||||
name must be unique.
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
serviceAnnotations:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: ServiceAnnotations to add to the service metadata.
|
||||
type: object
|
||||
smtpConfig:
|
||||
properties:
|
||||
host:
|
||||
type: string
|
||||
password:
|
||||
properties:
|
||||
secretRef:
|
||||
description: SecretKeySelector selects a key of a Secret.
|
||||
properties:
|
||||
key:
|
||||
description: The key of the secret to select from. Must
|
||||
be a valid secret key.
|
||||
type: string
|
||||
name:
|
||||
default: ""
|
||||
description: |-
|
||||
Name of the referent.
|
||||
This field is effectively required, but due to backwards compatibility is
|
||||
allowed to be empty. Instances of this type with an empty value here are
|
||||
almost certainly wrong.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
optional:
|
||||
description: Specify whether the Secret or its key must
|
||||
be defined
|
||||
type: boolean
|
||||
required:
|
||||
- key
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
required:
|
||||
- secretRef
|
||||
type: object
|
||||
replyToAddress:
|
||||
type: string
|
||||
senderAddress:
|
||||
type: string
|
||||
senderName:
|
||||
type: string
|
||||
tls:
|
||||
default: true
|
||||
type: boolean
|
||||
user:
|
||||
type: string
|
||||
required:
|
||||
- host
|
||||
- senderAddress
|
||||
- senderName
|
||||
- tls
|
||||
description: ServiceAnnotations are extra annotations added to the
|
||||
Zitadel Service.
|
||||
type: object
|
||||
required:
|
||||
- domainSettings
|
||||
- externalPort
|
||||
- externalSecure
|
||||
- firstOrgName
|
||||
- host
|
||||
- image
|
||||
- postgresClusterRef
|
||||
- purpose
|
||||
- resources
|
||||
- rootTLSSecret
|
||||
- smtpConfig
|
||||
type: object
|
||||
status:
|
||||
description: ZitadelClusterStatus defines the observed state of ZitadelCluster
|
||||
description: ClusterStatus defines the observed state of Cluster.
|
||||
properties:
|
||||
conditions:
|
||||
description: |-
|
||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
description: Conditions store the status conditions of the Cluster.
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
@@ -342,19 +261,11 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
defaultInstanceId:
|
||||
default: ""
|
||||
type: string
|
||||
replicas:
|
||||
default: 3
|
||||
description: Replicas is the current number of running Zitadel pods.
|
||||
format: int32
|
||||
type: integer
|
||||
smtpProviderId:
|
||||
default: ""
|
||||
type: string
|
||||
required:
|
||||
- defaultInstanceId
|
||||
- smtpProviderId
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
@@ -1,227 +0,0 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: flows.zitadel.topmanage.com
|
||||
spec:
|
||||
group: zitadel.topmanage.com
|
||||
names:
|
||||
kind: Flow
|
||||
listKind: FlowList
|
||||
plural: flows
|
||||
singular: flow
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Flow is the Schema for the flows API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: FlowSpec defines the desired state of Flow
|
||||
properties:
|
||||
actionRefs:
|
||||
items:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: |-
|
||||
If referring to a piece of an object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: |-
|
||||
Specific resourceVersion to which this reference is made, if any.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||
type: string
|
||||
uid:
|
||||
description: |-
|
||||
UID of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
type: array
|
||||
flowType:
|
||||
enum:
|
||||
- FLOW_TYPE_EXTERNAL_AUTHENTICATION
|
||||
- "1"
|
||||
- "2"
|
||||
- "3"
|
||||
- "4"
|
||||
type: string
|
||||
organizationRef:
|
||||
description: |-
|
||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: |-
|
||||
If referring to a piece of an object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: |-
|
||||
Specific resourceVersion to which this reference is made, if any.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||
type: string
|
||||
uid:
|
||||
description: |-
|
||||
UID of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
triggerType:
|
||||
enum:
|
||||
- TRIGGER_TYPE_POST_AUTHENTICATION
|
||||
- TRIGGER_TYPE_PRE_CREATION
|
||||
- TRIGGER_TYPE_POST_CREATION
|
||||
- TRIGGER_TYPE_POST_AUTHENTICATION
|
||||
- TRIGGER_TYPE_PRE_CREATION
|
||||
- TRIGGER_TYPE_POST_CREATION
|
||||
- "1"
|
||||
- "2"
|
||||
- "3"
|
||||
- "4"
|
||||
- "5"
|
||||
- "6"
|
||||
type: string
|
||||
required:
|
||||
- actionRefs
|
||||
- flowType
|
||||
- organizationRef
|
||||
- triggerType
|
||||
type: object
|
||||
status:
|
||||
description: FlowStatus defines the observed state of Flow
|
||||
properties:
|
||||
conditions:
|
||||
description: |-
|
||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
|
||||
@@ -3,20 +3,36 @@ kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: machineusers.zitadel.topmanage.com
|
||||
name: instances.zitadel.github.com
|
||||
spec:
|
||||
group: zitadel.topmanage.com
|
||||
group: zitadel.github.com
|
||||
names:
|
||||
kind: MachineUser
|
||||
listKind: MachineUserList
|
||||
plural: machineusers
|
||||
singular: machineuser
|
||||
kind: Instance
|
||||
listKind: InstanceList
|
||||
plural: instances
|
||||
singular: instance
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
- additionalPrinterColumns:
|
||||
- jsonPath: .spec.instanceName
|
||||
name: Instance
|
||||
type: string
|
||||
- jsonPath: .spec.clusterRef.name
|
||||
name: Cluster
|
||||
type: string
|
||||
- jsonPath: .spec.customDomain
|
||||
name: Domain
|
||||
type: string
|
||||
- jsonPath: .status.conditions[?(@.type=="Ready")].status
|
||||
name: Ready
|
||||
type: string
|
||||
- jsonPath: .metadata.creationTimestamp
|
||||
name: Age
|
||||
type: date
|
||||
name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: MachineUser is the Schema for the machineusers API
|
||||
description: Instance is the Schema for the instances API.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
@@ -36,17 +52,13 @@ spec:
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: MachineUserSpec defines the desired state of MachineUser
|
||||
properties:
|
||||
accessTokenType:
|
||||
enum:
|
||||
- ACCESS_TOKEN_TYPE_BEARER
|
||||
- ACCESS_TOKEN_TYPE_JWT
|
||||
type: string
|
||||
organizationRef:
|
||||
description: |-
|
||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
InstanceSpec defines the desired state of Instance.
|
||||
Fields map directly to POST /instances/_create (CreateInstance) in the Zitadel System API.
|
||||
properties:
|
||||
clusterRef:
|
||||
description: ClusterRef references the Cluster this instance will
|
||||
be provisioned on.
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
@@ -88,70 +100,120 @@ spec:
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
userGrants:
|
||||
customDomain:
|
||||
type: string
|
||||
defaultLanguage:
|
||||
default: en
|
||||
description: DefaultLanguage is the BCP-47 language tag used as the
|
||||
instance default (e.g. "en").
|
||||
type: string
|
||||
instanceName:
|
||||
description: InstanceName is the display name of the Zitadel instance.
|
||||
type: string
|
||||
loginUI:
|
||||
default:
|
||||
image:
|
||||
name: ghcr.io/zitadel/zitadel-login
|
||||
resources: {}
|
||||
properties:
|
||||
image:
|
||||
properties:
|
||||
name:
|
||||
default: ghcr.io/zitadel/zitadel-login
|
||||
type: string
|
||||
tag:
|
||||
description: if empty it uses the same tag as zitadel cluster
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
resources:
|
||||
description: ResourceRequirements describes the compute resource
|
||||
requirements.
|
||||
properties:
|
||||
claims:
|
||||
description: |-
|
||||
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||
that are used by this container.
|
||||
|
||||
This is an alpha field and requires enabling the
|
||||
DynamicResourceAllocation feature gate.
|
||||
|
||||
This field is immutable. It can only be set for containers.
|
||||
items:
|
||||
description: ResourceClaim references one entry in PodSpec.ResourceClaims.
|
||||
properties:
|
||||
projectRef:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: |-
|
||||
If referring to a piece of an object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
Name must match the name of one entry in pod.spec.resourceClaims of
|
||||
the Pod where this field is used. It makes that resource available
|
||||
inside a container.
|
||||
type: string
|
||||
namespace:
|
||||
request:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
Request is the name chosen for a request in the referenced claim.
|
||||
If empty, everything from the claim is made available, otherwise
|
||||
only the result of this request.
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: |-
|
||||
Specific resourceVersion to which this reference is made, if any.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||
type: string
|
||||
uid:
|
||||
description: |-
|
||||
UID of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
roleKeys:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- projectRef
|
||||
- name
|
||||
type: object
|
||||
type: array
|
||||
x-kubernetes-list-map-keys:
|
||||
- name
|
||||
x-kubernetes-list-type: map
|
||||
limits:
|
||||
additionalProperties:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: |-
|
||||
Limits describes the maximum amount of compute resources allowed.
|
||||
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
type: object
|
||||
requests:
|
||||
additionalProperties:
|
||||
anyOf:
|
||||
- type: integer
|
||||
- type: string
|
||||
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
|
||||
x-kubernetes-int-or-string: true
|
||||
description: |-
|
||||
Requests describes the minimum amount of compute resources required.
|
||||
If Requests is omitted for a container, it defaults to Limits if that is explicitly specified,
|
||||
otherwise to an implementation-defined value. Requests cannot exceed Limits.
|
||||
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||
type: object
|
||||
type: object
|
||||
required:
|
||||
- accessTokenType
|
||||
- organizationRef
|
||||
- image
|
||||
- resources
|
||||
type: object
|
||||
org:
|
||||
description: Org configures the first organisation and its initial
|
||||
IAM_OWNER machine user.
|
||||
properties:
|
||||
name:
|
||||
default: DEFAULT
|
||||
description: Name of the first organization.
|
||||
type: string
|
||||
required:
|
||||
- name
|
||||
type: object
|
||||
required:
|
||||
- clusterRef
|
||||
- customDomain
|
||||
- instanceName
|
||||
- loginUI
|
||||
- org
|
||||
type: object
|
||||
status:
|
||||
description: MachineUserStatus defines the observed state of MachineUser
|
||||
description: InstanceStatus defines the observed state of Instance.
|
||||
properties:
|
||||
conditions:
|
||||
description: |-
|
||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
description: Conditions store the status conditions of the Instance.
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
@@ -207,19 +269,10 @@ spec:
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
keyId:
|
||||
default: ""
|
||||
instanceId:
|
||||
description: InstanceId is the instance ID returned by Zitadel after
|
||||
successful provisioning.
|
||||
type: string
|
||||
patId:
|
||||
default: ""
|
||||
type: string
|
||||
userId:
|
||||
default: ""
|
||||
type: string
|
||||
required:
|
||||
- keyId
|
||||
- patId
|
||||
- userId
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
@@ -1,240 +0,0 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: oidcapps.zitadel.topmanage.com
|
||||
spec:
|
||||
group: zitadel.topmanage.com
|
||||
names:
|
||||
kind: OIDCApp
|
||||
listKind: OIDCAppList
|
||||
plural: oidcapps
|
||||
singular: oidcapp
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: OIDCApp is the Schema for the oidcapps API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: OIDCAppSpec defines the desired state of OIDCApp
|
||||
properties:
|
||||
accessTokenRoleAssertion:
|
||||
type: boolean
|
||||
accessTokenType:
|
||||
enum:
|
||||
- OIDC_TOKEN_TYPE_BEARER
|
||||
- OIDC_TOKEN_TYPE_JWT
|
||||
type: string
|
||||
additionalOrigins:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
appType:
|
||||
enum:
|
||||
- OIDC_APP_TYPE_WEB
|
||||
- OIDC_APP_TYPE_USER_AGENT
|
||||
- OIDC_APP_TYPE_NATIVE
|
||||
type: string
|
||||
authMethodType:
|
||||
enum:
|
||||
- OIDC_AUTH_METHOD_TYPE_BASIC
|
||||
- OIDC_AUTH_METHOD_TYPE_POST
|
||||
- OIDC_AUTH_METHOD_TYPE_NONE
|
||||
- OIDC_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT
|
||||
type: string
|
||||
clockSkew:
|
||||
format: duration
|
||||
type: string
|
||||
devMode:
|
||||
type: boolean
|
||||
grantTypes:
|
||||
items:
|
||||
enum:
|
||||
- OIDC_GRANT_TYPE_AUTHORIZATION_CODE
|
||||
- OIDC_GRANT_TYPE_IMPLICIT
|
||||
- OIDC_GRANT_TYPE_REFRESH_TOKEN
|
||||
- OIDC_GRANT_TYPE_DEVICE_CODE
|
||||
- OIDC_GRANT_TYPE_TOKEN_EXCHANGE
|
||||
type: string
|
||||
type: array
|
||||
idTokenRoleAssertion:
|
||||
type: boolean
|
||||
idTokenUserinfoAssertion:
|
||||
type: boolean
|
||||
postLogoutRedirectUris:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
projectRef:
|
||||
description: |-
|
||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: |-
|
||||
If referring to a piece of an object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: |-
|
||||
Specific resourceVersion to which this reference is made, if any.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||
type: string
|
||||
uid:
|
||||
description: |-
|
||||
UID of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
redirectUris:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
responseTypes:
|
||||
items:
|
||||
enum:
|
||||
- OIDC_RESPONSE_TYPE_CODE
|
||||
- OIDC_RESPONSE_TYPE_ID_TOKEN
|
||||
- OIDC_RESPONSE_TYPE_ID_TOKEN_TOKEN
|
||||
type: string
|
||||
type: array
|
||||
skipNativeAppSuccessPage:
|
||||
type: boolean
|
||||
required:
|
||||
- accessTokenRoleAssertion
|
||||
- accessTokenType
|
||||
- appType
|
||||
- authMethodType
|
||||
- clockSkew
|
||||
- devMode
|
||||
- grantTypes
|
||||
- idTokenRoleAssertion
|
||||
- idTokenUserinfoAssertion
|
||||
- postLogoutRedirectUris
|
||||
- projectRef
|
||||
- redirectUris
|
||||
- responseTypes
|
||||
- skipNativeAppSuccessPage
|
||||
type: object
|
||||
status:
|
||||
description: OIDCAppStatus defines the observed state of OIDCApp
|
||||
properties:
|
||||
appId:
|
||||
default: ""
|
||||
type: string
|
||||
clientId:
|
||||
default: ""
|
||||
type: string
|
||||
conditions:
|
||||
description: |-
|
||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- appId
|
||||
- clientId
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
|
||||
@@ -1,184 +0,0 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: organizations.zitadel.topmanage.com
|
||||
spec:
|
||||
group: zitadel.topmanage.com
|
||||
names:
|
||||
kind: Organization
|
||||
listKind: OrganizationList
|
||||
plural: organizations
|
||||
singular: organization
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Organization is the Schema for the organizations API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: OrganizationSpec defines the desired state of Organization
|
||||
properties:
|
||||
organizationAdmin:
|
||||
properties:
|
||||
email:
|
||||
type: string
|
||||
firstName:
|
||||
type: string
|
||||
lastName:
|
||||
type: string
|
||||
userName:
|
||||
type: string
|
||||
required:
|
||||
- email
|
||||
- firstName
|
||||
- lastName
|
||||
- userName
|
||||
type: object
|
||||
zitadelClusterRef:
|
||||
description: |-
|
||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: |-
|
||||
If referring to a piece of an object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: |-
|
||||
Specific resourceVersion to which this reference is made, if any.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||
type: string
|
||||
uid:
|
||||
description: |-
|
||||
UID of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
required:
|
||||
- organizationAdmin
|
||||
- zitadelClusterRef
|
||||
type: object
|
||||
status:
|
||||
description: OrganizationStatus defines the observed state of Organization
|
||||
properties:
|
||||
adminId:
|
||||
default: ""
|
||||
type: string
|
||||
conditions:
|
||||
description: |-
|
||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
Conditions for the Database object.
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
orgId:
|
||||
default: ""
|
||||
type: string
|
||||
required:
|
||||
- adminId
|
||||
- orgId
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
|
||||
@@ -1,239 +0,0 @@
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: projects.zitadel.topmanage.com
|
||||
spec:
|
||||
group: zitadel.topmanage.com
|
||||
names:
|
||||
kind: Project
|
||||
listKind: ProjectList
|
||||
plural: projects
|
||||
singular: project
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Project is the Schema for the projects API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: ProjectSpec defines the desired state of Project
|
||||
properties:
|
||||
grants:
|
||||
items:
|
||||
properties:
|
||||
organizationRef:
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: |-
|
||||
If referring to a piece of an object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: |-
|
||||
Specific resourceVersion to which this reference is made, if any.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||
type: string
|
||||
uid:
|
||||
description: |-
|
||||
UID of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
roleKeys:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
required:
|
||||
- organizationRef
|
||||
- roleKeys
|
||||
type: object
|
||||
type: array
|
||||
hasProjectCheck:
|
||||
type: boolean
|
||||
organizationRef:
|
||||
description: |-
|
||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
https://zitadel.com/docs/apis/resources/mgmt/management-service-add-project
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: |-
|
||||
If referring to a piece of an object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: |-
|
||||
Specific resourceVersion to which this reference is made, if any.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||
type: string
|
||||
uid:
|
||||
description: |-
|
||||
UID of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
projectRoleAssertion:
|
||||
type: boolean
|
||||
projectRoleCheck:
|
||||
type: boolean
|
||||
roles:
|
||||
items:
|
||||
properties:
|
||||
displayName:
|
||||
type: string
|
||||
group:
|
||||
type: string
|
||||
key:
|
||||
type: string
|
||||
required:
|
||||
- displayName
|
||||
- group
|
||||
- key
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- organizationRef
|
||||
type: object
|
||||
status:
|
||||
description: ProjectStatus defines the observed state of Project
|
||||
properties:
|
||||
conditions:
|
||||
description: |-
|
||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
Conditions for the Database object.
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
projectId:
|
||||
default: ""
|
||||
type: string
|
||||
required:
|
||||
- projectId
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
|
||||
@@ -54,9 +54,12 @@ app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
Create the name of the service account to use
|
||||
*/}}
|
||||
{{- define "zitadel-k8s-operator.serviceAccountName" -}}
|
||||
{{- if .Values.serviceAccount.create }}
|
||||
{{- default (include "zitadel-k8s-operator.fullname" .) .Values.serviceAccount.name }}
|
||||
{{- $default := (include "zitadel-k8s-operator.fullname" .) }}
|
||||
{{- with .Values.serviceAccount }}
|
||||
{{- if .create }}
|
||||
{{- default $default .name }}
|
||||
{{- else }}
|
||||
{{- default "default" .Values.serviceAccount.name }}
|
||||
{{- default "default" .name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
@@ -79,7 +79,11 @@ spec:
|
||||
}}
|
||||
securityContext: {{- toYaml .Values.controllerManager.manager.containerSecurityContext
|
||||
| nindent 10 }}
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
serviceAccountName: {{ include "zitadel-k8s-operator.fullname" . }}-controller-manager
|
||||
nodeSelector: {{- toYaml .Values.controllerManager.nodeSelector | nindent 8 }}
|
||||
securityContext: {{- toYaml .Values.controllerManager.podSecurityContext | nindent
|
||||
8 }}
|
||||
serviceAccountName: {{ include "zitadel-k8s-operator.serviceAccountName" . }}
|
||||
terminationGracePeriodSeconds: 10
|
||||
tolerations: {{- toYaml .Values.controllerManager.tolerations | nindent 8 }}
|
||||
topologySpreadConstraints: {{- toYaml .Values.controllerManager.topologySpreadConstraints
|
||||
| nindent 8 }}
|
||||
|
||||
@@ -55,5 +55,5 @@ roleRef:
|
||||
name: '{{ include "zitadel-k8s-operator.fullname" . }}-leader-election-role'
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: '{{ include "zitadel-k8s-operator.fullname" . }}-controller-manager'
|
||||
name: '{{ include "zitadel-k8s-operator.serviceAccountName" . }}'
|
||||
namespace: '{{ .Release.Namespace }}'
|
||||
@@ -128,17 +128,48 @@ rules:
|
||||
- list
|
||||
- patch
|
||||
- watch
|
||||
- apiGroups:
|
||||
- zitadel.github.com
|
||||
resources:
|
||||
- clusters
|
||||
- connections
|
||||
- instances
|
||||
- machineusers
|
||||
- organizations
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
- get
|
||||
- list
|
||||
- patch
|
||||
- update
|
||||
- watch
|
||||
- apiGroups:
|
||||
- zitadel.github.com
|
||||
resources:
|
||||
- clusters/finalizers
|
||||
- connections/finalizers
|
||||
- instances/finalizers
|
||||
- machineusers/finalizers
|
||||
- organizations/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- zitadel.github.com
|
||||
resources:
|
||||
- clusters/status
|
||||
- connections/status
|
||||
- instances/status
|
||||
- machineusers/status
|
||||
- organizations/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
- update
|
||||
- apiGroups:
|
||||
- zitadel.topmanage.com
|
||||
resources:
|
||||
- actions
|
||||
- apiapps
|
||||
- flows
|
||||
- machineusers
|
||||
- oidcapps
|
||||
- organizations
|
||||
- projects
|
||||
- zitadelclusters
|
||||
- instances
|
||||
verbs:
|
||||
- create
|
||||
- delete
|
||||
@@ -150,27 +181,13 @@ rules:
|
||||
- apiGroups:
|
||||
- zitadel.topmanage.com
|
||||
resources:
|
||||
- actions/finalizers
|
||||
- apiapps/finalizers
|
||||
- flows/finalizers
|
||||
- machineusers/finalizers
|
||||
- oidcapps/finalizers
|
||||
- organizations/finalizers
|
||||
- projects/finalizers
|
||||
- zitadelclusters/finalizers
|
||||
- instances/finalizers
|
||||
verbs:
|
||||
- update
|
||||
- apiGroups:
|
||||
- zitadel.topmanage.com
|
||||
resources:
|
||||
- actions/status
|
||||
- apiapps/status
|
||||
- flows/status
|
||||
- machineusers/status
|
||||
- oidcapps/status
|
||||
- organizations/status
|
||||
- projects/status
|
||||
- zitadelclusters/status
|
||||
- instances/status
|
||||
verbs:
|
||||
- get
|
||||
- patch
|
||||
@@ -191,5 +208,5 @@ roleRef:
|
||||
name: '{{ include "zitadel-k8s-operator.fullname" . }}-manager-role'
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: '{{ include "zitadel-k8s-operator.fullname" . }}-controller-manager'
|
||||
name: '{{ include "zitadel-k8s-operator.serviceAccountName" . }}'
|
||||
namespace: '{{ .Release.Namespace }}'
|
||||
|
||||
@@ -36,5 +36,5 @@ roleRef:
|
||||
name: '{{ include "zitadel-k8s-operator.fullname" . }}-proxy-role'
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: '{{ include "zitadel-k8s-operator.fullname" . }}-controller-manager'
|
||||
name: '{{ include "zitadel-k8s-operator.serviceAccountName" . }}'
|
||||
namespace: '{{ .Release.Namespace }}'
|
||||
@@ -1,11 +1,13 @@
|
||||
{{ if .Values.serviceAccount.create }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "zitadel-k8s-operator.fullname" . }}-controller-manager
|
||||
name: {{ include "zitadel-k8s-operator.serviceAccountName" . }}
|
||||
labels:
|
||||
app.kubernetes.io/component: rbac
|
||||
app.kubernetes.io/created-by: src
|
||||
app.kubernetes.io/part-of: src
|
||||
{{- include "zitadel-k8s-operator.labels" . | nindent 4 }}
|
||||
{{- with .Values.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml .Values.controllerManager.serviceAccount.annotations | nindent 4 }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
|
||||
{{- end }}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
controllerManager:
|
||||
kubeRbacProxy:
|
||||
args:
|
||||
@@ -11,7 +12,7 @@ controllerManager:
|
||||
drop:
|
||||
- ALL
|
||||
image:
|
||||
repository: gcr.io/kubebuilder/kube-rbac-proxy
|
||||
repository: registry.k8s.io/kubebuilder/kube-rbac-proxy
|
||||
tag: v0.13.1
|
||||
resources:
|
||||
limits:
|
||||
@@ -31,8 +32,7 @@ controllerManager:
|
||||
drop:
|
||||
- ALL
|
||||
image:
|
||||
repository: controller
|
||||
tag: latest
|
||||
repository: gitea.corredorconect.com/software-engineering/zitadel-k8s-operator
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
@@ -40,9 +40,12 @@ controllerManager:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 64Mi
|
||||
nodeSelector: {}
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
replicas: 1
|
||||
serviceAccount:
|
||||
annotations: {}
|
||||
tolerations: []
|
||||
topologySpreadConstraints: []
|
||||
kubernetesClusterDomain: cluster.local
|
||||
metricsService:
|
||||
ports:
|
||||
@@ -51,3 +54,8 @@ metricsService:
|
||||
protocol: TCP
|
||||
targetPort: https
|
||||
type: ClusterIP
|
||||
serviceAccount:
|
||||
annotations: {}
|
||||
automount: true
|
||||
create: true
|
||||
name: ""
|
||||
|
||||
14
pkg/admin/admin.go
Normal file
14
pkg/admin/admin.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package admin
|
||||
|
||||
import (
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
AccountName = "admin"
|
||||
Key = "password"
|
||||
)
|
||||
|
||||
func AdminPasswordSecretName(zitadel *zitadelv1alpha1.Cluster) string {
|
||||
return zitadel.Name + "-admin-password-secret"
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
metadata "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder/metadata"
|
||||
"fmt"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
metadata "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/metadata"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
type ConfigMapOpts struct {
|
||||
Zitadel *zitadelv1alpha1.ZitadelCluster
|
||||
Zitadel *zitadelv1alpha1.Cluster
|
||||
Key types.NamespacedName
|
||||
Data map[string]string
|
||||
Labels map[string]string
|
||||
42
pkg/builder/connection_builder.go
Normal file
42
pkg/builder/connection_builder.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
metadata "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/metadata"
|
||||
zitadelresourcesv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-resources-operator/api/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
func (b *Builder) BuildConnection(key types.NamespacedName, instance *zitadelv1alpha1.Instance) (*zitadelresourcesv1alpha1.Connection, error) {
|
||||
objMeta :=
|
||||
metadata.NewMetadataBuilder(key).
|
||||
Build()
|
||||
|
||||
org := &zitadelresourcesv1alpha1.Connection{
|
||||
ObjectMeta: objMeta,
|
||||
Spec: zitadelresourcesv1alpha1.ConnectionSpec{
|
||||
Host: instance.Spec.CustomDomain,
|
||||
Secure: true,
|
||||
InsecureSkipVerifyTLS: true,
|
||||
Authentication: zitadelresourcesv1alpha1.Authentication{
|
||||
PAT: &zitadelresourcesv1alpha1.PAT{
|
||||
TokenSecretKey: corev1.SecretKeySelector{
|
||||
LocalObjectReference: corev1.LocalObjectReference{
|
||||
Name: instance.MachineSecretName(),
|
||||
},
|
||||
Key: "pat",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if err := controllerutil.SetControllerReference(instance, org, b.scheme); err != nil {
|
||||
return nil, fmt.Errorf("error setting controller reference in Connection manifest: %v", err)
|
||||
}
|
||||
return org, nil
|
||||
}
|
||||
@@ -3,12 +3,12 @@ package builder
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
labels "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder/labels"
|
||||
metadata "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder/metadata"
|
||||
configuration "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/configuration"
|
||||
deployment "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/deployment"
|
||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/masterkey"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
labels "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/labels"
|
||||
metadata "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/metadata"
|
||||
configuration "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/configuration"
|
||||
deployment "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/deployment"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/masterkey"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -18,7 +18,7 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
func (b *Builder) BuildDeployment(zitadel *zitadelv1alpha1.ZitadelCluster, key types.NamespacedName) (*appsv1.Deployment, error) {
|
||||
func (b *Builder) BuildDeployment(zitadel *zitadelv1alpha1.Cluster, key types.NamespacedName) (*appsv1.Deployment, error) {
|
||||
replicas := zitadel.Spec.Replicas
|
||||
objMeta :=
|
||||
metadata.NewMetadataBuilder(key).
|
||||
@@ -51,7 +51,7 @@ func (b *Builder) BuildDeployment(zitadel *zitadelv1alpha1.ZitadelCluster, key t
|
||||
return dep, nil
|
||||
}
|
||||
|
||||
func (b *Builder) buildDepPodTemplate(zitadel *zitadelv1alpha1.ZitadelCluster, labels map[string]string) (*corev1.PodTemplateSpec, error) {
|
||||
func (b *Builder) buildDepPodTemplate(zitadel *zitadelv1alpha1.Cluster, labels map[string]string) (*corev1.PodTemplateSpec, error) {
|
||||
objMeta :=
|
||||
metadata.NewMetadataBuilder(client.ObjectKeyFromObject(zitadel)).
|
||||
WithZitadel(zitadel).
|
||||
@@ -80,7 +80,7 @@ func (b *Builder) buildDepPodTemplate(zitadel *zitadelv1alpha1.ZitadelCluster, l
|
||||
nil
|
||||
}
|
||||
|
||||
func (b *Builder) buildDepContainers(zitadel *zitadelv1alpha1.ZitadelCluster) *[]corev1.Container {
|
||||
func (b *Builder) buildDepContainers(zitadel *zitadelv1alpha1.Cluster) *[]corev1.Container {
|
||||
readyProbeHandle := corev1.ProbeHandler{
|
||||
HTTPGet: &corev1.HTTPGetAction{HTTPHeaders: []corev1.HTTPHeader{},
|
||||
Port: intstr.FromInt(deployment.ZitadelPort),
|
||||
@@ -112,6 +112,16 @@ func (b *Builder) buildDepContainers(zitadel *zitadelv1alpha1.ZitadelCluster) *[
|
||||
ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: masterkey.MasterKeyName(zitadel)}, Key: masterkey.Key}},
|
||||
},
|
||||
|
||||
{
|
||||
Name: "ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD",
|
||||
ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: zitadel.Spec.PostgreSQLClusterRef.Name + "-superuser"}, Key: "password"}},
|
||||
},
|
||||
|
||||
{
|
||||
Name: "ZITADEL_DATABASE_POSTGRES_USER_PASSWORD",
|
||||
ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: zitadel.Spec.PostgreSQLClusterRef.Name + "-user"}, Key: "password"}},
|
||||
},
|
||||
|
||||
// {
|
||||
// Name: "ZITADEL_DATABASE_COCKROACH_ADMIN_SSL_ROOTCERT",
|
||||
// Value: "/certs/ca.crt",
|
||||
@@ -3,9 +3,9 @@ package builder
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
configuration "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/configuration"
|
||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/masterkey"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
configuration "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/configuration"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/masterkey"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
@@ -13,10 +13,9 @@ import (
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
func (b *Builder) BuildInitJob(zitadel *zitadelv1alpha1.ZitadelCluster, key types.NamespacedName) (*batchv1.Job, error) {
|
||||
func (b *Builder) BuildInitJob(zitadel *zitadelv1alpha1.Cluster, key types.NamespacedName) (*batchv1.Job, error) {
|
||||
|
||||
backOffLimit := int32(5)
|
||||
ttlAfterFinish := int32(100)
|
||||
activeDeadlineSeconds := int64(1800)
|
||||
runAsNonRoot := true
|
||||
enableServiceLinks := false
|
||||
@@ -30,7 +29,6 @@ func (b *Builder) BuildInitJob(zitadel *zitadelv1alpha1.ZitadelCluster, key type
|
||||
Spec: batchv1.JobSpec{
|
||||
BackoffLimit: &backOffLimit,
|
||||
ActiveDeadlineSeconds: &activeDeadlineSeconds,
|
||||
TTLSecondsAfterFinished: &ttlAfterFinish,
|
||||
Template: corev1.PodTemplateSpec{
|
||||
Spec: corev1.PodSpec{
|
||||
RestartPolicy: corev1.RestartPolicyOnFailure,
|
||||
@@ -54,6 +52,7 @@ func (b *Builder) BuildInitJob(zitadel *zitadelv1alpha1.ZitadelCluster, key type
|
||||
Image: zitadel.Spec.Image.Name + ":" + zitadel.Spec.Image.Tag,
|
||||
Args: []string{
|
||||
"init",
|
||||
"zitadel",
|
||||
"--config", "/config/zitadel-config-yaml",
|
||||
},
|
||||
Env: []corev1.EnvVar{
|
||||
@@ -81,6 +80,15 @@ func (b *Builder) BuildInitJob(zitadel *zitadelv1alpha1.ZitadelCluster, key type
|
||||
// Name: "ZITADEL_DATABASE_COCKROACH_USER_SSL_KEY",
|
||||
// Value: "/certs/tls.key",
|
||||
// },
|
||||
{
|
||||
Name: "ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD",
|
||||
ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: zitadel.Spec.PostgreSQLClusterRef.Name + "-superuser"}, Key: "password"}},
|
||||
},
|
||||
|
||||
{
|
||||
Name: "ZITADEL_DATABASE_POSTGRES_USER_PASSWORD",
|
||||
ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: zitadel.Spec.PostgreSQLClusterRef.Name + "-user"}, Key: "password"}},
|
||||
},
|
||||
},
|
||||
VolumeMounts: []corev1.VolumeMount{
|
||||
{Name: "zitadel-config-yaml", MountPath: "/config"},
|
||||
@@ -98,7 +106,7 @@ func (b *Builder) BuildInitJob(zitadel *zitadelv1alpha1.ZitadelCluster, key type
|
||||
return initJob, nil
|
||||
}
|
||||
|
||||
func (b *Builder) BuildSetupJob(zitadel *zitadelv1alpha1.ZitadelCluster, key types.NamespacedName) (*batchv1.Job, error) {
|
||||
func (b *Builder) BuildSetupJob(zitadel *zitadelv1alpha1.Cluster, key types.NamespacedName) (*batchv1.Job, error) {
|
||||
|
||||
backOffLimit := int32(5)
|
||||
activeDeadlineSeconds := int64(1800)
|
||||
@@ -177,6 +185,16 @@ func (b *Builder) BuildSetupJob(zitadel *zitadelv1alpha1.ZitadelCluster, key typ
|
||||
// Name: "ZITADEL_DATABASE_COCKROACH_USER_SSL_KEY",
|
||||
// Value: "/certs/tls.key",
|
||||
// },
|
||||
//
|
||||
{
|
||||
Name: "ZITADEL_DATABASE_POSTGRES_ADMIN_PASSWORD",
|
||||
ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: zitadel.Spec.PostgreSQLClusterRef.Name + "-superuser"}, Key: "password"}},
|
||||
},
|
||||
|
||||
{
|
||||
Name: "ZITADEL_DATABASE_POSTGRES_USER_PASSWORD",
|
||||
ValueFrom: &corev1.EnvVarSource{SecretKeyRef: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: zitadel.Spec.PostgreSQLClusterRef.Name + "-user"}, Key: "password"}},
|
||||
},
|
||||
},
|
||||
VolumeMounts: []corev1.VolumeMount{
|
||||
{Name: "zitadel-config-yaml", MountPath: "/config"},
|
||||
@@ -1,8 +1,8 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
deployment "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/deployment"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
deployment "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/deployment"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -10,6 +10,7 @@ const (
|
||||
instanceLabel = "app.kubernetes.io/instance"
|
||||
deploymentPodName = "deployment.kubernetes.io/pod-name"
|
||||
appZitadel = "zitadel"
|
||||
appLoginUI = "zitadel-login-ui"
|
||||
appExporter = "exporter"
|
||||
)
|
||||
|
||||
@@ -33,12 +34,17 @@ func (b *LabelsBuilder) WithInstance(instance string) *LabelsBuilder {
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *LabelsBuilder) WithZitadel(zitadel *zitadelv1alpha1.ZitadelCluster) *LabelsBuilder {
|
||||
func (b *LabelsBuilder) WithZitadel(zitadel *zitadelv1alpha1.Cluster) *LabelsBuilder {
|
||||
return b.WithApp(appZitadel).
|
||||
WithInstance(zitadel.Name)
|
||||
}
|
||||
|
||||
func (b *LabelsBuilder) WithDeploymentPod(zitadel *zitadelv1alpha1.ZitadelCluster, podIndex int) *LabelsBuilder {
|
||||
func (b *LabelsBuilder) WithLoginUI(instance *zitadelv1alpha1.Instance) *LabelsBuilder {
|
||||
return b.WithApp(appLoginUI).
|
||||
WithInstance(instance.Name)
|
||||
}
|
||||
|
||||
func (b *LabelsBuilder) WithDeploymentPod(zitadel *zitadelv1alpha1.Cluster, podIndex int) *LabelsBuilder {
|
||||
b.labels[deploymentPodName] = deployment.PodName(zitadel.ObjectMeta, podIndex)
|
||||
return b
|
||||
}
|
||||
@@ -50,12 +56,17 @@ func (b *LabelsBuilder) WithLabels(labels map[string]string) *LabelsBuilder {
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *LabelsBuilder) WithZitadelSelectorLabels(zitadel *zitadelv1alpha1.ZitadelCluster) *LabelsBuilder {
|
||||
func (b *LabelsBuilder) WithZitadelSelectorLabels(zitadel *zitadelv1alpha1.Cluster) *LabelsBuilder {
|
||||
b = b.WithZitadel(zitadel)
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *LabelsBuilder) WithMetricsSelectorLabels(zitadel *zitadelv1alpha1.ZitadelCluster) *LabelsBuilder {
|
||||
func (b *LabelsBuilder) WithLoginUISelectorLabels(instance *zitadelv1alpha1.Instance) *LabelsBuilder {
|
||||
b = b.WithLoginUI(instance)
|
||||
return b
|
||||
}
|
||||
|
||||
func (b *LabelsBuilder) WithMetricsSelectorLabels(zitadel *zitadelv1alpha1.Cluster) *LabelsBuilder {
|
||||
return b.WithApp(appExporter).
|
||||
WithInstance(zitadel.Name)
|
||||
}
|
||||
120
pkg/builder/login_deployment_builder.go
Normal file
120
pkg/builder/login_deployment_builder.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
labels "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/labels"
|
||||
metadata "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/metadata"
|
||||
deployment "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/deployment"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/intstr"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
func (b *Builder) BuildLoginDeployment(cluster *zitadelv1alpha1.Cluster, instance *zitadelv1alpha1.Instance, customDomain string, key types.NamespacedName) (*appsv1.Deployment, error) {
|
||||
replicas := int32(1)
|
||||
tag := cluster.Spec.Image.Tag
|
||||
if instance.Spec.LoginUI.Image.Tag != nil {
|
||||
tag = *instance.Spec.LoginUI.Image.Tag
|
||||
}
|
||||
objMeta :=
|
||||
metadata.NewMetadataBuilder(key).
|
||||
WithAnnotations(map[string]string{
|
||||
"reloader.stakater.com/auto": "true",
|
||||
}).
|
||||
Build()
|
||||
|
||||
selectorLabels :=
|
||||
labels.NewLabelsBuilder().
|
||||
WithLoginUISelectorLabels(instance).
|
||||
Build()
|
||||
templateObjMeta :=
|
||||
metadata.NewMetadataBuilder(client.ObjectKeyFromObject(instance)).
|
||||
WithLabels(selectorLabels).
|
||||
Build()
|
||||
|
||||
dep := &appsv1.Deployment{
|
||||
ObjectMeta: objMeta,
|
||||
Spec: appsv1.DeploymentSpec{
|
||||
Replicas: &replicas,
|
||||
Selector: &metav1.LabelSelector{
|
||||
MatchLabels: selectorLabels,
|
||||
},
|
||||
Template: corev1.PodTemplateSpec{
|
||||
ObjectMeta: templateObjMeta,
|
||||
Spec: corev1.PodSpec{
|
||||
// SecurityContext: &corev1.PodSecurityContext{FSGroup: &group},
|
||||
Containers: []corev1.Container{
|
||||
corev1.Container{
|
||||
|
||||
Name: "login-ui",
|
||||
Image: instance.Spec.LoginUI.Image.Name + ":" + tag,
|
||||
ImagePullPolicy: corev1.PullIfNotPresent,
|
||||
Env: []corev1.EnvVar{
|
||||
{
|
||||
Name: "ZITADEL_SERVICE_USER_TOKEN_FILE",
|
||||
Value: "/login-client/pat",
|
||||
},
|
||||
|
||||
{
|
||||
Name: "ZITADEL_API_URL",
|
||||
Value: fmt.Sprintf("http://%s:%d", deployment.ServiceFQDN(cluster.ObjectMeta), deployment.ZitadelPort),
|
||||
},
|
||||
|
||||
{
|
||||
Name: "CUSTOM_REQUEST_HEADERS",
|
||||
Value: fmt.Sprintf("Host:%s,X-Zitadel-Public-Host:%s", customDomain, customDomain),
|
||||
},
|
||||
},
|
||||
Ports: []corev1.ContainerPort{
|
||||
{Name: deployment.LoginName, ContainerPort: deployment.LoginPort},
|
||||
},
|
||||
LivenessProbe: &corev1.Probe{
|
||||
ProbeHandler: corev1.ProbeHandler{
|
||||
HTTPGet: &corev1.HTTPGetAction{
|
||||
Path: "/ui/v2/login/healthy",
|
||||
Port: intstr.FromString(deployment.LoginName),
|
||||
Scheme: corev1.URISchemeHTTP,
|
||||
},
|
||||
},
|
||||
FailureThreshold: 3,
|
||||
InitialDelaySeconds: 0,
|
||||
PeriodSeconds: 5,
|
||||
},
|
||||
ReadinessProbe: &corev1.Probe{
|
||||
ProbeHandler: corev1.ProbeHandler{
|
||||
HTTPGet: &corev1.HTTPGetAction{
|
||||
Path: "/ui/v2/login/security",
|
||||
Port: intstr.FromString(deployment.LoginName),
|
||||
Scheme: corev1.URISchemeHTTP,
|
||||
},
|
||||
},
|
||||
FailureThreshold: 3,
|
||||
InitialDelaySeconds: 0,
|
||||
PeriodSeconds: 5,
|
||||
},
|
||||
|
||||
Resources: instance.Spec.LoginUI.Resources,
|
||||
VolumeMounts: []corev1.VolumeMount{
|
||||
{Name: "login-ui-pat", MountPath: "/login-client"},
|
||||
},
|
||||
},
|
||||
},
|
||||
Volumes: []corev1.Volume{
|
||||
{Name: "login-ui-pat", VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{
|
||||
SecretName: instance.LoginMachineUserName() + "-pat-secret",
|
||||
}}},
|
||||
},
|
||||
},
|
||||
},
|
||||
}}
|
||||
if err := controllerutil.SetControllerReference(instance, dep, b.scheme); err != nil {
|
||||
return nil, fmt.Errorf("error setting controller reference to Deployment: %v", err)
|
||||
}
|
||||
return dep, nil
|
||||
}
|
||||
51
pkg/builder/machine_user_builder.go
Normal file
51
pkg/builder/machine_user_builder.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
metadata "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/metadata"
|
||||
zitadelresourcesv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-resources-operator/api/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
type MachineUserOpts struct {
|
||||
Instance *zitadelv1alpha1.Instance
|
||||
Authorizations []zitadelresourcesv1alpha1.Authorization
|
||||
InternalPermissions []zitadelresourcesv1alpha1.InternalPermissions
|
||||
Username string
|
||||
}
|
||||
|
||||
func (b *Builder) BuildMachineUser(
|
||||
key types.NamespacedName,
|
||||
opts MachineUserOpts, owner metav1.Object) (*zitadelresourcesv1alpha1.MachineUser, error) {
|
||||
objMeta :=
|
||||
metadata.NewMetadataBuilder(key).
|
||||
Build()
|
||||
|
||||
mu := &zitadelresourcesv1alpha1.MachineUser{
|
||||
ObjectMeta: objMeta,
|
||||
Spec: zitadelresourcesv1alpha1.MachineUserSpec{
|
||||
OrganizationRef: zitadelresourcesv1alpha1.OrganizationRef{
|
||||
ObjectReference: corev1.ObjectReference{
|
||||
Kind: "Organization",
|
||||
Namespace: opts.Instance.Namespace,
|
||||
Name: opts.Instance.FirstOrgObjectName(),
|
||||
},
|
||||
},
|
||||
AccessTokenType: "ACCESS_TOKEN_TYPE_BEARER",
|
||||
Authorizations: opts.Authorizations,
|
||||
InternalPermissions: opts.InternalPermissions,
|
||||
Metadata: []map[string]string{},
|
||||
Username: opts.Username,
|
||||
},
|
||||
}
|
||||
|
||||
if err := controllerutil.SetControllerReference(owner, mu, b.scheme); err != nil {
|
||||
return nil, fmt.Errorf("error setting controller reference in Machine User manifest: %v", err)
|
||||
}
|
||||
return mu, nil
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
package metadata
|
||||
|
||||
import (
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -22,7 +22,7 @@ func NewMetadataBuilder(key types.NamespacedName) *MetadataBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
func (b *MetadataBuilder) WithZitadel(zitadel *zitadelv1alpha1.ZitadelCluster) *MetadataBuilder {
|
||||
func (b *MetadataBuilder) WithZitadel(zitadel *zitadelv1alpha1.Cluster) *MetadataBuilder {
|
||||
if zitadel == nil {
|
||||
return b
|
||||
}
|
||||
45
pkg/builder/organization_builder.go
Normal file
45
pkg/builder/organization_builder.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
metadata "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/metadata"
|
||||
zitadelresourcesv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-resources-operator/api/v1alpha1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
type OrganizationOpts struct {
|
||||
Key types.NamespacedName
|
||||
Zitadel *zitadelv1alpha1.Instance
|
||||
OrganizationName string
|
||||
}
|
||||
|
||||
func (b *Builder) BuildOrganization(opts OrganizationOpts, owner metav1.Object) (*zitadelresourcesv1alpha1.Organization, error) {
|
||||
objMeta :=
|
||||
metadata.NewMetadataBuilder(opts.Key).
|
||||
Build()
|
||||
|
||||
org := &zitadelresourcesv1alpha1.Organization{
|
||||
ObjectMeta: objMeta,
|
||||
Spec: zitadelresourcesv1alpha1.OrganizationSpec{
|
||||
ConnectionRef: zitadelresourcesv1alpha1.ConnectionRef{
|
||||
ObjectReference: corev1.ObjectReference{
|
||||
Kind: "Connection",
|
||||
Namespace: opts.Zitadel.Namespace,
|
||||
Name: opts.Zitadel.ConnectionObjectName(),
|
||||
APIVersion: "v1alpha1",
|
||||
},
|
||||
},
|
||||
OrganzationName: opts.OrganizationName,
|
||||
},
|
||||
}
|
||||
|
||||
if err := controllerutil.SetControllerReference(owner, org, b.scheme); err != nil {
|
||||
return nil, fmt.Errorf("error setting controller reference in Organization manifest: %v", err)
|
||||
}
|
||||
return org, nil
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
metadata "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder/metadata"
|
||||
"fmt"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
metadata "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/metadata"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
type SecretOpts struct {
|
||||
Zitadel *zitadelv1alpha1.ZitadelCluster
|
||||
Zitadel *zitadelv1alpha1.Cluster
|
||||
Key types.NamespacedName
|
||||
Data map[string][]byte
|
||||
Labels map[string]string
|
||||
69
pkg/builder/service_builder.go
Normal file
69
pkg/builder/service_builder.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package builder
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
labels "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/labels"
|
||||
metadata "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/metadata"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
||||
)
|
||||
|
||||
type ServiceOpts struct {
|
||||
Ports []corev1.ServicePort
|
||||
}
|
||||
|
||||
func (b *Builder) BuildService(zitadel *zitadelv1alpha1.Cluster, key types.NamespacedName,
|
||||
opts ServiceOpts) (*corev1.Service, error) {
|
||||
objMeta :=
|
||||
metadata.NewMetadataBuilder(key).
|
||||
WithZitadel(zitadel).
|
||||
Build()
|
||||
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: objMeta,
|
||||
Spec: corev1.ServiceSpec{
|
||||
Type: corev1.ServiceTypeClusterIP,
|
||||
Ports: opts.Ports,
|
||||
Selector: serviceSelectorLabels(opts, zitadel),
|
||||
},
|
||||
}
|
||||
if err := controllerutil.SetControllerReference(zitadel, svc, b.scheme); err != nil {
|
||||
return nil, fmt.Errorf("error setting controller reference to Service: %v", err)
|
||||
}
|
||||
return svc, nil
|
||||
}
|
||||
|
||||
func (b *Builder) BuildLoginService(instance *zitadelv1alpha1.Instance, key types.NamespacedName,
|
||||
opts ServiceOpts) (*corev1.Service, error) {
|
||||
objMeta :=
|
||||
metadata.NewMetadataBuilder(key).
|
||||
Build()
|
||||
|
||||
svc := &corev1.Service{
|
||||
ObjectMeta: objMeta,
|
||||
Spec: corev1.ServiceSpec{
|
||||
Type: corev1.ServiceTypeClusterIP,
|
||||
Ports: opts.Ports,
|
||||
Selector: serviceLoginSelectorLabels(opts, instance),
|
||||
},
|
||||
}
|
||||
if err := controllerutil.SetControllerReference(instance, svc, b.scheme); err != nil {
|
||||
return nil, fmt.Errorf("error setting controller reference to Service: %v", err)
|
||||
}
|
||||
return svc, nil
|
||||
}
|
||||
|
||||
func serviceLoginSelectorLabels(opts ServiceOpts, instance *zitadelv1alpha1.Instance) map[string]string {
|
||||
return labels.NewLabelsBuilder().
|
||||
WithLoginUISelectorLabels(instance).
|
||||
Build()
|
||||
}
|
||||
|
||||
func serviceSelectorLabels(opts ServiceOpts, cluster *zitadelv1alpha1.Cluster) map[string]string {
|
||||
return labels.NewLabelsBuilder().
|
||||
WithZitadelSelectorLabels(cluster).
|
||||
Build()
|
||||
}
|
||||
@@ -4,7 +4,7 @@ import (
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
)
|
||||
|
||||
func SetReadyHealthty(c Conditioner) {
|
||||
@@ -51,8 +51,8 @@ func SetReadyFailed(c Conditioner) {
|
||||
SetReadyFailedWithMessage(c, "Failed")
|
||||
}
|
||||
|
||||
func SetReadyWithDeployment(c Conditioner, sts *appsv1.Deployment, instanceId string) {
|
||||
if sts.Status.Replicas == 0 || sts.Status.ReadyReplicas != sts.Status.Replicas || instanceId == "" {
|
||||
func SetReadyWithDeployment(c Conditioner, sts *appsv1.Deployment) {
|
||||
if sts.Status.Replicas == 0 || sts.Status.ReadyReplicas != sts.Status.Replicas {
|
||||
c.SetCondition(metav1.Condition{
|
||||
Type: zitadelv1alpha1.ConditionTypeReady,
|
||||
Status: metav1.ConditionFalse,
|
||||
9
pkg/configuration/configuration.go
Normal file
9
pkg/configuration/configuration.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package configuration
|
||||
|
||||
import (
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
)
|
||||
|
||||
func ConfigurationName(zitadel *zitadelv1alpha1.Cluster) string {
|
||||
return zitadel.Name + "-configuration-configmap"
|
||||
}
|
||||
@@ -4,10 +4,10 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
builder "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder"
|
||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/deployment"
|
||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/masterkey"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
builder "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/deployment"
|
||||
systemapiaccount "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/systemapi"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -27,11 +27,10 @@ func NewConfigMapReconciler(client client.Client, builder *builder.Builder) *Con
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ConfigMapReconciler) ReconcileZitadelConfiguration(ctx context.Context, key types.NamespacedName, zitadel *zitadelv1alpha1.ZitadelCluster, postgres *cloudnativepgv1.Cluster, base64key string) error {
|
||||
func (r *ConfigMapReconciler) ReconcileZitadelConfiguration(ctx context.Context, key types.NamespacedName, zitadel *zitadelv1alpha1.Cluster, postgres *cloudnativepgv1.Cluster, base64key string) error {
|
||||
config := make(map[string]string)
|
||||
config["zitadel-config-yaml"] =
|
||||
fmt.Sprintf(`
|
||||
Database:
|
||||
fmt.Sprintf(`Database:
|
||||
Postgres:
|
||||
Host: %s
|
||||
Port: 5432
|
||||
@@ -57,6 +56,8 @@ Projections:
|
||||
Customizations:
|
||||
smtp_configs:
|
||||
BulkLimit: 2000
|
||||
FirstInstance:
|
||||
Skip: true
|
||||
SystemAPIUsers:
|
||||
- %s:
|
||||
KeyData: %s
|
||||
@@ -66,7 +67,7 @@ SystemAPIUsers:
|
||||
- "SYSTEM_OWNER"
|
||||
- "IAM_OWNER"
|
||||
- "ORG_OWNER"
|
||||
`, deployment.ServiceFQDNWithService(postgres.ObjectMeta, postgres.Name+"-rw"), zitadel.Spec.Host, zitadel.Spec.ExternalPort, zitadel.Spec.ExternalSecure, masterkey.OwnerName, base64key)
|
||||
`, deployment.ServiceFQDNWithService(postgres.ObjectMeta, postgres.Name+"-rw"), zitadel.Spec.Host, zitadel.Spec.ExternalPort, zitadel.Spec.ExternalSecure, systemapiaccount.OwnerName, base64key)
|
||||
|
||||
opts := builder.ConfigMapOpts{
|
||||
Zitadel: zitadel,
|
||||
@@ -8,8 +8,8 @@ import (
|
||||
"encoding/pem"
|
||||
"fmt"
|
||||
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
builder "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
builder "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder"
|
||||
"github.com/sethvargo/go-password/password"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
@@ -29,7 +29,7 @@ func NewSecretReconciler(client client.Client, builder *builder.Builder) *Secret
|
||||
}
|
||||
|
||||
func (r *SecretReconciler) ReconcileRandomPassword(ctx context.Context, key types.NamespacedName, secretKey string,
|
||||
zitadel *zitadelv1alpha1.ZitadelCluster) (string, error) {
|
||||
zitadel *zitadelv1alpha1.Cluster) (string, error) {
|
||||
var existingSecret corev1.Secret
|
||||
if err := r.Get(ctx, key, &existingSecret); err == nil {
|
||||
return string(existingSecret.Data[secretKey]), nil
|
||||
@@ -58,7 +58,7 @@ func (r *SecretReconciler) ReconcileRandomPassword(ctx context.Context, key type
|
||||
}
|
||||
|
||||
func (r *SecretReconciler) ReconcileRandomPrivateRSA(ctx context.Context, key types.NamespacedName, secretKey string,
|
||||
zitadel *zitadelv1alpha1.ZitadelCluster) (string, error) {
|
||||
zitadel *zitadelv1alpha1.Cluster) (string, error) {
|
||||
var existingSecret corev1.Secret
|
||||
if err := r.Get(ctx, key, &existingSecret); err == nil {
|
||||
return string(existingSecret.Data[secretKey]), nil
|
||||
@@ -1,4 +1,4 @@
|
||||
package zitadel
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
@@ -6,29 +6,29 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
condition "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/condition"
|
||||
health "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/health"
|
||||
zitadelClient "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/zitadel"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
condition "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/condition"
|
||||
health "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/health"
|
||||
zitadelClient "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/zitadel"
|
||||
"github.com/hashicorp/go-multierror"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||
)
|
||||
|
||||
type ZitadelReconciler struct {
|
||||
type SystemReconciler struct {
|
||||
Client client.Client
|
||||
RefResolver *zitadelv1alpha1.RefResolver
|
||||
ConditionReady *condition.Ready
|
||||
|
||||
WrappedReconciler WrappedReconciler
|
||||
WrappedReconciler WrappedSystemReconciler
|
||||
Finalizer Finalizer
|
||||
RequeueInterval time.Duration
|
||||
}
|
||||
|
||||
func NewZitadelReconciler(client client.Client, cr *condition.Ready, wr WrappedReconciler, f Finalizer,
|
||||
func NewSystemReconciler(client client.Client, cr *condition.Ready, wr WrappedSystemReconciler, f Finalizer,
|
||||
requeueInterval time.Duration) Reconciler {
|
||||
return &ZitadelReconciler{
|
||||
return &SystemReconciler{
|
||||
Client: client,
|
||||
RefResolver: zitadelv1alpha1.NewRefResolver(client),
|
||||
ConditionReady: cr,
|
||||
@@ -38,44 +38,44 @@ func NewZitadelReconciler(client client.Client, cr *condition.Ready, wr WrappedR
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ZitadelReconciler) Reconcile(ctx context.Context, resource Resource) (ctrl.Result, error) {
|
||||
func (r *SystemReconciler) Reconcile(ctx context.Context, resource Resource) (ctrl.Result, error) {
|
||||
if resource.IsBeingDeleted() {
|
||||
if err := r.Finalizer.Finalize(ctx, resource); err != nil {
|
||||
return ctrl.Result{}, fmt.Errorf("error finalizing %s: %v", resource.GetName(), err)
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
zitadelRef, err := resource.ZitadelClusterRef(ctx, r.RefResolver)
|
||||
clusterRef, err := resource.ClusterRef(ctx, r.RefResolver)
|
||||
if err != nil {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
zitadel, err := r.RefResolver.ZitadelCluster(ctx, zitadelRef, resource.GetNamespace())
|
||||
cluster, err := r.RefResolver.Cluster(ctx, clusterRef, resource.GetNamespace())
|
||||
if err != nil {
|
||||
var errBundle *multierror.Error
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
err = r.WrappedReconciler.PatchStatus(ctx, r.ConditionReady.PatcherRefResolver(err, zitadel))
|
||||
err = r.WrappedReconciler.PatchStatus(ctx, r.ConditionReady.PatcherRefResolver(err, cluster))
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
return ctrl.Result{}, fmt.Errorf("error getting ZitadelCluster: %v", errBundle)
|
||||
return ctrl.Result{}, fmt.Errorf("error getting Cluster: %v", errBundle)
|
||||
}
|
||||
|
||||
if err := waitForZitadelCluster(ctx, r.Client, resource, zitadel); err != nil {
|
||||
if err := waitForCluster(ctx, r.Client, resource, cluster); err != nil {
|
||||
var errBundle *multierror.Error
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
err := r.WrappedReconciler.PatchStatus(ctx, r.ConditionReady.PatcherWithError(err))
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
return ctrl.Result{}, fmt.Errorf("error waiting for Zitadel: %v", errBundle)
|
||||
return ctrl.Result{}, fmt.Errorf("error waiting for Cluster: %v", errBundle)
|
||||
}
|
||||
|
||||
ztdClient, err := zitadelClient.NewClient(ctx, zitadel, *r.RefResolver)
|
||||
ztdClient, err := zitadelClient.NewSystemClient(ctx, cluster, *r.RefResolver)
|
||||
if err != nil {
|
||||
var errBundle *multierror.Error
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
msg := fmt.Sprintf("Error connecting to Zitadel: %v", err)
|
||||
msg := fmt.Sprintf("Error connecting to System: %v", err)
|
||||
err = r.WrappedReconciler.PatchStatus(ctx, r.ConditionReady.PatcherFailed(msg))
|
||||
errBundle = multierror.Append(errBundle, err)
|
||||
|
||||
@@ -107,27 +107,27 @@ func (r *ZitadelReconciler) Reconcile(ctx context.Context, resource Resource) (c
|
||||
return r.requeueResult(ctx, resource)
|
||||
}
|
||||
|
||||
func (r *ZitadelReconciler) retryResult(ctx context.Context, resource Resource, err error) (ctrl.Result, error) {
|
||||
func (r *SystemReconciler) retryResult(ctx context.Context, resource Resource, err error) (ctrl.Result, error) {
|
||||
return ctrl.Result{}, err
|
||||
}
|
||||
|
||||
func (r *ZitadelReconciler) requeueResult(ctx context.Context, resource Resource) (ctrl.Result, error) {
|
||||
func (r *SystemReconciler) requeueResult(ctx context.Context, resource Resource) (ctrl.Result, error) {
|
||||
if r.RequeueInterval > 0 {
|
||||
log.FromContext(ctx).V(1).Info("Requeuing ZITADEL resource")
|
||||
log.FromContext(ctx).V(1).Info("Requeuing SYSTEM resource")
|
||||
return ctrl.Result{RequeueAfter: r.RequeueInterval}, nil
|
||||
}
|
||||
return ctrl.Result{}, nil
|
||||
}
|
||||
|
||||
func waitForZitadelCluster(ctx context.Context, client client.Client, resource Resource,
|
||||
zitadel *zitadelv1alpha1.ZitadelCluster) error {
|
||||
var zitadelErr *multierror.Error
|
||||
healthy, err := health.IsZitadelClusterHealthy(ctx, client, zitadel)
|
||||
func waitForCluster(ctx context.Context, client client.Client, resource Resource,
|
||||
system *zitadelv1alpha1.Cluster) error {
|
||||
var systemErr *multierror.Error
|
||||
healthy, err := health.IsClusterHealthy(ctx, client, system)
|
||||
if err != nil {
|
||||
zitadelErr = multierror.Append(zitadelErr, err)
|
||||
systemErr = multierror.Append(systemErr, err)
|
||||
}
|
||||
if !healthy {
|
||||
zitadelErr = multierror.Append(zitadelErr, errors.New("Zitadel not healthy"))
|
||||
systemErr = multierror.Append(systemErr, errors.New("System not healthy"))
|
||||
}
|
||||
return zitadelErr.ErrorOrNil()
|
||||
return systemErr.ErrorOrNil()
|
||||
}
|
||||
@@ -1,31 +1,31 @@
|
||||
package zitadel
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
zitadelClient "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/zitadel"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
zitadelClient "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/zitadel"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
type ZitadelFinalizer struct {
|
||||
type SystemFinalizer struct {
|
||||
Client client.Client
|
||||
RefResolver *zitadelv1alpha1.RefResolver
|
||||
|
||||
WrappedFinalizer WrappedFinalizer
|
||||
WrappedFinalizer WrappedSystemFinalizer
|
||||
}
|
||||
|
||||
func NewZitadelFinalizer(client client.Client, wf WrappedFinalizer) Finalizer {
|
||||
return &ZitadelFinalizer{
|
||||
func NewSystemFinalizer(client client.Client, wf WrappedSystemFinalizer) Finalizer {
|
||||
return &SystemFinalizer{
|
||||
Client: client,
|
||||
RefResolver: zitadelv1alpha1.NewRefResolver(client),
|
||||
WrappedFinalizer: wf,
|
||||
}
|
||||
}
|
||||
|
||||
func (tf *ZitadelFinalizer) AddFinalizer(ctx context.Context) error {
|
||||
func (tf *SystemFinalizer) AddFinalizer(ctx context.Context) error {
|
||||
if tf.WrappedFinalizer.ContainsFinalizer() {
|
||||
return nil
|
||||
}
|
||||
@@ -35,16 +35,16 @@ func (tf *ZitadelFinalizer) AddFinalizer(ctx context.Context) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (tf *ZitadelFinalizer) Finalize(ctx context.Context, resource Resource) error {
|
||||
func (tf *SystemFinalizer) Finalize(ctx context.Context, resource Resource) error {
|
||||
if !tf.WrappedFinalizer.ContainsFinalizer() {
|
||||
return nil
|
||||
}
|
||||
|
||||
zitadelRef, err := resource.ZitadelClusterRef(ctx, tf.RefResolver)
|
||||
clusterRef, err := resource.ClusterRef(ctx, tf.RefResolver)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
zitadel, err := tf.RefResolver.ZitadelCluster(ctx, zitadelRef, resource.GetNamespace())
|
||||
system, err := tf.RefResolver.Cluster(ctx, clusterRef, resource.GetNamespace())
|
||||
if err != nil {
|
||||
if apierrors.IsNotFound(err) {
|
||||
if err := tf.WrappedFinalizer.RemoveFinalizer(ctx); err != nil {
|
||||
@@ -52,16 +52,16 @@ func (tf *ZitadelFinalizer) Finalize(ctx context.Context, resource Resource) err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("error getting ZitadelCluster: %v", err)
|
||||
return fmt.Errorf("error getting System: %v", err)
|
||||
}
|
||||
|
||||
if err := waitForZitadelCluster(ctx, tf.Client, resource, zitadel); err != nil {
|
||||
return fmt.Errorf("error waiting for ZitadelCluster: %v", err)
|
||||
if err := waitForCluster(ctx, tf.Client, resource, system); err != nil {
|
||||
return fmt.Errorf("error waiting for System: %v", err)
|
||||
}
|
||||
|
||||
ztdClient, err := zitadelClient.NewClient(ctx, zitadel, *tf.RefResolver)
|
||||
ztdClient, err := zitadelClient.NewSystemClient(ctx, system, *tf.RefResolver)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error connecting to ZitadelCluster: %v", err)
|
||||
return fmt.Errorf("error connecting to System: %v", err)
|
||||
}
|
||||
defer ztdClient.Connection.Close()
|
||||
|
||||
39
pkg/controller/system/types.go
Normal file
39
pkg/controller/system/types.go
Normal file
@@ -0,0 +1,39 @@
|
||||
package system
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
"github.com/zitadel/zitadel-go/v3/pkg/client/system"
|
||||
|
||||
condition "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/condition"
|
||||
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
ctrl "sigs.k8s.io/controller-runtime"
|
||||
)
|
||||
|
||||
type Resource interface {
|
||||
v1.Object
|
||||
ClusterRef(context.Context, *zitadelv1alpha1.RefResolver) (*zitadelv1alpha1.ClusterRef, error)
|
||||
IsBeingDeleted() bool
|
||||
}
|
||||
|
||||
type Reconciler interface {
|
||||
Reconcile(ctx context.Context, resource Resource) (ctrl.Result, error)
|
||||
}
|
||||
|
||||
type WrappedSystemReconciler interface {
|
||||
Reconcile(context.Context, *system.Client) error
|
||||
PatchStatus(context.Context, condition.Patcher) error
|
||||
}
|
||||
|
||||
type Finalizer interface {
|
||||
AddFinalizer(context.Context) error
|
||||
Finalize(context.Context, Resource) error
|
||||
}
|
||||
|
||||
type WrappedSystemFinalizer interface {
|
||||
AddFinalizer(context.Context) error
|
||||
RemoveFinalizer(context.Context) error
|
||||
ContainsFinalizer() bool
|
||||
Reconcile(context.Context, *system.Client) error
|
||||
}
|
||||
@@ -12,6 +12,8 @@ import (
|
||||
const (
|
||||
ZitadelName = "zitadel"
|
||||
ZitadelPort = 8080
|
||||
LoginName = "login-ui"
|
||||
LoginPort = 3000
|
||||
SecretMountPath = "/var/secrets/"
|
||||
)
|
||||
|
||||
@@ -3,9 +3,9 @@ package health
|
||||
import (
|
||||
"context"
|
||||
|
||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
|
||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/deployment"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/deployment"
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
type EndpointPolicy string
|
||||
|
||||
func IsZitadelClusterHealthy(ctx context.Context, client ctrlclient.Client, zitadel *zitadelv1alpha1.ZitadelCluster) (bool, error) {
|
||||
func IsClusterHealthy(ctx context.Context, client ctrlclient.Client, zitadel *zitadelv1alpha1.Cluster) (bool, error) {
|
||||
key := ctrlclient.ObjectKeyFromObject(zitadel)
|
||||
var dep appsv1.Deployment
|
||||
if err := client.Get(ctx, key, &dep); err != nil {
|
||||
13
pkg/masterkey/masterkey.go
Normal file
13
pkg/masterkey/masterkey.go
Normal file
@@ -0,0 +1,13 @@
|
||||
package masterkey
|
||||
|
||||
import (
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
Key = "key"
|
||||
)
|
||||
|
||||
func MasterKeyName(zitadel *zitadelv1alpha1.Cluster) string {
|
||||
return zitadel.Name + "-masterkey-secret"
|
||||
}
|
||||
14
pkg/systemapi/systemapi_account.go
Normal file
14
pkg/systemapi/systemapi_account.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package systemapiaccount
|
||||
|
||||
import (
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
)
|
||||
|
||||
const (
|
||||
Key = "private.pem"
|
||||
OwnerName = "k8s-operator"
|
||||
)
|
||||
|
||||
func SystemAPIAccountName(zitadel *zitadelv1alpha1.Cluster) string {
|
||||
return zitadel.Name + "-systemapiaccount-secret"
|
||||
}
|
||||
76
pkg/zitadel/zitadel.go
Normal file
76
pkg/zitadel/zitadel.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package zitadel
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/deployment"
|
||||
systemapiaccount "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/systemapi"
|
||||
"google.golang.org/grpc"
|
||||
"strings"
|
||||
|
||||
"github.com/zitadel/zitadel-go/v3/pkg/client/zitadel"
|
||||
|
||||
"github.com/zitadel/zitadel-go/v3/pkg/client/system"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
type MachineKey struct {
|
||||
Type string `json:"type"`
|
||||
KeyID string `json:"keyId"`
|
||||
Key string `json:"key"`
|
||||
UserID string `json:"userId"`
|
||||
}
|
||||
|
||||
func WithAuthority(cluster *zitadelv1alpha1.Cluster) func() zitadel.Option {
|
||||
return func() zitadel.Option {
|
||||
return zitadel.WithDialOptions(grpc.WithAuthority(GetAuthority(cluster)))
|
||||
}
|
||||
}
|
||||
|
||||
func NewSystemClient(ctx context.Context, cluster *zitadelv1alpha1.Cluster, refresolver zitadelv1alpha1.RefResolver) (*system.Client, error) {
|
||||
privateKeyData, err := refresolver.SecretKeyRef(ctx, corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: systemapiaccount.SystemAPIAccountName(cluster)}, Key: systemapiaccount.Key}, cluster.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
systemClient, err := system.NewClient(ctx, GetIssuer(cluster), GetAPI(cluster),
|
||||
system.JWTProfileFromKey([]byte(strings.TrimSpace(privateKeyData)), systemapiaccount.OwnerName),
|
||||
system.WithInsecure(),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error creating system client: %v", err)
|
||||
}
|
||||
return systemClient, nil
|
||||
}
|
||||
|
||||
func GetAuthority(zitadel *zitadelv1alpha1.Cluster) string {
|
||||
return fmt.Sprintf("%s:%d", zitadel.Spec.Host, zitadel.Spec.ExternalPort)
|
||||
}
|
||||
|
||||
func GetInstanceAuthority(zitadel *zitadelv1alpha1.Instance, cluster *zitadelv1alpha1.Cluster) string {
|
||||
return fmt.Sprintf("%s:%d", zitadel.Spec.CustomDomain, cluster.Spec.ExternalPort)
|
||||
}
|
||||
|
||||
func GetIssuer(zitadel *zitadelv1alpha1.Cluster) string {
|
||||
scheme := "http"
|
||||
if zitadel.Spec.ExternalSecure {
|
||||
scheme = "https"
|
||||
}
|
||||
return fmt.Sprintf("%s://%s", scheme, zitadel.Spec.Host)
|
||||
}
|
||||
|
||||
func GetAPI(zitadel *zitadelv1alpha1.Cluster) string {
|
||||
return fmt.Sprintf("%s:%d", deployment.ServiceFQDN(zitadel.ObjectMeta), deployment.ZitadelPort)
|
||||
}
|
||||
|
||||
func GetAPIHost(zitadel *zitadelv1alpha1.Cluster) string {
|
||||
return fmt.Sprintf("%s", deployment.ServiceFQDN(zitadel.ObjectMeta))
|
||||
}
|
||||
|
||||
func GetAPIPort(zitadel *zitadelv1alpha1.Cluster) string {
|
||||
return fmt.Sprintf("%d", deployment.ZitadelPort)
|
||||
}
|
||||
|
||||
func GetAPIUrl(zitadel *zitadelv1alpha1.Cluster) string {
|
||||
return fmt.Sprintf("http://%s:%d", deployment.ServiceFQDN(zitadel.ObjectMeta), deployment.ZitadelPort)
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file
|
||||
# Ignore build and test binaries.
|
||||
bin/
|
||||
testbin/
|
||||
26
src/.gitignore
vendored
26
src/.gitignore
vendored
@@ -1,26 +0,0 @@
|
||||
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
*.exe~
|
||||
*.dll
|
||||
*.so
|
||||
*.dylib
|
||||
bin
|
||||
testbin/*
|
||||
Dockerfile.cross
|
||||
|
||||
# Test binary, build with `go test -c`
|
||||
*.test
|
||||
|
||||
# Output of the go coverage tool, specifically when used with LiteIDE
|
||||
*.out
|
||||
|
||||
# Kubernetes Generated files - skip generated files, except for vendored files
|
||||
|
||||
!vendor/**/zz_generated.*
|
||||
|
||||
# editor and IDE paraphernalia
|
||||
.idea
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
86
src/PROJECT
86
src/PROJECT
@@ -1,86 +0,0 @@
|
||||
# Code generated by tool. DO NOT EDIT.
|
||||
# This file is used to track the info used to scaffold your project
|
||||
# and allow the plugins properly work.
|
||||
# More info: https://book.kubebuilder.io/reference/project-config.html
|
||||
domain: topmanage.com
|
||||
layout:
|
||||
- go.kubebuilder.io/v4-alpha
|
||||
plugins:
|
||||
manifests.sdk.operatorframework.io/v2: {}
|
||||
scorecard.sdk.operatorframework.io/v2: {}
|
||||
projectName: src
|
||||
repo: bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src
|
||||
resources:
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: topmanage.com
|
||||
group: zitadel
|
||||
kind: ZitadelCluster
|
||||
path: bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1
|
||||
version: v1alpha1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: topmanage.com
|
||||
group: zitadel
|
||||
kind: Organization
|
||||
path: bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1
|
||||
version: v1alpha1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: topmanage.com
|
||||
group: zitadel
|
||||
kind: Project
|
||||
path: bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1
|
||||
version: v1alpha1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: topmanage.com
|
||||
group: zitadel
|
||||
kind: OIDCApp
|
||||
path: bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1
|
||||
version: v1alpha1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: topmanage.com
|
||||
group: zitadel
|
||||
kind: MachineUser
|
||||
path: bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1
|
||||
version: v1alpha1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: topmanage.com
|
||||
group: zitadel
|
||||
kind: APIApp
|
||||
path: bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1
|
||||
version: v1alpha1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: topmanage.com
|
||||
group: zitadel
|
||||
kind: Action
|
||||
path: bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1
|
||||
version: v1alpha1
|
||||
- api:
|
||||
crdVersion: v1
|
||||
namespaced: true
|
||||
controller: true
|
||||
domain: topmanage.com
|
||||
group: zitadel
|
||||
kind: Flow
|
||||
path: bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1
|
||||
version: v1alpha1
|
||||
version: "3"
|
||||
@@ -1,109 +0,0 @@
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
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 v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
// ActionSpec defines the desired state of Action
|
||||
type ActionSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// +kubebuilder:validation:Required
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
OrganizationRef OrganizationRef `json:"organizationRef"`
|
||||
Script string `json:"script"`
|
||||
// +kubebuilder:default=true
|
||||
AllowedToFail bool `json:"allowedToFail"`
|
||||
// +kubebuilder:validation:Type=string
|
||||
// +kubebuilder:validation:Format=duration
|
||||
Timeout *metav1.Duration `json:"timeout"`
|
||||
}
|
||||
|
||||
// ActionStatus defines the observed state of Action
|
||||
type ActionStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"}
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
// +kubebuilder:default=""
|
||||
ActionId string `json:"actionId"`
|
||||
}
|
||||
|
||||
func (d *ActionStatus) SetCondition(condition metav1.Condition) {
|
||||
if d.Conditions == nil {
|
||||
d.Conditions = make([]metav1.Condition, 0)
|
||||
}
|
||||
meta.SetStatusCondition(&d.Conditions, condition)
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
|
||||
// Action is the Schema for the actions API
|
||||
type Action struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ActionSpec `json:"spec,omitempty"`
|
||||
Status ActionStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (d *Action) IsBeingDeleted() bool {
|
||||
return !d.DeletionTimestamp.IsZero()
|
||||
}
|
||||
|
||||
func (d *Action) IsReady() bool {
|
||||
return meta.IsStatusConditionTrue(d.Status.Conditions, ConditionTypeReady)
|
||||
}
|
||||
|
||||
func (d *Action) ZitadelClusterRef(ctx context.Context, refresolver *RefResolver) (*ZitadelClusterRef, error) {
|
||||
org, err := refresolver.OrganizationRef(ctx, &d.Spec.OrganizationRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if org.Status.OrgId == "" {
|
||||
return nil, fmt.Errorf("Organization has not been created yet...")
|
||||
}
|
||||
|
||||
ref, err := org.ZitadelClusterRef(ctx, refresolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// ActionList contains a list of Action
|
||||
type ActionList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Action `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Action{}, &ActionList{})
|
||||
}
|
||||
@@ -1,134 +0,0 @@
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
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 v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
// APIAppSpec defines the desired state of APIApp
|
||||
type APIAppSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
ProjectRef ProjectRef `json:"projectRef"`
|
||||
// +kubebuilder:validation:Enum=API_AUTH_METHOD_TYPE_BASIC;API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT
|
||||
AuthMethodType string `json:"authMethodType"`
|
||||
}
|
||||
|
||||
// APIAppStatus defines the observed state of APIApp
|
||||
type APIAppStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"}
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
// +kubebuilder:default=""
|
||||
AppId string `json:"appId"`
|
||||
// +kubebuilder:default=""
|
||||
KeyId string `json:"keyId"`
|
||||
// +kubebuilder:default=""
|
||||
ClientId string `json:"clientId"`
|
||||
}
|
||||
|
||||
func (d *APIAppStatus) SetCondition(condition metav1.Condition) {
|
||||
if d.Conditions == nil {
|
||||
d.Conditions = make([]metav1.Condition, 0)
|
||||
}
|
||||
meta.SetStatusCondition(&d.Conditions, condition)
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
|
||||
// APIApp is the Schema for the apiapps API
|
||||
type APIApp struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec APIAppSpec `json:"spec,omitempty"`
|
||||
Status APIAppStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (d *APIApp) IsBeingDeleted() bool {
|
||||
return !d.DeletionTimestamp.IsZero()
|
||||
}
|
||||
|
||||
func (d *APIApp) IsReady() bool {
|
||||
return meta.IsStatusConditionTrue(d.Status.Conditions, ConditionTypeReady)
|
||||
}
|
||||
|
||||
func (d *APIApp) ZitadelClusterRef(ctx context.Context, refresolver *RefResolver) (*ZitadelClusterRef, error) {
|
||||
project, err := refresolver.ProjectRef(ctx, &d.Spec.ProjectRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if project.Status.ProjectId == "" {
|
||||
return nil, fmt.Errorf("Project has not been created yet...")
|
||||
}
|
||||
org, err := refresolver.OrganizationRef(ctx, &project.Spec.OrganizationRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if org.Status.OrgId == "" {
|
||||
return nil, fmt.Errorf("Organization has not been created yet...")
|
||||
}
|
||||
ref, err := org.ZitadelClusterRef(ctx, refresolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ref, nil
|
||||
}
|
||||
func (d *APIApp) Organization(ctx context.Context, refresolver *RefResolver) (*Organization, error) {
|
||||
project, err := refresolver.ProjectRef(ctx, &d.Spec.ProjectRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
org, err := refresolver.OrganizationRef(ctx, &project.Spec.OrganizationRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return org, nil
|
||||
}
|
||||
|
||||
func (d *APIApp) Project(ctx context.Context, refresolver *RefResolver) (*Project, error) {
|
||||
project, err := refresolver.ProjectRef(ctx, &d.Spec.ProjectRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return project, nil
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// APIAppList contains a list of APIApp
|
||||
type APIAppList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []APIApp `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&APIApp{}, &APIAppList{})
|
||||
}
|
||||
@@ -1,106 +0,0 @@
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
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 v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
// FlowSpec defines the desired state of Flow
|
||||
type FlowSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// +kubebuilder:validation:Required
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
OrganizationRef OrganizationRef `json:"organizationRef"`
|
||||
// +kubebuilder:validation:Enum=FLOW_TYPE_EXTERNAL_AUTHENTICATION;"1";"2";"3";"4"
|
||||
FlowType string `json:"flowType"`
|
||||
// +kubebuilder:validation:Enum=TRIGGER_TYPE_POST_AUTHENTICATION;TRIGGER_TYPE_PRE_CREATION;TRIGGER_TYPE_POST_CREATION;TRIGGER_TYPE_POST_AUTHENTICATION;TRIGGER_TYPE_PRE_CREATION;TRIGGER_TYPE_POST_CREATION;"1";"2";"3";"4";"5";"6"
|
||||
TriggerType string `json:"triggerType"`
|
||||
ActionRefs []ActionRef `json:"actionRefs"`
|
||||
}
|
||||
|
||||
// FlowStatus defines the observed state of Flow
|
||||
type FlowStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"}
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
func (d *FlowStatus) SetCondition(condition metav1.Condition) {
|
||||
if d.Conditions == nil {
|
||||
d.Conditions = make([]metav1.Condition, 0)
|
||||
}
|
||||
meta.SetStatusCondition(&d.Conditions, condition)
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
|
||||
// Flow is the Schema for the flows API
|
||||
type Flow struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec FlowSpec `json:"spec,omitempty"`
|
||||
Status FlowStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (d *Flow) IsBeingDeleted() bool {
|
||||
return !d.DeletionTimestamp.IsZero()
|
||||
}
|
||||
|
||||
func (d *Flow) IsReady() bool {
|
||||
return meta.IsStatusConditionTrue(d.Status.Conditions, ConditionTypeReady)
|
||||
}
|
||||
|
||||
func (d *Flow) ZitadelClusterRef(ctx context.Context, refresolver *RefResolver) (*ZitadelClusterRef, error) {
|
||||
org, err := refresolver.OrganizationRef(ctx, &d.Spec.OrganizationRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if org.Status.OrgId == "" {
|
||||
return nil, fmt.Errorf("Organization has not been created yet...")
|
||||
}
|
||||
|
||||
ref, err := org.ZitadelClusterRef(ctx, refresolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// FlowList contains a list of Flow
|
||||
type FlowList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Flow `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Flow{}, &FlowList{})
|
||||
}
|
||||
@@ -1,131 +0,0 @@
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
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 v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
type UserGrant struct {
|
||||
ProjectRef ProjectRef `json:"projectRef"`
|
||||
RoleKeys []string `json:"roleKeys,omitempty"`
|
||||
}
|
||||
|
||||
// MachineUserSpec defines the desired state of MachineUser
|
||||
type MachineUserSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// +kubebuilder:validation:Required
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
OrganizationRef OrganizationRef `json:"organizationRef" webhook:"inmutable"`
|
||||
// +kubebuilder:validation:Enum=ACCESS_TOKEN_TYPE_BEARER;ACCESS_TOKEN_TYPE_JWT
|
||||
AccessTokenType string `json:"accessTokenType"`
|
||||
UserGrants []UserGrant `json:"userGrants,omitempty"`
|
||||
}
|
||||
|
||||
// MachineUserStatus defines the observed state of MachineUser
|
||||
type MachineUserStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"}
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
// +kubebuilder:default=""
|
||||
UserId string `json:"userId"`
|
||||
// +kubebuilder:default=""
|
||||
KeyId string `json:"keyId"`
|
||||
// +kubebuilder:default=""
|
||||
PATId string `json:"patId"`
|
||||
}
|
||||
|
||||
func (d *MachineUserStatus) SetCondition(condition metav1.Condition) {
|
||||
if d.Conditions == nil {
|
||||
d.Conditions = make([]metav1.Condition, 0)
|
||||
}
|
||||
meta.SetStatusCondition(&d.Conditions, condition)
|
||||
}
|
||||
|
||||
func (d *MachineUserStatus) GetConditionStatus(conditionType string) bool {
|
||||
if d.Conditions == nil {
|
||||
d.Conditions = make([]metav1.Condition, 0)
|
||||
}
|
||||
return meta.IsStatusConditionTrue(d.Conditions, conditionType)
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
|
||||
// MachineUser is the Schema for the machineusers API
|
||||
type MachineUser struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec MachineUserSpec `json:"spec,omitempty"`
|
||||
Status MachineUserStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (d *MachineUser) IsBeingDeleted() bool {
|
||||
return !d.DeletionTimestamp.IsZero()
|
||||
}
|
||||
|
||||
func (d *MachineUser) IsReady() bool {
|
||||
return meta.IsStatusConditionTrue(d.Status.Conditions, ConditionTypeReady)
|
||||
}
|
||||
|
||||
func (d *MachineUser) ZitadelClusterRef(ctx context.Context, refresolver *RefResolver) (*ZitadelClusterRef, error) {
|
||||
org, err := refresolver.OrganizationRef(ctx, &d.Spec.OrganizationRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if org.Status.OrgId == "" {
|
||||
return nil, fmt.Errorf("Organization has not been created yet...")
|
||||
}
|
||||
ref, err := org.ZitadelClusterRef(ctx, refresolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
func (d *MachineUser) PatSecretName() string {
|
||||
return d.Name + "-pat-secret"
|
||||
}
|
||||
|
||||
func (d *MachineUser) JWTSecretName() string {
|
||||
return d.Name + "-machinekey-secret"
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// MachineUserList contains a list of MachineUser
|
||||
type MachineUserList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []MachineUser `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&MachineUser{}, &MachineUserList{})
|
||||
}
|
||||
@@ -1,161 +0,0 @@
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
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 v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
// +kubebuilder:validation:Enum=OIDC_RESPONSE_TYPE_CODE;OIDC_RESPONSE_TYPE_ID_TOKEN;OIDC_RESPONSE_TYPE_ID_TOKEN_TOKEN
|
||||
type ResponseType string
|
||||
|
||||
// +kubebuilder:validation:Enum=OIDC_GRANT_TYPE_AUTHORIZATION_CODE;OIDC_GRANT_TYPE_IMPLICIT;OIDC_GRANT_TYPE_REFRESH_TOKEN;OIDC_GRANT_TYPE_DEVICE_CODE;OIDC_GRANT_TYPE_TOKEN_EXCHANGE
|
||||
type GrantType string
|
||||
|
||||
// OIDCAppSpec defines the desired state of OIDCApp
|
||||
type OIDCAppSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
ProjectRef ProjectRef `json:"projectRef"`
|
||||
RedirectUris []string `json:"redirectUris"`
|
||||
ResponseTypes []ResponseType `json:"responseTypes"`
|
||||
GrantTypes []GrantType `json:"grantTypes"`
|
||||
// +kubebuilder:validation:Enum=OIDC_APP_TYPE_WEB;OIDC_APP_TYPE_USER_AGENT;OIDC_APP_TYPE_NATIVE
|
||||
AppType string `json:"appType"`
|
||||
// +kubebuilder:validation:Enum=OIDC_AUTH_METHOD_TYPE_BASIC;OIDC_AUTH_METHOD_TYPE_POST;OIDC_AUTH_METHOD_TYPE_NONE;OIDC_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT
|
||||
AuthMethodType string `json:"authMethodType"`
|
||||
PostLogoutRedirectUris []string `json:"postLogoutRedirectUris"`
|
||||
DevMode bool `json:"devMode"`
|
||||
// +kubebuilder:validation:Enum=OIDC_TOKEN_TYPE_BEARER;OIDC_TOKEN_TYPE_JWT
|
||||
AccessTokenType string `json:"accessTokenType"`
|
||||
AccessTokenRoleAssertion bool `json:"accessTokenRoleAssertion"`
|
||||
IdTokenRoleAssertion bool `json:"idTokenRoleAssertion"`
|
||||
IdTokenUserinfoAssertion bool `json:"idTokenUserinfoAssertion"`
|
||||
// +kubebuilder:validation:Type=string
|
||||
// +kubebuilder:validation:Format=duration
|
||||
ClockSkew *metav1.Duration `json:"clockSkew"`
|
||||
// +optional
|
||||
AdditionalOrigins []string `json:"additionalOrigins"`
|
||||
SkipNativeAppSuccessPage bool `json:"skipNativeAppSuccessPage"`
|
||||
}
|
||||
|
||||
// OIDCAppStatus defines the observed state of OIDCApp
|
||||
type OIDCAppStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"}
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
// +kubebuilder:default=""
|
||||
AppId string `json:"appId"`
|
||||
// +kubebuilder:default=""
|
||||
ClientId string `json:"clientId"`
|
||||
}
|
||||
|
||||
func (d *OIDCAppStatus) SetCondition(condition metav1.Condition) {
|
||||
if d.Conditions == nil {
|
||||
d.Conditions = make([]metav1.Condition, 0)
|
||||
}
|
||||
meta.SetStatusCondition(&d.Conditions, condition)
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
|
||||
// OIDCApp is the Schema for the oidcapps API
|
||||
type OIDCApp struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec OIDCAppSpec `json:"spec,omitempty"`
|
||||
Status OIDCAppStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (d *OIDCApp) IsBeingDeleted() bool {
|
||||
return !d.DeletionTimestamp.IsZero()
|
||||
}
|
||||
|
||||
func (d *OIDCApp) IsReady() bool {
|
||||
return meta.IsStatusConditionTrue(d.Status.Conditions, ConditionTypeReady)
|
||||
}
|
||||
|
||||
func (d *OIDCApp) ZitadelClusterRef(ctx context.Context, refresolver *RefResolver) (*ZitadelClusterRef, error) {
|
||||
project, err := refresolver.ProjectRef(ctx, &d.Spec.ProjectRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if project.Status.ProjectId == "" {
|
||||
return nil, fmt.Errorf("Project has not been created yet...")
|
||||
}
|
||||
org, err := refresolver.OrganizationRef(ctx, &project.Spec.OrganizationRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if org.Status.OrgId == "" {
|
||||
return nil, fmt.Errorf("Organization has not been created yet...")
|
||||
}
|
||||
ref, err := org.ZitadelClusterRef(ctx, refresolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ref, nil
|
||||
}
|
||||
func (d *OIDCApp) Organization(ctx context.Context, refresolver *RefResolver) (*Organization, error) {
|
||||
project, err := refresolver.ProjectRef(ctx, &d.Spec.ProjectRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
org, err := refresolver.OrganizationRef(ctx, &project.Spec.OrganizationRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return org, nil
|
||||
}
|
||||
|
||||
func (d *OIDCApp) Project(ctx context.Context, refresolver *RefResolver) (*Project, error) {
|
||||
project, err := refresolver.ProjectRef(ctx, &d.Spec.ProjectRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return project, nil
|
||||
}
|
||||
|
||||
func (d *OIDCApp) ClientSecretName() string {
|
||||
return d.Name + "-client-secret"
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// OIDCAppList contains a list of OIDCApp
|
||||
type OIDCAppList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []OIDCApp `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&OIDCApp{}, &OIDCAppList{})
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
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 v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
type OrganizationAdmin struct {
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
Email string `json:"email"`
|
||||
UserName string `json:"userName"`
|
||||
}
|
||||
|
||||
// OrganizationSpec defines the desired state of Organization
|
||||
type OrganizationSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// +kubebuilder:validation:Required
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
ZitadelClusterRef ZitadelClusterRef `json:"zitadelClusterRef" webhook:"inmutable"`
|
||||
OrganizationAdmin OrganizationAdmin `json:"organizationAdmin"`
|
||||
}
|
||||
|
||||
// OrganizationStatus defines the observed state of Organization
|
||||
type OrganizationStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// Conditions for the Database object.
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"}
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
// +kubebuilder:default=""
|
||||
OrgId string `json:"orgId"`
|
||||
// +kubebuilder:default=""
|
||||
AdminId string `json:"adminId"`
|
||||
}
|
||||
|
||||
func (d *OrganizationStatus) SetCondition(condition metav1.Condition) {
|
||||
if d.Conditions == nil {
|
||||
d.Conditions = make([]metav1.Condition, 0)
|
||||
}
|
||||
meta.SetStatusCondition(&d.Conditions, condition)
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
|
||||
// Organization is the Schema for the organizations API
|
||||
type Organization struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec OrganizationSpec `json:"spec,omitempty"`
|
||||
Status OrganizationStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (d *Organization) IsBeingDeleted() bool {
|
||||
return !d.DeletionTimestamp.IsZero()
|
||||
}
|
||||
|
||||
func (d *Organization) IsReady() bool {
|
||||
return meta.IsStatusConditionTrue(d.Status.Conditions, ConditionTypeReady)
|
||||
}
|
||||
|
||||
func (d *Organization) ZitadelClusterRef(_ context.Context, _ *RefResolver) (*ZitadelClusterRef, error) {
|
||||
return &d.Spec.ZitadelClusterRef, nil
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// OrganizationList contains a list of Organization
|
||||
type OrganizationList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Organization `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Organization{}, &OrganizationList{})
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
Copyright 2024.
|
||||
|
||||
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 v1alpha1
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"k8s.io/apimachinery/pkg/api/meta"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
||||
|
||||
type Role struct {
|
||||
Key string `json:"key"`
|
||||
DisplayName string `json:"displayName"`
|
||||
Group string `json:"group"`
|
||||
}
|
||||
type Grant struct {
|
||||
OrganizationRef OrganizationRef `json:"organizationRef"`
|
||||
RoleKeys []string `json:"roleKeys"`
|
||||
}
|
||||
|
||||
// ProjectSpec defines the desired state of Project
|
||||
type ProjectSpec struct {
|
||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// https://zitadel.com/docs/apis/resources/mgmt/management-service-add-project
|
||||
// +kubebuilder:validation:Required
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
OrganizationRef OrganizationRef `json:"organizationRef"`
|
||||
// +optional
|
||||
Roles []Role `json:"roles"`
|
||||
// +optional
|
||||
Grants []Grant `json:"grants"`
|
||||
// +optional
|
||||
ProjectRoleAssertion bool `json:"projectRoleAssertion,omitempty"`
|
||||
// +optional
|
||||
ProjectRoleCheck bool `json:"projectRoleCheck,omitempty"`
|
||||
// +optional
|
||||
HasProjectCheck bool `json:"hasProjectCheck,omitempty"`
|
||||
}
|
||||
|
||||
// ProjectStatus defines the observed state of Project
|
||||
type ProjectStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
// Conditions for the Database object.
|
||||
// +optional
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"}
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
// +kubebuilder:default=""
|
||||
ProjectId string `json:"projectId"`
|
||||
}
|
||||
|
||||
func (d *ProjectStatus) SetCondition(condition metav1.Condition) {
|
||||
if d.Conditions == nil {
|
||||
d.Conditions = make([]metav1.Condition, 0)
|
||||
}
|
||||
meta.SetStatusCondition(&d.Conditions, condition)
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
//+kubebuilder:subresource:status
|
||||
|
||||
// Project is the Schema for the projects API
|
||||
type Project struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec ProjectSpec `json:"spec,omitempty"`
|
||||
Status ProjectStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (d *Project) IsBeingDeleted() bool {
|
||||
return !d.DeletionTimestamp.IsZero()
|
||||
}
|
||||
|
||||
func (d *Project) IsReady() bool {
|
||||
return meta.IsStatusConditionTrue(d.Status.Conditions, ConditionTypeReady)
|
||||
}
|
||||
|
||||
func (d *Project) ZitadelClusterRef(ctx context.Context, refresolver *RefResolver) (*ZitadelClusterRef, error) {
|
||||
org, err := refresolver.OrganizationRef(ctx, &d.Spec.OrganizationRef, d.Namespace)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if org.Status.OrgId == "" {
|
||||
return nil, fmt.Errorf("Organization has not been created yet...")
|
||||
}
|
||||
|
||||
ref, err := org.ZitadelClusterRef(ctx, refresolver)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return ref, nil
|
||||
}
|
||||
|
||||
//+kubebuilder:object:root=true
|
||||
|
||||
// ProjectList contains a list of Project
|
||||
type ProjectList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Project `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Project{}, &ProjectList{})
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
type OIDCAppRef struct {
|
||||
// ObjectReference is a reference to a object.
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
}
|
||||
|
||||
type PostgreSQLClusterRef struct {
|
||||
// ObjectReference is a reference to a object.
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
}
|
||||
|
||||
type ZitadelClusterRef struct {
|
||||
// ObjectReference is a reference to a object.
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
}
|
||||
|
||||
type OrganizationRef struct {
|
||||
// ObjectReference is a reference to a object.
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
}
|
||||
|
||||
type ProjectRef struct {
|
||||
// ObjectReference is a reference to a object.
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
}
|
||||
|
||||
type ActionRef struct {
|
||||
// ObjectReference is a reference to a object.
|
||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||
corev1.ObjectReference `json:",inline"`
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,173 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
annotations:
|
||||
controller-gen.kubebuilder.io/version: v0.17.3
|
||||
name: actions.zitadel.topmanage.com
|
||||
spec:
|
||||
group: zitadel.topmanage.com
|
||||
names:
|
||||
kind: Action
|
||||
listKind: ActionList
|
||||
plural: actions
|
||||
singular: action
|
||||
scope: Namespaced
|
||||
versions:
|
||||
- name: v1alpha1
|
||||
schema:
|
||||
openAPIV3Schema:
|
||||
description: Action is the Schema for the actions API
|
||||
properties:
|
||||
apiVersion:
|
||||
description: |-
|
||||
APIVersion defines the versioned schema of this representation of an object.
|
||||
Servers should convert recognized schemas to the latest internal value, and
|
||||
may reject unrecognized values.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind is a string value representing the REST resource this object represents.
|
||||
Servers may infer this from the endpoint the client submits requests to.
|
||||
Cannot be updated.
|
||||
In CamelCase.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
metadata:
|
||||
type: object
|
||||
spec:
|
||||
description: ActionSpec defines the desired state of Action
|
||||
properties:
|
||||
allowedToFail:
|
||||
default: true
|
||||
type: boolean
|
||||
organizationRef:
|
||||
description: |-
|
||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
properties:
|
||||
apiVersion:
|
||||
description: API version of the referent.
|
||||
type: string
|
||||
fieldPath:
|
||||
description: |-
|
||||
If referring to a piece of an object instead of an entire object, this string
|
||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
||||
referencing a part of an object.
|
||||
type: string
|
||||
kind:
|
||||
description: |-
|
||||
Kind of the referent.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||
type: string
|
||||
name:
|
||||
description: |-
|
||||
Name of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
||||
type: string
|
||||
namespace:
|
||||
description: |-
|
||||
Namespace of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
||||
type: string
|
||||
resourceVersion:
|
||||
description: |-
|
||||
Specific resourceVersion to which this reference is made, if any.
|
||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
||||
type: string
|
||||
uid:
|
||||
description: |-
|
||||
UID of the referent.
|
||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
|
||||
type: string
|
||||
type: object
|
||||
x-kubernetes-map-type: atomic
|
||||
script:
|
||||
type: string
|
||||
timeout:
|
||||
format: duration
|
||||
type: string
|
||||
required:
|
||||
- allowedToFail
|
||||
- organizationRef
|
||||
- script
|
||||
- timeout
|
||||
type: object
|
||||
status:
|
||||
description: ActionStatus defines the observed state of Action
|
||||
properties:
|
||||
actionId:
|
||||
default: ""
|
||||
type: string
|
||||
conditions:
|
||||
description: |-
|
||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
Important: Run "make" to regenerate code after modifying this file
|
||||
items:
|
||||
description: Condition contains details for one aspect of the current
|
||||
state of this API Resource.
|
||||
properties:
|
||||
lastTransitionTime:
|
||||
description: |-
|
||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||
format: date-time
|
||||
type: string
|
||||
message:
|
||||
description: |-
|
||||
message is a human readable message indicating details about the transition.
|
||||
This may be an empty string.
|
||||
maxLength: 32768
|
||||
type: string
|
||||
observedGeneration:
|
||||
description: |-
|
||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||
with respect to the current state of the instance.
|
||||
format: int64
|
||||
minimum: 0
|
||||
type: integer
|
||||
reason:
|
||||
description: |-
|
||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||
Producers of specific condition types may define expected values and meanings for this field,
|
||||
and whether the values are considered a guaranteed API.
|
||||
The value should be a CamelCase string.
|
||||
This field may not be empty.
|
||||
maxLength: 1024
|
||||
minLength: 1
|
||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||
type: string
|
||||
status:
|
||||
description: status of the condition, one of True, False, Unknown.
|
||||
enum:
|
||||
- "True"
|
||||
- "False"
|
||||
- Unknown
|
||||
type: string
|
||||
type:
|
||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||
maxLength: 316
|
||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||
type: string
|
||||
required:
|
||||
- lastTransitionTime
|
||||
- message
|
||||
- reason
|
||||
- status
|
||||
- type
|
||||
type: object
|
||||
type: array
|
||||
required:
|
||||
- actionId
|
||||
type: object
|
||||
type: object
|
||||
served: true
|
||||
storage: true
|
||||
subresources:
|
||||
status: {}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user