Compare commits
10 Commits
897ce79223
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 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.
|
# 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
|
# 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.
|
# github.com/src-bundle:$VERSION and github.com/src-catalog:$VERSION.
|
||||||
IMAGE_TAG_BASE ?= topmanage.com/src
|
IMAGE_TAG_BASE ?= github.com/src
|
||||||
|
|
||||||
# BUNDLE_IMG defines the image:tag used for the bundle.
|
# 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>)
|
# 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"
|
||||||
@@ -22,18 +22,18 @@ import (
|
|||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
|
|
||||||
// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
|
// Image defines the container image name and tag.
|
||||||
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
|
|
||||||
|
|
||||||
type Image struct {
|
type Image struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Tag string `json:"tag"`
|
Tag string `json:"tag"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Password holds a reference to a Kubernetes Secret key containing a password.
|
||||||
type Password struct {
|
type Password struct {
|
||||||
SecretKeyRef corev1.SecretKeySelector `json:"secretRef"`
|
SecretKeyRef corev1.SecretKeySelector `json:"secretRef"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SMTPConfig configures an SMTP provider.
|
||||||
type SMTPConfig struct {
|
type SMTPConfig struct {
|
||||||
SenderAddress string `json:"senderAddress"`
|
SenderAddress string `json:"senderAddress"`
|
||||||
SenderName string `json:"senderName"`
|
SenderName string `json:"senderName"`
|
||||||
@@ -45,6 +45,7 @@ type SMTPConfig struct {
|
|||||||
ReplyToAddress *string `json:"replyToAddress,omitempty"`
|
ReplyToAddress *string `json:"replyToAddress,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DomainSettings configures domain-related behaviour.
|
||||||
type DomainSettings struct {
|
type DomainSettings struct {
|
||||||
// +kubebuilder:default=true
|
// +kubebuilder:default=true
|
||||||
UserLoginMustBeDomain bool `json:"userLoginMustBeDomain"`
|
UserLoginMustBeDomain bool `json:"userLoginMustBeDomain"`
|
||||||
@@ -54,61 +55,65 @@ type DomainSettings struct {
|
|||||||
SMTPSenderAddressMatchesInstanceDomain bool `json:"smtpSenderAddressMatchesInstanceDomain"`
|
SMTPSenderAddressMatchesInstanceDomain bool `json:"smtpSenderAddressMatchesInstanceDomain"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// ZitadelClusterSpec defines the desired state of ZitadelCluster
|
// ClusterSpec defines the desired state of Cluster.
|
||||||
type ZitadelClusterSpec struct {
|
type ClusterSpec struct {
|
||||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
// Host is the external hostname used to reach Zitadel.
|
||||||
// Important: Run "make" to regenerate code after modifying this file
|
Host string `json:"host"`
|
||||||
// +kubebuilder:default="DEFAULT"
|
|
||||||
FirstOrgName string `json:"firstOrgName"`
|
// ExternalPort is the port exposed externally.
|
||||||
DomainSettings DomainSettings `json:"domainSettings"`
|
|
||||||
SMTPConfig SMTPConfig `json:"smtpConfig"`
|
|
||||||
Host string `json:"host"`
|
|
||||||
// +kubebuilder:default=443
|
// +kubebuilder:default=443
|
||||||
ExternalPort int64 `json:"externalPort"`
|
ExternalPort int64 `json:"externalPort"`
|
||||||
// +kubebuilder:default=true
|
|
||||||
ExternalSecure bool `json:"externalSecure"`
|
|
||||||
Image Image `json:"image"`
|
|
||||||
Resources corev1.ResourceRequirements `json:"resources"`
|
|
||||||
PostgreSQLClusterRef PostgreSQLClusterRef `json:"postgresClusterRef"`
|
|
||||||
// +kubebuilder:validation:Enum=demo;trial;staging;productive;testing
|
|
||||||
Purpose string `json:"purpose"`
|
|
||||||
// PodAnnotations to add to the Pods metadata.
|
|
||||||
// +optional
|
|
||||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
|
||||||
PodAnnotations map[string]string `json:"podAnnotations,omitempty"`
|
|
||||||
// ServiceAnnotations to add to the service metadata.
|
|
||||||
// +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
|
// ExternalSecure indicates whether TLS is used on the external endpoint.
|
||||||
type ZitadelClusterStatus struct {
|
// +kubebuilder:default=true
|
||||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
ExternalSecure bool `json:"externalSecure"`
|
||||||
// Important: Run "make" to regenerate code after modifying this file
|
|
||||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
// 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"`
|
||||||
|
|
||||||
|
// Replicas is the desired number of Zitadel pods.
|
||||||
// +kubebuilder:default=3
|
// +kubebuilder:default=3
|
||||||
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podCount"}
|
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podCount"}
|
||||||
Replicas int32 `json:"replicas,omitempty"`
|
Replicas int32 `json:"replicas,omitempty"`
|
||||||
// +kubebuilder:default=""
|
|
||||||
DefaultInstanceId string `json:"defaultInstanceId"`
|
// PodAnnotations are extra annotations added to each Zitadel Pod.
|
||||||
// +kubebuilder:default=""
|
// +optional
|
||||||
SMTPProviderId string `json:"smtpProviderId"`
|
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||||
|
PodAnnotations map[string]string `json:"podAnnotations,omitempty"`
|
||||||
|
|
||||||
|
// ServiceAnnotations are extra annotations added to the Zitadel Service.
|
||||||
|
// +optional
|
||||||
|
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||||
|
ServiceAnnotations map[string]string `json:"serviceAnnotations,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCondition sets a status condition
|
// ClusterStatus defines the observed state of Cluster.
|
||||||
func (s *ZitadelClusterStatus) SetCondition(condition metav1.Condition) {
|
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=status,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podCount"}
|
||||||
|
Replicas int32 `json:"replicas,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetCondition sets a status condition on the Cluster.
|
||||||
|
func (s *ClusterStatus) SetCondition(condition metav1.Condition) {
|
||||||
if s.Conditions == nil {
|
if s.Conditions == nil {
|
||||||
s.Conditions = make([]metav1.Condition, 0)
|
s.Conditions = make([]metav1.Condition, 0)
|
||||||
}
|
}
|
||||||
meta.SetStatusCondition(&s.Conditions, condition)
|
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 {
|
for _, c := range s.Conditions {
|
||||||
if c.Type == ConditionTypeReady && c.Status == metav1.ConditionTrue {
|
if c.Type == ConditionTypeReady && c.Status == metav1.ConditionTrue {
|
||||||
return true
|
return true
|
||||||
@@ -117,35 +122,40 @@ func (s *ZitadelClusterStatus) IsReady() bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *ZitadelClusterStatus) FillWithDefaults(zitadel *ZitadelCluster) {
|
// FillWithDefaults populates default values on the Cluster status.
|
||||||
//(Haim ;^D ): No defaults yet
|
func (s *ClusterStatus) FillWithDefaults(_ *Cluster) {
|
||||||
|
// (Haim ;^D): No defaults yet
|
||||||
}
|
}
|
||||||
|
|
||||||
//+kubebuilder:object:root=true
|
//+kubebuilder:object:root=true
|
||||||
//+kubebuilder:subresource:status
|
//+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
|
// Cluster is the Schema for the clusters API.
|
||||||
type ZitadelCluster struct {
|
type Cluster struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||||
|
|
||||||
Spec ZitadelClusterSpec `json:"spec,omitempty"`
|
Spec ClusterSpec `json:"spec,omitempty"`
|
||||||
Status ZitadelClusterStatus `json:"status,omitempty"`
|
Status ClusterStatus `json:"status,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ZitadelCluster) SetDefaults() {
|
// SetDefaults populates default values on the Cluster spec.
|
||||||
//(Haim ;^D ): No defaults yet
|
func (m *Cluster) SetDefaults() {
|
||||||
|
// (Haim ;^D): No defaults yet
|
||||||
}
|
}
|
||||||
|
|
||||||
//+kubebuilder:object:root=true
|
//+kubebuilder:object:root=true
|
||||||
|
|
||||||
// ZitadelClusterList contains a list of ZitadelCluster
|
// ClusterList contains a list of Cluster.
|
||||||
type ZitadelClusterList struct {
|
type ClusterList struct {
|
||||||
metav1.TypeMeta `json:",inline"`
|
metav1.TypeMeta `json:",inline"`
|
||||||
metav1.ListMeta `json:"metadata,omitempty"`
|
metav1.ListMeta `json:"metadata,omitempty"`
|
||||||
Items []ZitadelCluster `json:"items"`
|
Items []Cluster `json:"items"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
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
|
// Package v1alpha1 contains API Schema definitions for the zitadel v1alpha1 API group
|
||||||
// +kubebuilder:object:generate=true
|
// +kubebuilder:object:generate=true
|
||||||
// +groupName=zitadel.topmanage.com
|
// +groupName=zitadel.github.com
|
||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -26,7 +26,7 @@ import (
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
// GroupVersion is group version used to register these objects
|
// 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 is used to add go types to the GroupVersionKind scheme
|
||||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
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,
|
func (r *RefResolver) Instance(ctx context.Context, ref *InstanceRef,
|
||||||
namespace string) (*ZitadelCluster, error) {
|
namespace string) (*Instance, error) {
|
||||||
if ref.Kind != "" && ref.Kind != "ZitadelCluster" {
|
if ref.Kind != "" && ref.Kind != "Instance" {
|
||||||
return nil, fmt.Errorf("Unsupported reference kind: '%s'", ref.Kind)
|
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
|
key.Namespace = ref.Namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
var zitadel ZitadelCluster
|
var zitadel Instance
|
||||||
if err := r.client.Get(ctx, key, &zitadel); err != nil {
|
if err := r.client.Get(ctx, key, &zitadel); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &zitadel, nil
|
return &zitadel, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RefResolver) OIDCAppRef(ctx context.Context, ref *OIDCAppRef,
|
func (r *RefResolver) Cluster(ctx context.Context, ref *ClusterRef,
|
||||||
namespace string) (*OIDCApp, error) {
|
namespace string) (*Cluster, error) {
|
||||||
if ref.Kind != "" && ref.Kind != "OIDCApp" {
|
if ref.Kind != "" && ref.Kind != "Cluster" {
|
||||||
return nil, fmt.Errorf("Unsupported reference kind: '%s'", ref.Kind)
|
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
|
key.Namespace = ref.Namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
var zitadel OIDCApp
|
var zitadel Cluster
|
||||||
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
|
|
||||||
if err := r.client.Get(ctx, key, &zitadel); err != nil {
|
if err := r.client.Get(ctx, key, &zitadel); err != nil {
|
||||||
return nil, err
|
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
|
|
||||||
13
build/flake.lock
generated
13
build/flake.lock
generated
@@ -18,18 +18,6 @@
|
|||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
|
||||||
"locked": {
|
|
||||||
"lastModified": 0,
|
|
||||||
"narHash": "sha256-7Fu7oazPoYCbDzb9k8D/DdbKrC3aU1zlnc39Y8jy/s8=",
|
|
||||||
"path": "/nix/store/m4wcdchjxw2fdyzjp8i6irpc613pchkr-source",
|
|
||||||
"type": "path"
|
|
||||||
},
|
|
||||||
"original": {
|
|
||||||
"id": "nixpkgs",
|
|
||||||
"type": "indirect"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1743448293,
|
"lastModified": 1743448293,
|
||||||
@@ -48,7 +36,6 @@
|
|||||||
"root": {
|
"root": {
|
||||||
"inputs": {
|
"inputs": {
|
||||||
"flake-utils": "flake-utils",
|
"flake-utils": "flake-utils",
|
||||||
"nixpkgs": "nixpkgs",
|
|
||||||
"nixpkgs-unstable": "nixpkgs-unstable"
|
"nixpkgs-unstable": "nixpkgs-unstable"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -6,17 +6,16 @@
|
|||||||
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
|
nixpkgs-unstable.url = "nixpkgs/nixos-unstable";
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs = { self, nixpkgs, nixpkgs-unstable, flake-utils }:
|
outputs = { self, nixpkgs-unstable, flake-utils }:
|
||||||
flake-utils.lib.eachDefaultSystem (system:
|
flake-utils.lib.eachDefaultSystem (system:
|
||||||
let
|
let
|
||||||
unstable = nixpkgs-unstable.legacyPackages.${system};
|
pkgs = nixpkgs-unstable.legacyPackages.${system};
|
||||||
pkgs = nixpkgs.legacyPackages.${system};
|
package = pkgs.buildGoModule {
|
||||||
package = unstable.buildGoModule {
|
|
||||||
pname = "zitadel-k8s-operator";
|
pname = "zitadel-k8s-operator";
|
||||||
version = "0.0.0";
|
version = "0.0.0";
|
||||||
src = ../src;
|
src = ../.;
|
||||||
doCheck = false;
|
doCheck = false;
|
||||||
vendorHash = "sha256-HEXIHASdDC7chG9uF56f6pvZPVbxYs/fWFytDz6CAf4=";
|
vendorHash = "sha256-HEXIHASdDC7chG9uF56frpvZPVbxYs/fWFytDz6CAf4=";
|
||||||
installPhase = ''
|
installPhase = ''
|
||||||
runHook preInstall
|
runHook preInstall
|
||||||
|
|
||||||
@@ -45,8 +44,7 @@
|
|||||||
in with pkgs; {
|
in with pkgs; {
|
||||||
packages.default = package;
|
packages.default = package;
|
||||||
packages.dockerImage = dockerPackage;
|
packages.dockerImage = dockerPackage;
|
||||||
devShells.default = mkShell {
|
devShells.default =
|
||||||
buildInputs = [ nixfmt unstable.gopls operator-sdk unstable.go ];
|
mkShell { buildInputs = [ nixfmt gopls operator-sdk go ]; };
|
||||||
};
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
// "time"
|
||||||
|
|
||||||
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
|
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
|
||||||
// to ensure that exec-entrypoint and run can make use of them.
|
// to ensure that exec-entrypoint and run can make use of them.
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
@@ -32,14 +34,17 @@ import (
|
|||||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
||||||
server "sigs.k8s.io/controller-runtime/pkg/metrics/server"
|
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"
|
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
|
//+kubebuilder:scaffold:imports
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -51,6 +56,7 @@ var (
|
|||||||
func init() {
|
func init() {
|
||||||
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
|
||||||
utilruntime.Must(cloudnativepgv1.AddToScheme(scheme))
|
utilruntime.Must(cloudnativepgv1.AddToScheme(scheme))
|
||||||
|
utilruntime.Must(zitadelresourcesv1alpha1.AddToScheme(scheme))
|
||||||
utilruntime.Must(zitadelv1alpha1.AddToScheme(scheme))
|
utilruntime.Must(zitadelv1alpha1.AddToScheme(scheme))
|
||||||
//+kubebuilder:scaffold:scheme
|
//+kubebuilder:scaffold:scheme
|
||||||
}
|
}
|
||||||
@@ -77,7 +83,7 @@ func main() {
|
|||||||
Metrics: server.Options{BindAddress: metricsAddr},
|
Metrics: server.Options{BindAddress: metricsAddr},
|
||||||
HealthProbeBindAddress: probeAddr,
|
HealthProbeBindAddress: probeAddr,
|
||||||
LeaderElection: enableLeaderElection,
|
LeaderElection: enableLeaderElection,
|
||||||
LeaderElectionID: "88a0b43c.topmanage.com",
|
LeaderElectionID: "88a0b43c.github.com",
|
||||||
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
|
// LeaderElectionReleaseOnCancel defines if the leader should step down voluntarily
|
||||||
// when the Manager ends. This requires the binary to immediately end when the
|
// when the Manager ends. This requires the binary to immediately end when the
|
||||||
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
|
// Manager is stopped, otherwise, this setting is unsafe. Setting this significantly
|
||||||
@@ -103,7 +109,7 @@ func main() {
|
|||||||
refResolver := zitadelv1alpha1.NewRefResolver(client)
|
refResolver := zitadelv1alpha1.NewRefResolver(client)
|
||||||
conditionReady := conditions.NewReady()
|
conditionReady := conditions.NewReady()
|
||||||
requeueZitadel := 5 * time.Minute
|
requeueZitadel := 5 * time.Minute
|
||||||
if err = (&controller.ZitadelClusterReconciler{
|
if err = (&controller.ClusterReconciler{
|
||||||
Client: client,
|
Client: client,
|
||||||
Scheme: scheme,
|
Scheme: scheme,
|
||||||
ConditionReady: conditionReady,
|
ConditionReady: conditionReady,
|
||||||
@@ -116,35 +122,41 @@ func main() {
|
|||||||
setupLog.Error(err, "unable to create controller", "controller", "ZitadelCluster")
|
setupLog.Error(err, "unable to create controller", "controller", "ZitadelCluster")
|
||||||
os.Exit(1)
|
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)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = controller.NewProjectReconciler(client, refResolver, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
// if err = controller.NewOrganizationReconciler(client, refResolver, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||||
setupLog.Error(err, "unable to create controller", "controller", "Project")
|
// setupLog.Error(err, "unable to create controller", "controller", "Organization")
|
||||||
os.Exit(1)
|
// 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")
|
// if err = controller.NewProjectReconciler(client, refResolver, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||||
os.Exit(1)
|
// setupLog.Error(err, "unable to create controller", "controller", "Project")
|
||||||
}
|
// 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")
|
// if err = controller.NewOIDCAppReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||||
os.Exit(1)
|
// setupLog.Error(err, "unable to create controller", "controller", "OIDCApp")
|
||||||
}
|
// 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")
|
// if err = controller.NewMachineUserReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||||
os.Exit(1)
|
// setupLog.Error(err, "unable to create controller", "controller", "MachineUser")
|
||||||
}
|
// 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")
|
// if err = controller.NewAPIAppReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||||
os.Exit(1)
|
// setupLog.Error(err, "unable to create controller", "controller", "APIApp")
|
||||||
}
|
// 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")
|
// if err = controller.NewActionReconciler(client, refResolver, builder, conditionReady, requeueZitadel).SetupWithManager(mgr); err != nil {
|
||||||
os.Exit(1)
|
// 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
|
//+kubebuilder:scaffold:builder
|
||||||
|
|
||||||
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
|
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
|
||||||
@@ -4,20 +4,30 @@ kind: CustomResourceDefinition
|
|||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.17.3
|
controller-gen.kubebuilder.io/version: v0.17.3
|
||||||
name: zitadelclusters.zitadel.topmanage.com
|
name: clusters.zitadel.github.com
|
||||||
spec:
|
spec:
|
||||||
group: zitadel.topmanage.com
|
group: zitadel.github.com
|
||||||
names:
|
names:
|
||||||
kind: ZitadelCluster
|
kind: Cluster
|
||||||
listKind: ZitadelClusterList
|
listKind: ClusterList
|
||||||
plural: zitadelclusters
|
plural: clusters
|
||||||
singular: zitadelcluster
|
singular: cluster
|
||||||
scope: Namespaced
|
scope: Namespaced
|
||||||
versions:
|
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:
|
schema:
|
||||||
openAPIV3Schema:
|
openAPIV3Schema:
|
||||||
description: ZitadelCluster is the Schema for the zitadelclusters API
|
description: Cluster is the Schema for the clusters API.
|
||||||
properties:
|
properties:
|
||||||
apiVersion:
|
apiVersion:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -37,40 +47,23 @@ spec:
|
|||||||
metadata:
|
metadata:
|
||||||
type: object
|
type: object
|
||||||
spec:
|
spec:
|
||||||
description: ZitadelClusterSpec defines the desired state of ZitadelCluster
|
description: ClusterSpec defines the desired state of Cluster.
|
||||||
properties:
|
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:
|
externalPort:
|
||||||
default: 443
|
default: 443
|
||||||
|
description: ExternalPort is the port exposed externally.
|
||||||
format: int64
|
format: int64
|
||||||
type: integer
|
type: integer
|
||||||
externalSecure:
|
externalSecure:
|
||||||
default: true
|
default: true
|
||||||
|
description: ExternalSecure indicates whether TLS is used on the external
|
||||||
|
endpoint.
|
||||||
type: boolean
|
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:
|
host:
|
||||||
|
description: Host is the external hostname used to reach Zitadel.
|
||||||
type: string
|
type: string
|
||||||
image:
|
image:
|
||||||
|
description: Image is the Zitadel container image to deploy.
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
@@ -83,9 +76,12 @@ spec:
|
|||||||
podAnnotations:
|
podAnnotations:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: string
|
type: string
|
||||||
description: PodAnnotations to add to the Pods metadata.
|
description: PodAnnotations are extra annotations added to each Zitadel
|
||||||
|
Pod.
|
||||||
type: object
|
type: object
|
||||||
postgresClusterRef:
|
postgresClusterRef:
|
||||||
|
description: PostgreSQLClusterRef references the backing PostgreSQL
|
||||||
|
cluster.
|
||||||
properties:
|
properties:
|
||||||
apiVersion:
|
apiVersion:
|
||||||
description: API version of the referent.
|
description: API version of the referent.
|
||||||
@@ -127,20 +123,14 @@ spec:
|
|||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
purpose:
|
|
||||||
enum:
|
|
||||||
- demo
|
|
||||||
- trial
|
|
||||||
- staging
|
|
||||||
- productive
|
|
||||||
- testing
|
|
||||||
type: string
|
|
||||||
replicas:
|
replicas:
|
||||||
default: 3
|
default: 3
|
||||||
|
description: Replicas is the desired number of Zitadel pods.
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
resources:
|
resources:
|
||||||
description: ResourceRequirements describes the compute resource requirements.
|
description: Resources defines compute resource requests and limits
|
||||||
|
for the Zitadel pods.
|
||||||
properties:
|
properties:
|
||||||
claims:
|
claims:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -198,96 +188,25 @@ spec:
|
|||||||
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||||
type: object
|
type: object
|
||||||
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:
|
serviceAnnotations:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: string
|
type: string
|
||||||
description: ServiceAnnotations to add to the service metadata.
|
description: ServiceAnnotations are extra annotations added to the
|
||||||
type: object
|
Zitadel Service.
|
||||||
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
|
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- domainSettings
|
|
||||||
- externalPort
|
- externalPort
|
||||||
- externalSecure
|
- externalSecure
|
||||||
- firstOrgName
|
|
||||||
- host
|
- host
|
||||||
- image
|
- image
|
||||||
- postgresClusterRef
|
- postgresClusterRef
|
||||||
- purpose
|
|
||||||
- resources
|
- resources
|
||||||
- rootTLSSecret
|
|
||||||
- smtpConfig
|
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
description: ZitadelClusterStatus defines the observed state of ZitadelCluster
|
description: ClusterStatus defines the observed state of Cluster.
|
||||||
properties:
|
properties:
|
||||||
conditions:
|
conditions:
|
||||||
description: |-
|
description: Conditions store the status conditions of the Cluster.
|
||||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
|
||||||
Important: Run "make" to regenerate code after modifying this file
|
|
||||||
items:
|
items:
|
||||||
description: Condition contains details for one aspect of the current
|
description: Condition contains details for one aspect of the current
|
||||||
state of this API Resource.
|
state of this API Resource.
|
||||||
@@ -343,19 +262,11 @@ spec:
|
|||||||
- type
|
- type
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
defaultInstanceId:
|
|
||||||
default: ""
|
|
||||||
type: string
|
|
||||||
replicas:
|
replicas:
|
||||||
default: 3
|
default: 3
|
||||||
|
description: Replicas is the current number of running Zitadel pods.
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
smtpProviderId:
|
|
||||||
default: ""
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- defaultInstanceId
|
|
||||||
- smtpProviderId
|
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
@@ -4,20 +4,36 @@ kind: CustomResourceDefinition
|
|||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.17.3
|
controller-gen.kubebuilder.io/version: v0.17.3
|
||||||
name: machineusers.zitadel.topmanage.com
|
name: instances.zitadel.github.com
|
||||||
spec:
|
spec:
|
||||||
group: zitadel.topmanage.com
|
group: zitadel.github.com
|
||||||
names:
|
names:
|
||||||
kind: MachineUser
|
kind: Instance
|
||||||
listKind: MachineUserList
|
listKind: InstanceList
|
||||||
plural: machineusers
|
plural: instances
|
||||||
singular: machineuser
|
singular: instance
|
||||||
scope: Namespaced
|
scope: Namespaced
|
||||||
versions:
|
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:
|
schema:
|
||||||
openAPIV3Schema:
|
openAPIV3Schema:
|
||||||
description: MachineUser is the Schema for the machineusers API
|
description: Instance is the Schema for the instances API.
|
||||||
properties:
|
properties:
|
||||||
apiVersion:
|
apiVersion:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -37,17 +53,13 @@ spec:
|
|||||||
metadata:
|
metadata:
|
||||||
type: object
|
type: object
|
||||||
spec:
|
spec:
|
||||||
description: MachineUserSpec defines the desired state of MachineUser
|
description: |-
|
||||||
|
InstanceSpec defines the desired state of Instance.
|
||||||
|
Fields map directly to POST /instances/_create (CreateInstance) in the Zitadel System API.
|
||||||
properties:
|
properties:
|
||||||
accessTokenType:
|
clusterRef:
|
||||||
enum:
|
description: ClusterRef references the Cluster this instance will
|
||||||
- ACCESS_TOKEN_TYPE_BEARER
|
be provisioned on.
|
||||||
- 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
|
|
||||||
properties:
|
properties:
|
||||||
apiVersion:
|
apiVersion:
|
||||||
description: API version of the referent.
|
description: API version of the referent.
|
||||||
@@ -89,70 +101,120 @@ spec:
|
|||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
userGrants:
|
customDomain:
|
||||||
items:
|
type: string
|
||||||
properties:
|
defaultLanguage:
|
||||||
projectRef:
|
default: en
|
||||||
properties:
|
description: DefaultLanguage is the BCP-47 language tag used as the
|
||||||
apiVersion:
|
instance default (e.g. "en").
|
||||||
description: API version of the referent.
|
type: string
|
||||||
type: string
|
instanceName:
|
||||||
fieldPath:
|
description: InstanceName is the display name of the Zitadel instance.
|
||||||
description: |-
|
type: string
|
||||||
If referring to a piece of an object instead of an entire object, this string
|
loginUI:
|
||||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
default:
|
||||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
image:
|
||||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
name: ghcr.io/zitadel/zitadel-login
|
||||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
resources: {}
|
||||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
properties:
|
||||||
referencing a part of an object.
|
image:
|
||||||
type: string
|
properties:
|
||||||
kind:
|
name:
|
||||||
description: |-
|
default: ghcr.io/zitadel/zitadel-login
|
||||||
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: string
|
||||||
type: array
|
tag:
|
||||||
required:
|
description: if empty it uses the same tag as zitadel cluster
|
||||||
- projectRef
|
type: string
|
||||||
type: object
|
required:
|
||||||
type: array
|
- 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:
|
||||||
|
name:
|
||||||
|
description: |-
|
||||||
|
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
|
||||||
|
request:
|
||||||
|
description: |-
|
||||||
|
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
|
||||||
|
required:
|
||||||
|
- 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:
|
||||||
|
- 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:
|
required:
|
||||||
- accessTokenType
|
- clusterRef
|
||||||
- organizationRef
|
- customDomain
|
||||||
|
- instanceName
|
||||||
|
- loginUI
|
||||||
|
- org
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
description: MachineUserStatus defines the observed state of MachineUser
|
description: InstanceStatus defines the observed state of Instance.
|
||||||
properties:
|
properties:
|
||||||
conditions:
|
conditions:
|
||||||
description: |-
|
description: Conditions store the status conditions of the Instance.
|
||||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
|
||||||
Important: Run "make" to regenerate code after modifying this file
|
|
||||||
items:
|
items:
|
||||||
description: Condition contains details for one aspect of the current
|
description: Condition contains details for one aspect of the current
|
||||||
state of this API Resource.
|
state of this API Resource.
|
||||||
@@ -208,19 +270,10 @@ spec:
|
|||||||
- type
|
- type
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
keyId:
|
instanceId:
|
||||||
default: ""
|
description: InstanceId is the instance ID returned by Zitadel after
|
||||||
|
successful provisioning.
|
||||||
type: string
|
type: string
|
||||||
patId:
|
|
||||||
default: ""
|
|
||||||
type: string
|
|
||||||
userId:
|
|
||||||
default: ""
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- keyId
|
|
||||||
- patId
|
|
||||||
- userId
|
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
@@ -2,14 +2,8 @@
|
|||||||
# since it depends on service name and namespace that are out of this kustomize package.
|
# since it depends on service name and namespace that are out of this kustomize package.
|
||||||
# It should be run by config/default
|
# It should be run by config/default
|
||||||
resources:
|
resources:
|
||||||
- bases/zitadel.topmanage.com_zitadelclusters.yaml
|
- bases/zitadel.github.com_clusters.yaml
|
||||||
- bases/zitadel.topmanage.com_organizations.yaml
|
- bases/zitadel.github.com_instances.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
|
|
||||||
#+kubebuilder:scaffold:crdkustomizeresource
|
#+kubebuilder:scaffold:crdkustomizeresource
|
||||||
|
|
||||||
patchesStrategicMerge:
|
patchesStrategicMerge:
|
||||||
@@ -35,6 +29,7 @@ patchesStrategicMerge:
|
|||||||
#- patches/cainjection_in_apiapps.yaml
|
#- patches/cainjection_in_apiapps.yaml
|
||||||
#- patches/cainjection_in_actions.yaml
|
#- patches/cainjection_in_actions.yaml
|
||||||
#- patches/cainjection_in_flows.yaml
|
#- patches/cainjection_in_flows.yaml
|
||||||
|
#- path: patches/cainjection_in_connections.yaml
|
||||||
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
|
#+kubebuilder:scaffold:crdkustomizecainjectionpatch
|
||||||
|
|
||||||
# the following config is for teaching kustomize how to do kustomization for CRDs.
|
# the following config is for teaching kustomize how to do kustomization for CRDs.
|
||||||
@@ -12,9 +12,9 @@ metadata:
|
|||||||
name: zitadelcluster-editor-role
|
name: zitadelcluster-editor-role
|
||||||
rules:
|
rules:
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- zitadel.topmanage.com
|
- zitadel.github.com
|
||||||
resources:
|
resources:
|
||||||
- zitadelclusters
|
- clusters
|
||||||
verbs:
|
verbs:
|
||||||
- create
|
- create
|
||||||
- delete
|
- delete
|
||||||
@@ -24,8 +24,8 @@ rules:
|
|||||||
- update
|
- update
|
||||||
- watch
|
- watch
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- zitadel.topmanage.com
|
- zitadel.github.com
|
||||||
resources:
|
resources:
|
||||||
- zitadelclusters/status
|
- clusters/status
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
@@ -16,3 +16,8 @@ resources:
|
|||||||
- auth_proxy_role.yaml
|
- auth_proxy_role.yaml
|
||||||
- auth_proxy_role_binding.yaml
|
- auth_proxy_role_binding.yaml
|
||||||
- auth_proxy_client_clusterrole.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
|
- list
|
||||||
- patch
|
- patch
|
||||||
- watch
|
- 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:
|
- apiGroups:
|
||||||
- zitadel.topmanage.com
|
- zitadel.topmanage.com
|
||||||
resources:
|
resources:
|
||||||
- actions
|
- instances
|
||||||
- apiapps
|
|
||||||
- flows
|
|
||||||
- machineusers
|
|
||||||
- oidcapps
|
|
||||||
- organizations
|
|
||||||
- projects
|
|
||||||
- zitadelclusters
|
|
||||||
verbs:
|
verbs:
|
||||||
- create
|
- create
|
||||||
- delete
|
- delete
|
||||||
@@ -149,27 +180,13 @@ rules:
|
|||||||
- apiGroups:
|
- apiGroups:
|
||||||
- zitadel.topmanage.com
|
- zitadel.topmanage.com
|
||||||
resources:
|
resources:
|
||||||
- actions/finalizers
|
- instances/finalizers
|
||||||
- apiapps/finalizers
|
|
||||||
- flows/finalizers
|
|
||||||
- machineusers/finalizers
|
|
||||||
- oidcapps/finalizers
|
|
||||||
- organizations/finalizers
|
|
||||||
- projects/finalizers
|
|
||||||
- zitadelclusters/finalizers
|
|
||||||
verbs:
|
verbs:
|
||||||
- update
|
- update
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- zitadel.topmanage.com
|
- zitadel.topmanage.com
|
||||||
resources:
|
resources:
|
||||||
- actions/status
|
- instances/status
|
||||||
- apiapps/status
|
|
||||||
- flows/status
|
|
||||||
- machineusers/status
|
|
||||||
- oidcapps/status
|
|
||||||
- organizations/status
|
|
||||||
- projects/status
|
|
||||||
- zitadelclusters/status
|
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
- patch
|
- 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
|
||||||
@@ -1,21 +1,16 @@
|
|||||||
module bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src
|
module gitea.corredorconect.com/software-engineering/zitadel-k8s-operator
|
||||||
|
|
||||||
go 1.24.1
|
go 1.25.8
|
||||||
|
|
||||||
require (
|
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/cloudnative-pg/cloudnative-pg v1.25.1
|
||||||
github.com/gorilla/schema v1.4.1
|
|
||||||
github.com/hashicorp/go-multierror v1.1.1
|
github.com/hashicorp/go-multierror v1.1.1
|
||||||
github.com/onsi/ginkgo/v2 v2.23.3
|
github.com/onsi/ginkgo/v2 v2.23.3
|
||||||
github.com/onsi/gomega v1.36.3
|
github.com/onsi/gomega v1.36.3
|
||||||
github.com/sethvargo/go-password v0.3.1
|
github.com/sethvargo/go-password v0.3.1
|
||||||
github.com/zitadel/oidc v1.13.5
|
github.com/zitadel/zitadel-go/v3 v3.27.0
|
||||||
github.com/zitadel/zitadel-go/v3 v3.5.0
|
google.golang.org/grpc v1.79.3
|
||||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394
|
|
||||||
golang.org/x/oauth2 v0.28.0
|
|
||||||
google.golang.org/grpc v1.71.0
|
|
||||||
google.golang.org/protobuf v1.36.6
|
|
||||||
gopkg.in/square/go-jose.v2 v2.6.0
|
|
||||||
k8s.io/api v0.32.3
|
k8s.io/api v0.32.3
|
||||||
k8s.io/apimachinery v0.32.3
|
k8s.io/apimachinery v0.32.3
|
||||||
k8s.io/client-go v0.32.3
|
k8s.io/client-go v0.32.3
|
||||||
@@ -29,12 +24,12 @@ require (
|
|||||||
github.com/cloudnative-pg/machinery 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/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
||||||
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
|
github.com/emicklei/go-restful/v3 v3.12.1 // indirect
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.2.1 // indirect
|
github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect
|
||||||
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
|
github.com/evanphx/json-patch/v5 v5.9.11 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||||
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
github.com/fxamacker/cbor/v2 v2.7.0 // indirect
|
||||||
github.com/go-jose/go-jose/v4 v4.0.5 // indirect
|
github.com/go-jose/go-jose/v4 v4.1.3 // indirect
|
||||||
github.com/go-logr/logr v1.4.2 // indirect
|
github.com/go-logr/logr v1.4.3 // indirect
|
||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/go-logr/zapr v1.3.0 // indirect
|
github.com/go-logr/zapr v1.3.0 // indirect
|
||||||
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
github.com/go-openapi/jsonpointer v0.21.0 // indirect
|
||||||
@@ -51,7 +46,7 @@ require (
|
|||||||
github.com/google/uuid v1.6.0 // indirect
|
github.com/google/uuid v1.6.0 // indirect
|
||||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||||
github.com/gorilla/websocket v1.5.0 // indirect
|
github.com/gorilla/websocket v1.5.0 // indirect
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect
|
github.com/grpc-ecosystem/grpc-gateway/v2 v2.28.0 // indirect
|
||||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||||
github.com/josharian/intern v1.0.0 // indirect
|
github.com/josharian/intern v1.0.0 // indirect
|
||||||
github.com/json-iterator/go v1.1.12 // indirect
|
github.com/json-iterator/go v1.1.12 // indirect
|
||||||
@@ -71,29 +66,30 @@ require (
|
|||||||
github.com/prometheus/client_model v0.6.1 // indirect
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
github.com/prometheus/common v0.62.0 // indirect
|
github.com/prometheus/common v0.62.0 // indirect
|
||||||
github.com/prometheus/procfs v0.15.1 // indirect
|
github.com/prometheus/procfs v0.15.1 // indirect
|
||||||
github.com/sirupsen/logrus v1.9.3 // indirect
|
github.com/sirupsen/logrus v1.9.4 // indirect
|
||||||
github.com/spf13/pflag v1.0.6 // indirect
|
github.com/spf13/pflag v1.0.6 // indirect
|
||||||
github.com/x448/float16 v0.8.4 // indirect
|
github.com/x448/float16 v0.8.4 // indirect
|
||||||
github.com/zitadel/logging v0.6.1 // indirect
|
github.com/zitadel/logging v0.7.0 // indirect
|
||||||
github.com/zitadel/oidc/v3 v3.36.1 // indirect
|
github.com/zitadel/oidc/v3 v3.45.5 // indirect
|
||||||
github.com/zitadel/schema v1.3.0 // indirect
|
github.com/zitadel/schema v1.3.2 // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
|
||||||
go.opentelemetry.io/otel v1.34.0 // indirect
|
go.opentelemetry.io/otel v1.40.0 // indirect
|
||||||
go.opentelemetry.io/otel/metric v1.34.0 // indirect
|
go.opentelemetry.io/otel/metric v1.40.0 // indirect
|
||||||
go.opentelemetry.io/otel/trace v1.34.0 // indirect
|
go.opentelemetry.io/otel/trace v1.40.0 // indirect
|
||||||
go.uber.org/multierr v1.11.0 // indirect
|
go.uber.org/multierr v1.11.0 // indirect
|
||||||
go.uber.org/zap v1.27.0 // indirect
|
go.uber.org/zap v1.27.0 // indirect
|
||||||
golang.org/x/crypto v0.36.0 // indirect
|
golang.org/x/net v0.49.0 // indirect
|
||||||
golang.org/x/net v0.37.0 // indirect
|
golang.org/x/oauth2 v0.35.0 // indirect
|
||||||
golang.org/x/sync v0.12.0 // indirect
|
golang.org/x/sync v0.19.0 // indirect
|
||||||
golang.org/x/sys v0.31.0 // indirect
|
golang.org/x/sys v0.40.0 // indirect
|
||||||
golang.org/x/term v0.30.0 // indirect
|
golang.org/x/term v0.39.0 // indirect
|
||||||
golang.org/x/text v0.23.0 // indirect
|
golang.org/x/text v0.34.0 // indirect
|
||||||
golang.org/x/time v0.9.0 // indirect
|
golang.org/x/time v0.9.0 // indirect
|
||||||
golang.org/x/tools v0.31.0 // indirect
|
golang.org/x/tools v0.41.0 // indirect
|
||||||
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422 // indirect
|
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 // indirect
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f // 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.12.0 // indirect
|
gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect
|
||||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
|
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/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
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/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 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
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.10.0 h1:zU9WiOla1YA122oLM6i4EXvGW62DvKZVxIe6TYWexEs=
|
||||||
github.com/bmatcuk/doublestar/v4 v4.8.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
|
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 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
|
||||||
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
|
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=
|
github.com/cloudnative-pg/barman-cloud v0.1.0 h1:e/z52CehMBIh1LjZqNBJnncWJbS+1JYvRMBR8Js6Uiw=
|
||||||
@@ -18,8 +20,8 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
|
|||||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
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 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU=
|
||||||
github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc=
|
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.3.3 h1:MVQghNeW+LZcmXe7SY1V36Z+WFMDjpqGAGacLe2T0ds=
|
||||||
github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU=
|
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 h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
|
||||||
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
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 h1:/8HVnzMq13/3x9TPvjG08wUGqBTmZBsCWzjTM0wiaDU=
|
||||||
@@ -28,13 +30,13 @@ github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nos
|
|||||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
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 h1:iM5WgngdRBanHcxugY4JySA0nk1wZorNOpTgCMedv5E=
|
||||||
github.com/fxamacker/cbor/v2 v2.7.0/go.mod h1:pxXPTn3joSm21Gbwsv0w9OSA2y1HFR9qXEeXQVeNoDQ=
|
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.5 h1:Eg4myHZBjyvJmAFjFvWgrqDTXFyOzjj7YIm3L3mu6Ug=
|
||||||
github.com/go-chi/chi/v5 v5.2.1/go.mod h1:L2yAIGWB3H+phAw1NxKwWM+7eUH/lU8pOMm5hHcoops=
|
github.com/go-chi/chi/v5 v5.2.5/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0=
|
||||||
github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE=
|
github.com/go-jose/go-jose/v4 v4.1.3 h1:CVLmWDhDVRa6Mi/IgCgaopNosCaHz7zrMeF9MlZRkrs=
|
||||||
github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA=
|
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.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.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
|
||||||
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
|
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 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||||
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ=
|
||||||
@@ -65,14 +67,12 @@ github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/Z
|
|||||||
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
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/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 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
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 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
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.28.0 h1:HWRh5R2+9EifMyIHV7ZV+MIZqgz+PMpZ14Jynv3O2Zs=
|
||||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I=
|
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 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
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=
|
github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo=
|
||||||
@@ -133,49 +133,46 @@ 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/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 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc=
|
||||||
github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk=
|
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.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ=
|
||||||
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
|
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 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
|
||||||
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
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 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU=
|
||||||
github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs=
|
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.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w=
|
||||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g=
|
||||||
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=
|
||||||
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
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.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
|
||||||
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
|
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
|
||||||
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
|
||||||
github.com/thoas/go-funk v0.9.3 h1:7+nAEx3kn5ZJcnDm2Bh23N2yOtweO14bi//dvRtgLpw=
|
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/thoas/go-funk v0.9.3/go.mod h1:+IWnUfUmFO1+WVYQWQtIJHeRRdaIyyYglZN7xzUPe4Q=
|
||||||
github.com/x448/float16 v0.8.4 h1:qLwI1I70+NjRFUR3zs1JPUCgaCXSh3SW62uAKT1mSBM=
|
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/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.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||||
github.com/yuin/goldmark v1.2.1/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.7.0 h1:eugftwMM95Wgqwftsvj81isL0JK/hoScVqp/7iA2adQ=
|
||||||
github.com/zitadel/logging v0.6.1/go.mod h1:Y4CyAXHpl3Mig6JOszcV5Rqqsojj+3n7y2F591Mp/ow=
|
github.com/zitadel/logging v0.7.0/go.mod h1:9A6h9feBF/3u0IhA4uffdzSDY7mBaf7RE78H5sFMINQ=
|
||||||
github.com/zitadel/oidc v1.13.5 h1:7jhh68NGZitLqwLiVU9Dtwa4IraJPFF1vS+4UupO93U=
|
github.com/zitadel/oidc/v3 v3.45.5 h1:CubfcXQiqtysk+FZyIcvj1+1ayvdSV89v5xWu5asrDQ=
|
||||||
github.com/zitadel/oidc v1.13.5/go.mod h1:rHs1DhU3Sv3tnI6bQRVlFa3u0lCwtR7S21WHY+yXgPA=
|
github.com/zitadel/oidc/v3 v3.45.5/go.mod h1:MKHUazeiNX/jxRc6HD/Dv9qhL/wNuzrJAadBEGXiBeE=
|
||||||
github.com/zitadel/oidc/v3 v3.36.1 h1:1AT1NqKKEqAwx4GmKJZ9fYkWH2WIn/VKMfQ46nBtRf0=
|
github.com/zitadel/schema v1.3.2 h1:gfJvt7dOMfTmxzhscZ9KkapKo3Nei3B6cAxjav+lyjI=
|
||||||
github.com/zitadel/oidc/v3 v3.36.1/go.mod h1:dApGZLvWZTHRuxmcbQlW5d2XVjVYR3vGOdq536igmTs=
|
github.com/zitadel/schema v1.3.2/go.mod h1:IZmdfF9Wu62Zu6tJJTH3UsArevs3Y4smfJIj3L8fzxw=
|
||||||
github.com/zitadel/schema v1.3.0 h1:kQ9W9tvIwZICCKWcMvCEweXET1OcOyGEuFbHs4o5kg0=
|
github.com/zitadel/zitadel-go/v3 v3.27.0 h1:1BumImnIk3D9JYTq+IlVq793vZCXuMZuz1meWzeMQN4=
|
||||||
github.com/zitadel/schema v1.3.0/go.mod h1:NptN6mkBDFvERUCvZHlvWmmME+gmZ44xzwRXwhzsbtc=
|
github.com/zitadel/zitadel-go/v3 v3.27.0/go.mod h1:8UaWIIUR+c9jstT6bjoiknaxttxFZKNc7RYs32v03jw=
|
||||||
github.com/zitadel/zitadel-go/v3 v3.5.0 h1:8LnUiOCvwhgZxwBY15tk7Yzhv5vEJF+qiM3qWJGtxCI=
|
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
|
||||||
github.com/zitadel/zitadel-go/v3 v3.5.0/go.mod h1:YPfMqfpyOIuKdHNsZwWHAR/BWSIFOSIL41TyMnef/aU=
|
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
|
go.opentelemetry.io/otel v1.40.0 h1:oA5YeOcpRTXq6NN7frwmwFR0Cn3RhTVZvXsP4duvCms=
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
|
go.opentelemetry.io/otel v1.40.0/go.mod h1:IMb+uXZUKkMXdPddhwAHm6UfOwJyh4ct1ybIlV14J0g=
|
||||||
go.opentelemetry.io/otel v1.34.0 h1:zRLXxLCgL1WyKsPVrgbSdMN4c0FMkDAskSTQP+0hdUY=
|
go.opentelemetry.io/otel/metric v1.40.0 h1:rcZe317KPftE2rstWIBitCdVp89A2HqjkxR3c11+p9g=
|
||||||
go.opentelemetry.io/otel v1.34.0/go.mod h1:OWFPOQ+h4G8xpyjgqo4SxJYdDQ/qmRH+wivy7zzx9oI=
|
go.opentelemetry.io/otel/metric v1.40.0/go.mod h1:ib/crwQH7N3r5kfiBZQbwrTge743UDc7DTFVZrrXnqc=
|
||||||
go.opentelemetry.io/otel/metric v1.34.0 h1:+eTR3U0MyfWjRDhmFMxe2SsW64QrZ84AOhvqS7Y+PoQ=
|
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
|
||||||
go.opentelemetry.io/otel/metric v1.34.0/go.mod h1:CEDrp0fy2D0MvkXE+dPV7cMi8tWZwX3dmaIhwPOaqHE=
|
go.opentelemetry.io/otel/sdk v1.39.0/go.mod h1:vDojkC4/jsTJsE+kh+LXYQlbL8CgrEcwmt1ENZszdJE=
|
||||||
go.opentelemetry.io/otel/sdk v1.34.0 h1:95zS4k/2GOy069d321O8jWgYsW3MzVV+KuSPKp7Wr1A=
|
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
|
||||||
go.opentelemetry.io/otel/sdk v1.34.0/go.mod h1:0e/pNiaMAqaykJGKbi+tSjWfNNHMTxoC9qANsCzbyxU=
|
go.opentelemetry.io/otel/sdk/metric v1.39.0/go.mod h1:xq9HEVH7qeX69/JnwEfp6fVq5wosJsY1mt4lLfYdVew=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.34.0 h1:5CeK9ujjbFVL5c1PhLuStg1wxA7vQv7ce1EK0Gyvahk=
|
go.opentelemetry.io/otel/trace v1.40.0 h1:WA4etStDttCSYuhwvEa8OP8I5EWu24lkOzp+ZYblVjw=
|
||||||
go.opentelemetry.io/otel/sdk/metric v1.34.0/go.mod h1:jQ/r8Ze28zRKoNRdkjCZxfs6YvBTG1+YIqyFVFYec5w=
|
go.opentelemetry.io/otel/trace v1.40.0/go.mod h1:zeAhriXecNGP/s2SEG3+Y8X9ujcJOTqQ5RgdEJcawiA=
|
||||||
go.opentelemetry.io/otel/trace v1.34.0 h1:+ouXS2V8Rd4hp4580a8q23bg0azF2nI8cqLYnC8mh/k=
|
|
||||||
go.opentelemetry.io/otel/trace v1.34.0/go.mod h1:Svm7lSjQD7kG7KJ/MUHPVXSDGz2OX4h0M2jHBhmSfRE=
|
|
||||||
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
|
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/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 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||||
@@ -185,59 +182,56 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
|
|||||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
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-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
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.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
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-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-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.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.49.0 h1:eeHFmOGUTtaaPSGNmjBKpbng9MulQsJURQUAfUwY++o=
|
||||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
golang.org/x/net v0.49.0/go.mod h1:/ysNB2EvaqvesRkuLAyjI1ycPZlQHM3q01F02UY/MV8=
|
||||||
golang.org/x/oauth2 v0.28.0 h1:CrgCKl8PPAVtLnU3c+EDw6x11699EWlsDeWNWKdIOkc=
|
golang.org/x/oauth2 v0.35.0 h1:Mv2mzuHuZuY2+bkyWXIHMfhNdJAdwW3FuWeCPYN5GVQ=
|
||||||
golang.org/x/oauth2 v0.28.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8=
|
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-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-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.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.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||||
golang.org/x/sync v0.12.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
|
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-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-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-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.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
|
||||||
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
|
||||||
golang.org/x/term v0.30.0 h1:PQ39fJZ+mfadBm0y5WlL4vlM7Sx1Hgf13sMIY2+QS9Y=
|
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
|
||||||
golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g=
|
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
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.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
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 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
|
||||||
golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
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-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-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-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.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||||
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
|
golang.org/x/tools v0.41.0 h1:a9b8iMweWG+S0OBnlU36rzLp20z1Rp10w+IY2czHTQc=
|
||||||
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
|
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-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-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-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/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 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw=
|
||||||
gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY=
|
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=
|
gonum.org/v1/gonum v0.16.0 h1:5+ul4Swaf3ESvrOnidPp4GZbzf0mxVQpDCYUQE7OJfk=
|
||||||
google.golang.org/genproto/googleapis/api v0.0.0-20250106144421-5f5ef82da422/go.mod h1:b6h1vNKhxaSoEI+5jc3PJUCustfli/mRab7295pY7rw=
|
gonum.org/v1/gonum v0.16.0/go.mod h1:fef3am4MQ93R2HHpKnLk4/Tbh/s0+wqD5nfa6Pnwy4E=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f h1:OxYkA3wjPsZyBylwymxSHa7ViiW1Sml4ToBrncvFehI=
|
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57 h1:JLQynH/LBHfCTSbDWl+py8C+Rg/k1OVH3xfcaiANuF0=
|
||||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250115164207-1a7da9e5054f/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50=
|
google.golang.org/genproto/googleapis/api v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:kSJwQxqmFXeo79zOmbrALdflXQeAYcUbgS7PbpMknCY=
|
||||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57 h1:mWPCjDEyshlQYzBpMNHaEof6UX1PmHcaUODUywQ0uac=
|
||||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
google.golang.org/genproto/googleapis/rpc v0.0.0-20260209200024-4cfbd4190f57/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||||
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
|
google.golang.org/grpc v1.79.3 h1:sybAEdRIEtvcD68Gx7dmnwjZKlyfuc61Dyo9pGXXkKE=
|
||||||
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
|
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 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 h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||||
@@ -245,11 +239,8 @@ gopkg.in/evanphx/json-patch.v4 v4.12.0 h1:n6jtcsulIzXPJaxegRbvFNNrZDjbij7ny3gmSP
|
|||||||
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
gopkg.in/evanphx/json-patch.v4 v4.12.0/go.mod h1:p8EYWUEYMpynmqDbY58zCKCFZw8pRWMG4EsWvDvM72M=
|
||||||
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc=
|
||||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
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 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
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 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
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 h1:Hw7KqxRusq+6QSplE3NYG4MBxZw1BZnq4aP4cJVINls=
|
||||||
470
internal/controller/cluster_controller.go
Normal file
470
internal/controller/cluster_controller.go
Normal file
@@ -0,0 +1,470 @@
|
|||||||
|
/*
|
||||||
|
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"
|
||||||
|
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,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
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"
|
logf "sigs.k8s.io/controller-runtime/pkg/log"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/log/zap"
|
"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
|
//+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:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.17.3
|
controller-gen.kubebuilder.io/version: v0.17.3
|
||||||
name: zitadelclusters.zitadel.topmanage.com
|
name: clusters.zitadel.github.com
|
||||||
spec:
|
spec:
|
||||||
group: zitadel.topmanage.com
|
group: zitadel.github.com
|
||||||
names:
|
names:
|
||||||
kind: ZitadelCluster
|
kind: Cluster
|
||||||
listKind: ZitadelClusterList
|
listKind: ClusterList
|
||||||
plural: zitadelclusters
|
plural: clusters
|
||||||
singular: zitadelcluster
|
singular: cluster
|
||||||
scope: Namespaced
|
scope: Namespaced
|
||||||
versions:
|
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:
|
schema:
|
||||||
openAPIV3Schema:
|
openAPIV3Schema:
|
||||||
description: ZitadelCluster is the Schema for the zitadelclusters API
|
description: Cluster is the Schema for the clusters API.
|
||||||
properties:
|
properties:
|
||||||
apiVersion:
|
apiVersion:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -36,40 +46,23 @@ spec:
|
|||||||
metadata:
|
metadata:
|
||||||
type: object
|
type: object
|
||||||
spec:
|
spec:
|
||||||
description: ZitadelClusterSpec defines the desired state of ZitadelCluster
|
description: ClusterSpec defines the desired state of Cluster.
|
||||||
properties:
|
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:
|
externalPort:
|
||||||
default: 443
|
default: 443
|
||||||
|
description: ExternalPort is the port exposed externally.
|
||||||
format: int64
|
format: int64
|
||||||
type: integer
|
type: integer
|
||||||
externalSecure:
|
externalSecure:
|
||||||
default: true
|
default: true
|
||||||
|
description: ExternalSecure indicates whether TLS is used on the external
|
||||||
|
endpoint.
|
||||||
type: boolean
|
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:
|
host:
|
||||||
|
description: Host is the external hostname used to reach Zitadel.
|
||||||
type: string
|
type: string
|
||||||
image:
|
image:
|
||||||
|
description: Image is the Zitadel container image to deploy.
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
@@ -82,9 +75,12 @@ spec:
|
|||||||
podAnnotations:
|
podAnnotations:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: string
|
type: string
|
||||||
description: PodAnnotations to add to the Pods metadata.
|
description: PodAnnotations are extra annotations added to each Zitadel
|
||||||
|
Pod.
|
||||||
type: object
|
type: object
|
||||||
postgresClusterRef:
|
postgresClusterRef:
|
||||||
|
description: PostgreSQLClusterRef references the backing PostgreSQL
|
||||||
|
cluster.
|
||||||
properties:
|
properties:
|
||||||
apiVersion:
|
apiVersion:
|
||||||
description: API version of the referent.
|
description: API version of the referent.
|
||||||
@@ -126,20 +122,14 @@ spec:
|
|||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
purpose:
|
|
||||||
enum:
|
|
||||||
- demo
|
|
||||||
- trial
|
|
||||||
- staging
|
|
||||||
- productive
|
|
||||||
- testing
|
|
||||||
type: string
|
|
||||||
replicas:
|
replicas:
|
||||||
default: 3
|
default: 3
|
||||||
|
description: Replicas is the desired number of Zitadel pods.
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
resources:
|
resources:
|
||||||
description: ResourceRequirements describes the compute resource requirements.
|
description: Resources defines compute resource requests and limits
|
||||||
|
for the Zitadel pods.
|
||||||
properties:
|
properties:
|
||||||
claims:
|
claims:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -197,96 +187,25 @@ spec:
|
|||||||
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/
|
||||||
type: object
|
type: object
|
||||||
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:
|
serviceAnnotations:
|
||||||
additionalProperties:
|
additionalProperties:
|
||||||
type: string
|
type: string
|
||||||
description: ServiceAnnotations to add to the service metadata.
|
description: ServiceAnnotations are extra annotations added to the
|
||||||
type: object
|
Zitadel Service.
|
||||||
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
|
|
||||||
type: object
|
type: object
|
||||||
required:
|
required:
|
||||||
- domainSettings
|
|
||||||
- externalPort
|
- externalPort
|
||||||
- externalSecure
|
- externalSecure
|
||||||
- firstOrgName
|
|
||||||
- host
|
- host
|
||||||
- image
|
- image
|
||||||
- postgresClusterRef
|
- postgresClusterRef
|
||||||
- purpose
|
|
||||||
- resources
|
- resources
|
||||||
- rootTLSSecret
|
|
||||||
- smtpConfig
|
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
description: ZitadelClusterStatus defines the observed state of ZitadelCluster
|
description: ClusterStatus defines the observed state of Cluster.
|
||||||
properties:
|
properties:
|
||||||
conditions:
|
conditions:
|
||||||
description: |-
|
description: Conditions store the status conditions of the Cluster.
|
||||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
|
||||||
Important: Run "make" to regenerate code after modifying this file
|
|
||||||
items:
|
items:
|
||||||
description: Condition contains details for one aspect of the current
|
description: Condition contains details for one aspect of the current
|
||||||
state of this API Resource.
|
state of this API Resource.
|
||||||
@@ -342,19 +261,11 @@ spec:
|
|||||||
- type
|
- type
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
defaultInstanceId:
|
|
||||||
default: ""
|
|
||||||
type: string
|
|
||||||
replicas:
|
replicas:
|
||||||
default: 3
|
default: 3
|
||||||
|
description: Replicas is the current number of running Zitadel pods.
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
smtpProviderId:
|
|
||||||
default: ""
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- defaultInstanceId
|
|
||||||
- smtpProviderId
|
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
served: true
|
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:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.17.3
|
controller-gen.kubebuilder.io/version: v0.17.3
|
||||||
name: machineusers.zitadel.topmanage.com
|
name: instances.zitadel.github.com
|
||||||
spec:
|
spec:
|
||||||
group: zitadel.topmanage.com
|
group: zitadel.github.com
|
||||||
names:
|
names:
|
||||||
kind: MachineUser
|
kind: Instance
|
||||||
listKind: MachineUserList
|
listKind: InstanceList
|
||||||
plural: machineusers
|
plural: instances
|
||||||
singular: machineuser
|
singular: instance
|
||||||
scope: Namespaced
|
scope: Namespaced
|
||||||
versions:
|
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:
|
schema:
|
||||||
openAPIV3Schema:
|
openAPIV3Schema:
|
||||||
description: MachineUser is the Schema for the machineusers API
|
description: Instance is the Schema for the instances API.
|
||||||
properties:
|
properties:
|
||||||
apiVersion:
|
apiVersion:
|
||||||
description: |-
|
description: |-
|
||||||
@@ -36,17 +52,13 @@ spec:
|
|||||||
metadata:
|
metadata:
|
||||||
type: object
|
type: object
|
||||||
spec:
|
spec:
|
||||||
description: MachineUserSpec defines the desired state of MachineUser
|
description: |-
|
||||||
|
InstanceSpec defines the desired state of Instance.
|
||||||
|
Fields map directly to POST /instances/_create (CreateInstance) in the Zitadel System API.
|
||||||
properties:
|
properties:
|
||||||
accessTokenType:
|
clusterRef:
|
||||||
enum:
|
description: ClusterRef references the Cluster this instance will
|
||||||
- ACCESS_TOKEN_TYPE_BEARER
|
be provisioned on.
|
||||||
- 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
|
|
||||||
properties:
|
properties:
|
||||||
apiVersion:
|
apiVersion:
|
||||||
description: API version of the referent.
|
description: API version of the referent.
|
||||||
@@ -88,70 +100,120 @@ spec:
|
|||||||
type: string
|
type: string
|
||||||
type: object
|
type: object
|
||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
userGrants:
|
customDomain:
|
||||||
items:
|
type: string
|
||||||
properties:
|
defaultLanguage:
|
||||||
projectRef:
|
default: en
|
||||||
properties:
|
description: DefaultLanguage is the BCP-47 language tag used as the
|
||||||
apiVersion:
|
instance default (e.g. "en").
|
||||||
description: API version of the referent.
|
type: string
|
||||||
type: string
|
instanceName:
|
||||||
fieldPath:
|
description: InstanceName is the display name of the Zitadel instance.
|
||||||
description: |-
|
type: string
|
||||||
If referring to a piece of an object instead of an entire object, this string
|
loginUI:
|
||||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
default:
|
||||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
image:
|
||||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
name: ghcr.io/zitadel/zitadel-login
|
||||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
resources: {}
|
||||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
properties:
|
||||||
referencing a part of an object.
|
image:
|
||||||
type: string
|
properties:
|
||||||
kind:
|
name:
|
||||||
description: |-
|
default: ghcr.io/zitadel/zitadel-login
|
||||||
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: string
|
||||||
type: array
|
tag:
|
||||||
required:
|
description: if empty it uses the same tag as zitadel cluster
|
||||||
- projectRef
|
type: string
|
||||||
type: object
|
required:
|
||||||
type: array
|
- 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:
|
||||||
|
name:
|
||||||
|
description: |-
|
||||||
|
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
|
||||||
|
request:
|
||||||
|
description: |-
|
||||||
|
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
|
||||||
|
required:
|
||||||
|
- 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:
|
||||||
|
- 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:
|
required:
|
||||||
- accessTokenType
|
- clusterRef
|
||||||
- organizationRef
|
- customDomain
|
||||||
|
- instanceName
|
||||||
|
- loginUI
|
||||||
|
- org
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
description: MachineUserStatus defines the observed state of MachineUser
|
description: InstanceStatus defines the observed state of Instance.
|
||||||
properties:
|
properties:
|
||||||
conditions:
|
conditions:
|
||||||
description: |-
|
description: Conditions store the status conditions of the Instance.
|
||||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
|
||||||
Important: Run "make" to regenerate code after modifying this file
|
|
||||||
items:
|
items:
|
||||||
description: Condition contains details for one aspect of the current
|
description: Condition contains details for one aspect of the current
|
||||||
state of this API Resource.
|
state of this API Resource.
|
||||||
@@ -207,19 +269,10 @@ spec:
|
|||||||
- type
|
- type
|
||||||
type: object
|
type: object
|
||||||
type: array
|
type: array
|
||||||
keyId:
|
instanceId:
|
||||||
default: ""
|
description: InstanceId is the instance ID returned by Zitadel after
|
||||||
|
successful provisioning.
|
||||||
type: string
|
type: string
|
||||||
patId:
|
|
||||||
default: ""
|
|
||||||
type: string
|
|
||||||
userId:
|
|
||||||
default: ""
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- keyId
|
|
||||||
- patId
|
|
||||||
- userId
|
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
served: true
|
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
|
Create the name of the service account to use
|
||||||
*/}}
|
*/}}
|
||||||
{{- define "zitadel-k8s-operator.serviceAccountName" -}}
|
{{- define "zitadel-k8s-operator.serviceAccountName" -}}
|
||||||
{{- if .Values.serviceAccount.create }}
|
{{- $default := (include "zitadel-k8s-operator.fullname" .) }}
|
||||||
{{- default (include "zitadel-k8s-operator.fullname" .) .Values.serviceAccount.name }}
|
{{- with .Values.serviceAccount }}
|
||||||
|
{{- if .create }}
|
||||||
|
{{- default $default .name }}
|
||||||
{{- else }}
|
{{- else }}
|
||||||
{{- default "default" .Values.serviceAccount.name }}
|
{{- default "default" .name }}
|
||||||
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|||||||
@@ -79,7 +79,11 @@ spec:
|
|||||||
}}
|
}}
|
||||||
securityContext: {{- toYaml .Values.controllerManager.manager.containerSecurityContext
|
securityContext: {{- toYaml .Values.controllerManager.manager.containerSecurityContext
|
||||||
| nindent 10 }}
|
| nindent 10 }}
|
||||||
securityContext:
|
nodeSelector: {{- toYaml .Values.controllerManager.nodeSelector | nindent 8 }}
|
||||||
runAsNonRoot: true
|
securityContext: {{- toYaml .Values.controllerManager.podSecurityContext | nindent
|
||||||
serviceAccountName: {{ include "zitadel-k8s-operator.fullname" . }}-controller-manager
|
8 }}
|
||||||
|
serviceAccountName: {{ include "zitadel-k8s-operator.serviceAccountName" . }}
|
||||||
terminationGracePeriodSeconds: 10
|
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'
|
name: '{{ include "zitadel-k8s-operator.fullname" . }}-leader-election-role'
|
||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: '{{ include "zitadel-k8s-operator.fullname" . }}-controller-manager'
|
name: '{{ include "zitadel-k8s-operator.serviceAccountName" . }}'
|
||||||
namespace: '{{ .Release.Namespace }}'
|
namespace: '{{ .Release.Namespace }}'
|
||||||
@@ -128,17 +128,48 @@ rules:
|
|||||||
- list
|
- list
|
||||||
- patch
|
- patch
|
||||||
- watch
|
- 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:
|
- apiGroups:
|
||||||
- zitadel.topmanage.com
|
- zitadel.topmanage.com
|
||||||
resources:
|
resources:
|
||||||
- actions
|
- instances
|
||||||
- apiapps
|
|
||||||
- flows
|
|
||||||
- machineusers
|
|
||||||
- oidcapps
|
|
||||||
- organizations
|
|
||||||
- projects
|
|
||||||
- zitadelclusters
|
|
||||||
verbs:
|
verbs:
|
||||||
- create
|
- create
|
||||||
- delete
|
- delete
|
||||||
@@ -150,27 +181,13 @@ rules:
|
|||||||
- apiGroups:
|
- apiGroups:
|
||||||
- zitadel.topmanage.com
|
- zitadel.topmanage.com
|
||||||
resources:
|
resources:
|
||||||
- actions/finalizers
|
- instances/finalizers
|
||||||
- apiapps/finalizers
|
|
||||||
- flows/finalizers
|
|
||||||
- machineusers/finalizers
|
|
||||||
- oidcapps/finalizers
|
|
||||||
- organizations/finalizers
|
|
||||||
- projects/finalizers
|
|
||||||
- zitadelclusters/finalizers
|
|
||||||
verbs:
|
verbs:
|
||||||
- update
|
- update
|
||||||
- apiGroups:
|
- apiGroups:
|
||||||
- zitadel.topmanage.com
|
- zitadel.topmanage.com
|
||||||
resources:
|
resources:
|
||||||
- actions/status
|
- instances/status
|
||||||
- apiapps/status
|
|
||||||
- flows/status
|
|
||||||
- machineusers/status
|
|
||||||
- oidcapps/status
|
|
||||||
- organizations/status
|
|
||||||
- projects/status
|
|
||||||
- zitadelclusters/status
|
|
||||||
verbs:
|
verbs:
|
||||||
- get
|
- get
|
||||||
- patch
|
- patch
|
||||||
@@ -191,5 +208,5 @@ roleRef:
|
|||||||
name: '{{ include "zitadel-k8s-operator.fullname" . }}-manager-role'
|
name: '{{ include "zitadel-k8s-operator.fullname" . }}-manager-role'
|
||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: '{{ include "zitadel-k8s-operator.fullname" . }}-controller-manager'
|
name: '{{ include "zitadel-k8s-operator.serviceAccountName" . }}'
|
||||||
namespace: '{{ .Release.Namespace }}'
|
namespace: '{{ .Release.Namespace }}'
|
||||||
|
|||||||
@@ -12,6 +12,6 @@ spec:
|
|||||||
type: {{ .Values.metricsService.type }}
|
type: {{ .Values.metricsService.type }}
|
||||||
selector:
|
selector:
|
||||||
control-plane: controller-manager
|
control-plane: controller-manager
|
||||||
{{- include "zitadel-k8s-operator.selectorLabels" . | nindent 4 }}
|
{{- include "zitadel-k8s-operator.selectorLabels" . | nindent 4 }}
|
||||||
ports:
|
ports:
|
||||||
{{- .Values.metricsService.ports | toYaml | nindent 2 }}
|
{{- .Values.metricsService.ports | toYaml | nindent 2 }}
|
||||||
|
|||||||
@@ -36,5 +36,5 @@ roleRef:
|
|||||||
name: '{{ include "zitadel-k8s-operator.fullname" . }}-proxy-role'
|
name: '{{ include "zitadel-k8s-operator.fullname" . }}-proxy-role'
|
||||||
subjects:
|
subjects:
|
||||||
- kind: ServiceAccount
|
- kind: ServiceAccount
|
||||||
name: '{{ include "zitadel-k8s-operator.fullname" . }}-controller-manager'
|
name: '{{ include "zitadel-k8s-operator.serviceAccountName" . }}'
|
||||||
namespace: '{{ .Release.Namespace }}'
|
namespace: '{{ .Release.Namespace }}'
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
|
{{ if .Values.serviceAccount.create }}
|
||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ServiceAccount
|
kind: ServiceAccount
|
||||||
metadata:
|
metadata:
|
||||||
name: {{ include "zitadel-k8s-operator.fullname" . }}-controller-manager
|
name: {{ include "zitadel-k8s-operator.serviceAccountName" . }}
|
||||||
labels:
|
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 }}
|
{{- include "zitadel-k8s-operator.labels" . | nindent 4 }}
|
||||||
|
{{- with .Values.serviceAccount.annotations }}
|
||||||
annotations:
|
annotations:
|
||||||
{{- toYaml .Values.controllerManager.serviceAccount.annotations | nindent 4 }}
|
{{- toYaml . | nindent 4 }}
|
||||||
|
{{- end }}
|
||||||
|
automountServiceAccountToken: {{ .Values.serviceAccount.automount }}
|
||||||
|
{{- end }}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
controllerManager:
|
controllerManager:
|
||||||
kubeRbacProxy:
|
kubeRbacProxy:
|
||||||
args:
|
args:
|
||||||
@@ -11,7 +12,7 @@ controllerManager:
|
|||||||
drop:
|
drop:
|
||||||
- ALL
|
- ALL
|
||||||
image:
|
image:
|
||||||
repository: gcr.io/kubebuilder/kube-rbac-proxy
|
repository: registry.k8s.io/kubebuilder/kube-rbac-proxy
|
||||||
tag: v0.13.1
|
tag: v0.13.1
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
@@ -31,8 +32,7 @@ controllerManager:
|
|||||||
drop:
|
drop:
|
||||||
- ALL
|
- ALL
|
||||||
image:
|
image:
|
||||||
repository: controller
|
repository: gitea.corredorconect.com/software-engineering/zitadel-k8s-operator
|
||||||
tag: latest
|
|
||||||
resources:
|
resources:
|
||||||
limits:
|
limits:
|
||||||
cpu: 500m
|
cpu: 500m
|
||||||
@@ -40,9 +40,12 @@ controllerManager:
|
|||||||
requests:
|
requests:
|
||||||
cpu: 10m
|
cpu: 10m
|
||||||
memory: 64Mi
|
memory: 64Mi
|
||||||
|
nodeSelector: {}
|
||||||
|
podSecurityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
replicas: 1
|
replicas: 1
|
||||||
serviceAccount:
|
tolerations: []
|
||||||
annotations: {}
|
topologySpreadConstraints: []
|
||||||
kubernetesClusterDomain: cluster.local
|
kubernetesClusterDomain: cluster.local
|
||||||
metricsService:
|
metricsService:
|
||||||
ports:
|
ports:
|
||||||
@@ -51,3 +54,8 @@ metricsService:
|
|||||||
protocol: TCP
|
protocol: TCP
|
||||||
targetPort: https
|
targetPort: https
|
||||||
type: ClusterIP
|
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
|
package builder
|
||||||
|
|
||||||
import (
|
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"
|
"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"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ConfigMapOpts struct {
|
type ConfigMapOpts struct {
|
||||||
Zitadel *zitadelv1alpha1.ZitadelCluster
|
Zitadel *zitadelv1alpha1.Cluster
|
||||||
Key types.NamespacedName
|
Key types.NamespacedName
|
||||||
Data map[string]string
|
Data map[string]string
|
||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
40
pkg/builder/connection_builder.go
Normal file
40
pkg/builder/connection_builder.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
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,
|
||||||
|
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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||||
labels "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder/labels"
|
labels "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/labels"
|
||||||
metadata "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder/metadata"
|
metadata "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder/metadata"
|
||||||
configuration "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/configuration"
|
configuration "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/configuration"
|
||||||
deployment "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/deployment"
|
deployment "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/deployment"
|
||||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/masterkey"
|
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/masterkey"
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -18,7 +18,7 @@ import (
|
|||||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
"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
|
replicas := zitadel.Spec.Replicas
|
||||||
objMeta :=
|
objMeta :=
|
||||||
metadata.NewMetadataBuilder(key).
|
metadata.NewMetadataBuilder(key).
|
||||||
@@ -51,7 +51,7 @@ func (b *Builder) BuildDeployment(zitadel *zitadelv1alpha1.ZitadelCluster, key t
|
|||||||
return dep, nil
|
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 :=
|
objMeta :=
|
||||||
metadata.NewMetadataBuilder(client.ObjectKeyFromObject(zitadel)).
|
metadata.NewMetadataBuilder(client.ObjectKeyFromObject(zitadel)).
|
||||||
WithZitadel(zitadel).
|
WithZitadel(zitadel).
|
||||||
@@ -80,7 +80,7 @@ func (b *Builder) buildDepPodTemplate(zitadel *zitadelv1alpha1.ZitadelCluster, l
|
|||||||
nil
|
nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) buildDepContainers(zitadel *zitadelv1alpha1.ZitadelCluster) *[]corev1.Container {
|
func (b *Builder) buildDepContainers(zitadel *zitadelv1alpha1.Cluster) *[]corev1.Container {
|
||||||
readyProbeHandle := corev1.ProbeHandler{
|
readyProbeHandle := corev1.ProbeHandler{
|
||||||
HTTPGet: &corev1.HTTPGetAction{HTTPHeaders: []corev1.HTTPHeader{},
|
HTTPGet: &corev1.HTTPGetAction{HTTPHeaders: []corev1.HTTPHeader{},
|
||||||
Port: intstr.FromInt(deployment.ZitadelPort),
|
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}},
|
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",
|
// Name: "ZITADEL_DATABASE_COCKROACH_ADMIN_SSL_ROOTCERT",
|
||||||
// Value: "/certs/ca.crt",
|
// Value: "/certs/ca.crt",
|
||||||
@@ -3,9 +3,9 @@ package builder
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||||
configuration "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/configuration"
|
configuration "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/configuration"
|
||||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/masterkey"
|
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/masterkey"
|
||||||
batchv1 "k8s.io/api/batch/v1"
|
batchv1 "k8s.io/api/batch/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -13,10 +13,9 @@ import (
|
|||||||
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
|
"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)
|
backOffLimit := int32(5)
|
||||||
ttlAfterFinish := int32(100)
|
|
||||||
activeDeadlineSeconds := int64(1800)
|
activeDeadlineSeconds := int64(1800)
|
||||||
runAsNonRoot := true
|
runAsNonRoot := true
|
||||||
enableServiceLinks := false
|
enableServiceLinks := false
|
||||||
@@ -28,9 +27,8 @@ func (b *Builder) BuildInitJob(zitadel *zitadelv1alpha1.ZitadelCluster, key type
|
|||||||
Namespace: key.Namespace,
|
Namespace: key.Namespace,
|
||||||
},
|
},
|
||||||
Spec: batchv1.JobSpec{
|
Spec: batchv1.JobSpec{
|
||||||
BackoffLimit: &backOffLimit,
|
BackoffLimit: &backOffLimit,
|
||||||
ActiveDeadlineSeconds: &activeDeadlineSeconds,
|
ActiveDeadlineSeconds: &activeDeadlineSeconds,
|
||||||
TTLSecondsAfterFinished: &ttlAfterFinish,
|
|
||||||
Template: corev1.PodTemplateSpec{
|
Template: corev1.PodTemplateSpec{
|
||||||
Spec: corev1.PodSpec{
|
Spec: corev1.PodSpec{
|
||||||
RestartPolicy: corev1.RestartPolicyOnFailure,
|
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,
|
Image: zitadel.Spec.Image.Name + ":" + zitadel.Spec.Image.Tag,
|
||||||
Args: []string{
|
Args: []string{
|
||||||
"init",
|
"init",
|
||||||
|
"zitadel",
|
||||||
"--config", "/config/zitadel-config-yaml",
|
"--config", "/config/zitadel-config-yaml",
|
||||||
},
|
},
|
||||||
Env: []corev1.EnvVar{
|
Env: []corev1.EnvVar{
|
||||||
@@ -81,6 +80,15 @@ func (b *Builder) BuildInitJob(zitadel *zitadelv1alpha1.ZitadelCluster, key type
|
|||||||
// Name: "ZITADEL_DATABASE_COCKROACH_USER_SSL_KEY",
|
// Name: "ZITADEL_DATABASE_COCKROACH_USER_SSL_KEY",
|
||||||
// Value: "/certs/tls.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{
|
VolumeMounts: []corev1.VolumeMount{
|
||||||
{Name: "zitadel-config-yaml", MountPath: "/config"},
|
{Name: "zitadel-config-yaml", MountPath: "/config"},
|
||||||
@@ -98,7 +106,7 @@ func (b *Builder) BuildInitJob(zitadel *zitadelv1alpha1.ZitadelCluster, key type
|
|||||||
return initJob, nil
|
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)
|
backOffLimit := int32(5)
|
||||||
activeDeadlineSeconds := int64(1800)
|
activeDeadlineSeconds := int64(1800)
|
||||||
@@ -177,6 +185,16 @@ func (b *Builder) BuildSetupJob(zitadel *zitadelv1alpha1.ZitadelCluster, key typ
|
|||||||
// Name: "ZITADEL_DATABASE_COCKROACH_USER_SSL_KEY",
|
// Name: "ZITADEL_DATABASE_COCKROACH_USER_SSL_KEY",
|
||||||
// Value: "/certs/tls.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{
|
VolumeMounts: []corev1.VolumeMount{
|
||||||
{Name: "zitadel-config-yaml", MountPath: "/config"},
|
{Name: "zitadel-config-yaml", MountPath: "/config"},
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
package builder
|
package builder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||||
deployment "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/deployment"
|
deployment "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/deployment"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -10,6 +10,7 @@ const (
|
|||||||
instanceLabel = "app.kubernetes.io/instance"
|
instanceLabel = "app.kubernetes.io/instance"
|
||||||
deploymentPodName = "deployment.kubernetes.io/pod-name"
|
deploymentPodName = "deployment.kubernetes.io/pod-name"
|
||||||
appZitadel = "zitadel"
|
appZitadel = "zitadel"
|
||||||
|
appLoginUI = "zitadel-login-ui"
|
||||||
appExporter = "exporter"
|
appExporter = "exporter"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -33,12 +34,17 @@ func (b *LabelsBuilder) WithInstance(instance string) *LabelsBuilder {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *LabelsBuilder) WithZitadel(zitadel *zitadelv1alpha1.ZitadelCluster) *LabelsBuilder {
|
func (b *LabelsBuilder) WithZitadel(zitadel *zitadelv1alpha1.Cluster) *LabelsBuilder {
|
||||||
return b.WithApp(appZitadel).
|
return b.WithApp(appZitadel).
|
||||||
WithInstance(zitadel.Name)
|
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)
|
b.labels[deploymentPodName] = deployment.PodName(zitadel.ObjectMeta, podIndex)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
@@ -50,12 +56,17 @@ func (b *LabelsBuilder) WithLabels(labels map[string]string) *LabelsBuilder {
|
|||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *LabelsBuilder) WithZitadelSelectorLabels(zitadel *zitadelv1alpha1.ZitadelCluster) *LabelsBuilder {
|
func (b *LabelsBuilder) WithZitadelSelectorLabels(zitadel *zitadelv1alpha1.Cluster) *LabelsBuilder {
|
||||||
b = b.WithZitadel(zitadel)
|
b = b.WithZitadel(zitadel)
|
||||||
return b
|
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).
|
return b.WithApp(appExporter).
|
||||||
WithInstance(zitadel.Name)
|
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
|
package metadata
|
||||||
|
|
||||||
import (
|
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"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"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 {
|
if zitadel == nil {
|
||||||
return b
|
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
|
package builder
|
||||||
|
|
||||||
import (
|
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"
|
"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"
|
corev1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type SecretOpts struct {
|
type SecretOpts struct {
|
||||||
Zitadel *zitadelv1alpha1.ZitadelCluster
|
Zitadel *zitadelv1alpha1.Cluster
|
||||||
Key types.NamespacedName
|
Key types.NamespacedName
|
||||||
Data map[string][]byte
|
Data map[string][]byte
|
||||||
Labels map[string]string
|
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"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/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) {
|
func SetReadyHealthty(c Conditioner) {
|
||||||
@@ -51,8 +51,8 @@ func SetReadyFailed(c Conditioner) {
|
|||||||
SetReadyFailedWithMessage(c, "Failed")
|
SetReadyFailedWithMessage(c, "Failed")
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetReadyWithDeployment(c Conditioner, sts *appsv1.Deployment, instanceId string) {
|
func SetReadyWithDeployment(c Conditioner, sts *appsv1.Deployment) {
|
||||||
if sts.Status.Replicas == 0 || sts.Status.ReadyReplicas != sts.Status.Replicas || instanceId == "" {
|
if sts.Status.Replicas == 0 || sts.Status.ReadyReplicas != sts.Status.Replicas {
|
||||||
c.SetCondition(metav1.Condition{
|
c.SetCondition(metav1.Condition{
|
||||||
Type: zitadelv1alpha1.ConditionTypeReady,
|
Type: zitadelv1alpha1.ConditionTypeReady,
|
||||||
Status: metav1.ConditionFalse,
|
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"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||||
builder "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder"
|
builder "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder"
|
||||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/deployment"
|
"gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/deployment"
|
||||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/masterkey"
|
systemapiaccount "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/systemapi"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"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 := make(map[string]string)
|
||||||
config["zitadel-config-yaml"] =
|
config["zitadel-config-yaml"] =
|
||||||
fmt.Sprintf(`
|
fmt.Sprintf(`Database:
|
||||||
Database:
|
|
||||||
Postgres:
|
Postgres:
|
||||||
Host: %s
|
Host: %s
|
||||||
Port: 5432
|
Port: 5432
|
||||||
@@ -57,6 +56,8 @@ Projections:
|
|||||||
Customizations:
|
Customizations:
|
||||||
smtp_configs:
|
smtp_configs:
|
||||||
BulkLimit: 2000
|
BulkLimit: 2000
|
||||||
|
FirstInstance:
|
||||||
|
Skip: true
|
||||||
SystemAPIUsers:
|
SystemAPIUsers:
|
||||||
- %s:
|
- %s:
|
||||||
KeyData: %s
|
KeyData: %s
|
||||||
@@ -66,7 +67,7 @@ SystemAPIUsers:
|
|||||||
- "SYSTEM_OWNER"
|
- "SYSTEM_OWNER"
|
||||||
- "IAM_OWNER"
|
- "IAM_OWNER"
|
||||||
- "ORG_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{
|
opts := builder.ConfigMapOpts{
|
||||||
Zitadel: zitadel,
|
Zitadel: zitadel,
|
||||||
@@ -8,8 +8,8 @@ import (
|
|||||||
"encoding/pem"
|
"encoding/pem"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||||
builder "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder"
|
builder "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/builder"
|
||||||
"github.com/sethvargo/go-password/password"
|
"github.com/sethvargo/go-password/password"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"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,
|
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
|
var existingSecret corev1.Secret
|
||||||
if err := r.Get(ctx, key, &existingSecret); err == nil {
|
if err := r.Get(ctx, key, &existingSecret); err == nil {
|
||||||
return string(existingSecret.Data[secretKey]), 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,
|
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
|
var existingSecret corev1.Secret
|
||||||
if err := r.Get(ctx, key, &existingSecret); err == nil {
|
if err := r.Get(ctx, key, &existingSecret); err == nil {
|
||||||
return string(existingSecret.Data[secretKey]), nil
|
return string(existingSecret.Data[secretKey]), nil
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package zitadel
|
package system
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@@ -6,29 +6,29 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||||
condition "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/condition"
|
condition "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/condition"
|
||||||
health "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/health"
|
health "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/health"
|
||||||
zitadelClient "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/zitadel"
|
zitadelClient "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/zitadel"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
ctrl "sigs.k8s.io/controller-runtime"
|
ctrl "sigs.k8s.io/controller-runtime"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/log"
|
"sigs.k8s.io/controller-runtime/pkg/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ZitadelReconciler struct {
|
type SystemReconciler struct {
|
||||||
Client client.Client
|
Client client.Client
|
||||||
RefResolver *zitadelv1alpha1.RefResolver
|
RefResolver *zitadelv1alpha1.RefResolver
|
||||||
ConditionReady *condition.Ready
|
ConditionReady *condition.Ready
|
||||||
|
|
||||||
WrappedReconciler WrappedReconciler
|
WrappedReconciler WrappedSystemReconciler
|
||||||
Finalizer Finalizer
|
Finalizer Finalizer
|
||||||
RequeueInterval time.Duration
|
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 {
|
requeueInterval time.Duration) Reconciler {
|
||||||
return &ZitadelReconciler{
|
return &SystemReconciler{
|
||||||
Client: client,
|
Client: client,
|
||||||
RefResolver: zitadelv1alpha1.NewRefResolver(client),
|
RefResolver: zitadelv1alpha1.NewRefResolver(client),
|
||||||
ConditionReady: cr,
|
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 resource.IsBeingDeleted() {
|
||||||
if err := r.Finalizer.Finalize(ctx, resource); err != nil {
|
if err := r.Finalizer.Finalize(ctx, resource); err != nil {
|
||||||
return ctrl.Result{}, fmt.Errorf("error finalizing %s: %v", resource.GetName(), err)
|
return ctrl.Result{}, fmt.Errorf("error finalizing %s: %v", resource.GetName(), err)
|
||||||
}
|
}
|
||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
zitadelRef, err := resource.ZitadelClusterRef(ctx, r.RefResolver)
|
clusterRef, err := resource.ClusterRef(ctx, r.RefResolver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ctrl.Result{}, err
|
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 {
|
if err != nil {
|
||||||
var errBundle *multierror.Error
|
var errBundle *multierror.Error
|
||||||
errBundle = multierror.Append(errBundle, err)
|
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)
|
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
|
var errBundle *multierror.Error
|
||||||
errBundle = multierror.Append(errBundle, err)
|
errBundle = multierror.Append(errBundle, err)
|
||||||
|
|
||||||
err := r.WrappedReconciler.PatchStatus(ctx, r.ConditionReady.PatcherWithError(err))
|
err := r.WrappedReconciler.PatchStatus(ctx, r.ConditionReady.PatcherWithError(err))
|
||||||
errBundle = multierror.Append(errBundle, 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 {
|
if err != nil {
|
||||||
var errBundle *multierror.Error
|
var errBundle *multierror.Error
|
||||||
errBundle = multierror.Append(errBundle, err)
|
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))
|
err = r.WrappedReconciler.PatchStatus(ctx, r.ConditionReady.PatcherFailed(msg))
|
||||||
errBundle = multierror.Append(errBundle, err)
|
errBundle = multierror.Append(errBundle, err)
|
||||||
|
|
||||||
@@ -107,27 +107,27 @@ func (r *ZitadelReconciler) Reconcile(ctx context.Context, resource Resource) (c
|
|||||||
return r.requeueResult(ctx, resource)
|
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
|
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 {
|
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{RequeueAfter: r.RequeueInterval}, nil
|
||||||
}
|
}
|
||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func waitForZitadelCluster(ctx context.Context, client client.Client, resource Resource,
|
func waitForCluster(ctx context.Context, client client.Client, resource Resource,
|
||||||
zitadel *zitadelv1alpha1.ZitadelCluster) error {
|
system *zitadelv1alpha1.Cluster) error {
|
||||||
var zitadelErr *multierror.Error
|
var systemErr *multierror.Error
|
||||||
healthy, err := health.IsZitadelClusterHealthy(ctx, client, zitadel)
|
healthy, err := health.IsClusterHealthy(ctx, client, system)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
zitadelErr = multierror.Append(zitadelErr, err)
|
systemErr = multierror.Append(systemErr, err)
|
||||||
}
|
}
|
||||||
if !healthy {
|
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 (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
zitadelv1alpha1 "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/api/v1alpha1"
|
||||||
zitadelClient "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/zitadel"
|
zitadelClient "gitea.corredorconect.com/software-engineering/zitadel-k8s-operator/pkg/zitadel"
|
||||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ZitadelFinalizer struct {
|
type SystemFinalizer struct {
|
||||||
Client client.Client
|
Client client.Client
|
||||||
RefResolver *zitadelv1alpha1.RefResolver
|
RefResolver *zitadelv1alpha1.RefResolver
|
||||||
|
|
||||||
WrappedFinalizer WrappedFinalizer
|
WrappedFinalizer WrappedSystemFinalizer
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewZitadelFinalizer(client client.Client, wf WrappedFinalizer) Finalizer {
|
func NewSystemFinalizer(client client.Client, wf WrappedSystemFinalizer) Finalizer {
|
||||||
return &ZitadelFinalizer{
|
return &SystemFinalizer{
|
||||||
Client: client,
|
Client: client,
|
||||||
RefResolver: zitadelv1alpha1.NewRefResolver(client),
|
RefResolver: zitadelv1alpha1.NewRefResolver(client),
|
||||||
WrappedFinalizer: wf,
|
WrappedFinalizer: wf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tf *ZitadelFinalizer) AddFinalizer(ctx context.Context) error {
|
func (tf *SystemFinalizer) AddFinalizer(ctx context.Context) error {
|
||||||
if tf.WrappedFinalizer.ContainsFinalizer() {
|
if tf.WrappedFinalizer.ContainsFinalizer() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -35,16 +35,16 @@ func (tf *ZitadelFinalizer) AddFinalizer(ctx context.Context) error {
|
|||||||
return nil
|
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() {
|
if !tf.WrappedFinalizer.ContainsFinalizer() {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
zitadelRef, err := resource.ZitadelClusterRef(ctx, tf.RefResolver)
|
clusterRef, err := resource.ClusterRef(ctx, tf.RefResolver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
zitadel, err := tf.RefResolver.ZitadelCluster(ctx, zitadelRef, resource.GetNamespace())
|
system, err := tf.RefResolver.Cluster(ctx, clusterRef, resource.GetNamespace())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if apierrors.IsNotFound(err) {
|
if apierrors.IsNotFound(err) {
|
||||||
if err := tf.WrappedFinalizer.RemoveFinalizer(ctx); err != nil {
|
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 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 {
|
if err := waitForCluster(ctx, tf.Client, resource, system); err != nil {
|
||||||
return fmt.Errorf("error waiting for ZitadelCluster: %v", err)
|
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 {
|
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()
|
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 (
|
const (
|
||||||
ZitadelName = "zitadel"
|
ZitadelName = "zitadel"
|
||||||
ZitadelPort = 8080
|
ZitadelPort = 8080
|
||||||
|
LoginName = "login-ui"
|
||||||
|
LoginPort = 3000
|
||||||
SecretMountPath = "/var/secrets/"
|
SecretMountPath = "/var/secrets/"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -3,9 +3,9 @@ package health
|
|||||||
import (
|
import (
|
||||||
"context"
|
"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"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
|
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||||
@@ -13,7 +13,7 @@ import (
|
|||||||
|
|
||||||
type EndpointPolicy string
|
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)
|
key := ctrlclient.ObjectKeyFromObject(zitadel)
|
||||||
var dep appsv1.Deployment
|
var dep appsv1.Deployment
|
||||||
if err := client.Get(ctx, key, &dep); err != nil {
|
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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user