Compare commits
10 Commits
897ce79223
...
da5d944430
| 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
|
|
||||||
// +kubebuilder:default="DEFAULT"
|
|
||||||
FirstOrgName string `json:"firstOrgName"`
|
|
||||||
DomainSettings DomainSettings `json:"domainSettings"`
|
|
||||||
SMTPConfig SMTPConfig `json:"smtpConfig"`
|
|
||||||
Host string `json:"host"`
|
Host string `json:"host"`
|
||||||
|
|
||||||
|
// ExternalPort is the port exposed externally.
|
||||||
// +kubebuilder:default=443
|
// +kubebuilder:default=443
|
||||||
ExternalPort int64 `json:"externalPort"`
|
ExternalPort int64 `json:"externalPort"`
|
||||||
|
|
||||||
|
// ExternalSecure indicates whether TLS is used on the external endpoint.
|
||||||
// +kubebuilder:default=true
|
// +kubebuilder:default=true
|
||||||
ExternalSecure bool `json:"externalSecure"`
|
ExternalSecure bool `json:"externalSecure"`
|
||||||
|
|
||||||
|
// Image is the Zitadel container image to deploy.
|
||||||
Image Image `json:"image"`
|
Image Image `json:"image"`
|
||||||
|
|
||||||
|
// Resources defines compute resource requests and limits for the Zitadel pods.
|
||||||
Resources corev1.ResourceRequirements `json:"resources"`
|
Resources corev1.ResourceRequirements `json:"resources"`
|
||||||
|
|
||||||
|
// PostgreSQLClusterRef references the backing PostgreSQL cluster.
|
||||||
PostgreSQLClusterRef PostgreSQLClusterRef `json:"postgresClusterRef"`
|
PostgreSQLClusterRef PostgreSQLClusterRef `json:"postgresClusterRef"`
|
||||||
// +kubebuilder:validation:Enum=demo;trial;staging;productive;testing
|
|
||||||
Purpose string `json:"purpose"`
|
// Replicas is the desired number of Zitadel pods.
|
||||||
// PodAnnotations to add to the Pods metadata.
|
// +kubebuilder:default=3
|
||||||
|
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podCount"}
|
||||||
|
Replicas int32 `json:"replicas,omitempty"`
|
||||||
|
|
||||||
|
// PodAnnotations are extra annotations added to each Zitadel Pod.
|
||||||
// +optional
|
// +optional
|
||||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||||
PodAnnotations map[string]string `json:"podAnnotations,omitempty"`
|
PodAnnotations map[string]string `json:"podAnnotations,omitempty"`
|
||||||
// ServiceAnnotations to add to the service metadata.
|
|
||||||
|
// ServiceAnnotations are extra annotations added to the Zitadel Service.
|
||||||
// +optional
|
// +optional
|
||||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||||
ServiceAnnotations map[string]string `json:"serviceAnnotations,omitempty"`
|
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
|
// ClusterStatus defines the observed state of Cluster.
|
||||||
type ZitadelClusterStatus struct {
|
type ClusterStatus struct {
|
||||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
// Conditions store the status conditions of the Cluster.
|
||||||
// Important: Run "make" to regenerate code after modifying this file
|
|
||||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||||
|
|
||||||
|
// Replicas is the current number of running 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=status,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:podCount"}
|
||||||
Replicas int32 `json:"replicas,omitempty"`
|
Replicas int32 `json:"replicas,omitempty"`
|
||||||
// +kubebuilder:default=""
|
|
||||||
DefaultInstanceId string `json:"defaultInstanceId"`
|
|
||||||
// +kubebuilder:default=""
|
|
||||||
SMTPProviderId string `json:"smtpProviderId"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCondition sets a status condition
|
// SetCondition sets a status condition on the Cluster.
|
||||||
func (s *ZitadelClusterStatus) SetCondition(condition metav1.Condition) {
|
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
|
|
||||||
properties:
|
|
||||||
accessTokenType:
|
|
||||||
enum:
|
|
||||||
- ACCESS_TOKEN_TYPE_BEARER
|
|
||||||
- ACCESS_TOKEN_TYPE_JWT
|
|
||||||
type: string
|
|
||||||
organizationRef:
|
|
||||||
description: |-
|
description: |-
|
||||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
InstanceSpec defines the desired state of Instance.
|
||||||
Important: Run "make" to regenerate code after modifying this file
|
Fields map directly to POST /instances/_create (CreateInstance) in the Zitadel System API.
|
||||||
|
properties:
|
||||||
|
clusterRef:
|
||||||
|
description: ClusterRef references the Cluster this instance will
|
||||||
|
be provisioned on.
|
||||||
properties:
|
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:
|
||||||
|
type: string
|
||||||
|
defaultLanguage:
|
||||||
|
default: en
|
||||||
|
description: DefaultLanguage is the BCP-47 language tag used as the
|
||||||
|
instance default (e.g. "en").
|
||||||
|
type: string
|
||||||
|
instanceName:
|
||||||
|
description: InstanceName is the display name of the Zitadel instance.
|
||||||
|
type: string
|
||||||
|
loginUI:
|
||||||
|
default:
|
||||||
|
image:
|
||||||
|
name: ghcr.io/zitadel/zitadel-login
|
||||||
|
resources: {}
|
||||||
|
properties:
|
||||||
|
image:
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
default: ghcr.io/zitadel/zitadel-login
|
||||||
|
type: string
|
||||||
|
tag:
|
||||||
|
description: if empty it uses the same tag as zitadel cluster
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
resources:
|
||||||
|
description: ResourceRequirements describes the compute resource
|
||||||
|
requirements.
|
||||||
|
properties:
|
||||||
|
claims:
|
||||||
|
description: |-
|
||||||
|
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||||
|
that are used by this container.
|
||||||
|
|
||||||
|
This is an alpha field and requires enabling the
|
||||||
|
DynamicResourceAllocation feature gate.
|
||||||
|
|
||||||
|
This field is immutable. It can only be set for containers.
|
||||||
items:
|
items:
|
||||||
|
description: ResourceClaim references one entry in PodSpec.ResourceClaims.
|
||||||
properties:
|
properties:
|
||||||
projectRef:
|
|
||||||
properties:
|
|
||||||
apiVersion:
|
|
||||||
description: API version of the referent.
|
|
||||||
type: string
|
|
||||||
fieldPath:
|
|
||||||
description: |-
|
|
||||||
If referring to a piece of an object instead of an entire object, this string
|
|
||||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
|
||||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
|
||||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
|
||||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
|
||||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
|
||||||
referencing a part of an object.
|
|
||||||
type: string
|
|
||||||
kind:
|
|
||||||
description: |-
|
|
||||||
Kind of the referent.
|
|
||||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
|
||||||
type: string
|
|
||||||
name:
|
name:
|
||||||
description: |-
|
description: |-
|
||||||
Name of the referent.
|
Name must match the name of one entry in pod.spec.resourceClaims of
|
||||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
the Pod where this field is used. It makes that resource available
|
||||||
|
inside a container.
|
||||||
type: string
|
type: string
|
||||||
namespace:
|
request:
|
||||||
description: |-
|
description: |-
|
||||||
Namespace of the referent.
|
Request is the name chosen for a request in the referenced claim.
|
||||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
If empty, everything from the claim is made available, otherwise
|
||||||
|
only the result of this request.
|
||||||
type: string
|
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:
|
required:
|
||||||
- projectRef
|
- name
|
||||||
type: object
|
type: object
|
||||||
type: array
|
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:
|
required:
|
||||||
- accessTokenType
|
- image
|
||||||
- organizationRef
|
- resources
|
||||||
|
type: object
|
||||||
|
org:
|
||||||
|
description: Org configures the first organisation and its initial
|
||||||
|
IAM_OWNER machine user.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
default: DEFAULT
|
||||||
|
description: Name of the first organization.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- clusterRef
|
||||||
|
- customDomain
|
||||||
|
- instanceName
|
||||||
|
- loginUI
|
||||||
|
- org
|
||||||
type: object
|
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
|
|
||||||
properties:
|
|
||||||
accessTokenType:
|
|
||||||
enum:
|
|
||||||
- ACCESS_TOKEN_TYPE_BEARER
|
|
||||||
- ACCESS_TOKEN_TYPE_JWT
|
|
||||||
type: string
|
|
||||||
organizationRef:
|
|
||||||
description: |-
|
description: |-
|
||||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
InstanceSpec defines the desired state of Instance.
|
||||||
Important: Run "make" to regenerate code after modifying this file
|
Fields map directly to POST /instances/_create (CreateInstance) in the Zitadel System API.
|
||||||
|
properties:
|
||||||
|
clusterRef:
|
||||||
|
description: ClusterRef references the Cluster this instance will
|
||||||
|
be provisioned on.
|
||||||
properties:
|
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:
|
||||||
|
type: string
|
||||||
|
defaultLanguage:
|
||||||
|
default: en
|
||||||
|
description: DefaultLanguage is the BCP-47 language tag used as the
|
||||||
|
instance default (e.g. "en").
|
||||||
|
type: string
|
||||||
|
instanceName:
|
||||||
|
description: InstanceName is the display name of the Zitadel instance.
|
||||||
|
type: string
|
||||||
|
loginUI:
|
||||||
|
default:
|
||||||
|
image:
|
||||||
|
name: ghcr.io/zitadel/zitadel-login
|
||||||
|
resources: {}
|
||||||
|
properties:
|
||||||
|
image:
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
default: ghcr.io/zitadel/zitadel-login
|
||||||
|
type: string
|
||||||
|
tag:
|
||||||
|
description: if empty it uses the same tag as zitadel cluster
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
resources:
|
||||||
|
description: ResourceRequirements describes the compute resource
|
||||||
|
requirements.
|
||||||
|
properties:
|
||||||
|
claims:
|
||||||
|
description: |-
|
||||||
|
Claims lists the names of resources, defined in spec.resourceClaims,
|
||||||
|
that are used by this container.
|
||||||
|
|
||||||
|
This is an alpha field and requires enabling the
|
||||||
|
DynamicResourceAllocation feature gate.
|
||||||
|
|
||||||
|
This field is immutable. It can only be set for containers.
|
||||||
items:
|
items:
|
||||||
|
description: ResourceClaim references one entry in PodSpec.ResourceClaims.
|
||||||
properties:
|
properties:
|
||||||
projectRef:
|
|
||||||
properties:
|
|
||||||
apiVersion:
|
|
||||||
description: API version of the referent.
|
|
||||||
type: string
|
|
||||||
fieldPath:
|
|
||||||
description: |-
|
|
||||||
If referring to a piece of an object instead of an entire object, this string
|
|
||||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
|
||||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
|
||||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
|
||||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
|
||||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
|
||||||
referencing a part of an object.
|
|
||||||
type: string
|
|
||||||
kind:
|
|
||||||
description: |-
|
|
||||||
Kind of the referent.
|
|
||||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
|
||||||
type: string
|
|
||||||
name:
|
name:
|
||||||
description: |-
|
description: |-
|
||||||
Name of the referent.
|
Name must match the name of one entry in pod.spec.resourceClaims of
|
||||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
the Pod where this field is used. It makes that resource available
|
||||||
|
inside a container.
|
||||||
type: string
|
type: string
|
||||||
namespace:
|
request:
|
||||||
description: |-
|
description: |-
|
||||||
Namespace of the referent.
|
Request is the name chosen for a request in the referenced claim.
|
||||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
If empty, everything from the claim is made available, otherwise
|
||||||
|
only the result of this request.
|
||||||
type: string
|
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:
|
required:
|
||||||
- projectRef
|
- name
|
||||||
type: object
|
type: object
|
||||||
type: array
|
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:
|
required:
|
||||||
- accessTokenType
|
- image
|
||||||
- organizationRef
|
- resources
|
||||||
|
type: object
|
||||||
|
org:
|
||||||
|
description: Org configures the first organisation and its initial
|
||||||
|
IAM_OWNER machine user.
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
default: DEFAULT
|
||||||
|
description: Name of the first organization.
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- name
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- clusterRef
|
||||||
|
- customDomain
|
||||||
|
- instanceName
|
||||||
|
- loginUI
|
||||||
|
- org
|
||||||
type: object
|
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 }}'
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -30,7 +29,6 @@ func (b *Builder) BuildInitJob(zitadel *zitadelv1alpha1.ZitadelCluster, key type
|
|||||||
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
@@ -1,173 +0,0 @@
|
|||||||
---
|
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
|
||||||
kind: CustomResourceDefinition
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
controller-gen.kubebuilder.io/version: v0.17.3
|
|
||||||
name: actions.zitadel.topmanage.com
|
|
||||||
spec:
|
|
||||||
group: zitadel.topmanage.com
|
|
||||||
names:
|
|
||||||
kind: Action
|
|
||||||
listKind: ActionList
|
|
||||||
plural: actions
|
|
||||||
singular: action
|
|
||||||
scope: Namespaced
|
|
||||||
versions:
|
|
||||||
- name: v1alpha1
|
|
||||||
schema:
|
|
||||||
openAPIV3Schema:
|
|
||||||
description: Action is the Schema for the actions API
|
|
||||||
properties:
|
|
||||||
apiVersion:
|
|
||||||
description: |-
|
|
||||||
APIVersion defines the versioned schema of this representation of an object.
|
|
||||||
Servers should convert recognized schemas to the latest internal value, and
|
|
||||||
may reject unrecognized values.
|
|
||||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
|
||||||
type: string
|
|
||||||
kind:
|
|
||||||
description: |-
|
|
||||||
Kind is a string value representing the REST resource this object represents.
|
|
||||||
Servers may infer this from the endpoint the client submits requests to.
|
|
||||||
Cannot be updated.
|
|
||||||
In CamelCase.
|
|
||||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
|
||||||
type: string
|
|
||||||
metadata:
|
|
||||||
type: object
|
|
||||||
spec:
|
|
||||||
description: ActionSpec defines the desired state of Action
|
|
||||||
properties:
|
|
||||||
allowedToFail:
|
|
||||||
default: true
|
|
||||||
type: boolean
|
|
||||||
organizationRef:
|
|
||||||
description: |-
|
|
||||||
INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
|
||||||
Important: Run "make" to regenerate code after modifying this file
|
|
||||||
properties:
|
|
||||||
apiVersion:
|
|
||||||
description: API version of the referent.
|
|
||||||
type: string
|
|
||||||
fieldPath:
|
|
||||||
description: |-
|
|
||||||
If referring to a piece of an object instead of an entire object, this string
|
|
||||||
should contain a valid JSON/Go field access statement, such as desiredState.manifest.containers[2].
|
|
||||||
For example, if the object reference is to a container within a pod, this would take on a value like:
|
|
||||||
"spec.containers{name}" (where "name" refers to the name of the container that triggered
|
|
||||||
the event) or if no container name is specified "spec.containers[2]" (container with
|
|
||||||
index 2 in this pod). This syntax is chosen only to have some well-defined way of
|
|
||||||
referencing a part of an object.
|
|
||||||
type: string
|
|
||||||
kind:
|
|
||||||
description: |-
|
|
||||||
Kind of the referent.
|
|
||||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
|
||||||
type: string
|
|
||||||
name:
|
|
||||||
description: |-
|
|
||||||
Name of the referent.
|
|
||||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
|
|
||||||
type: string
|
|
||||||
namespace:
|
|
||||||
description: |-
|
|
||||||
Namespace of the referent.
|
|
||||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/namespaces/
|
|
||||||
type: string
|
|
||||||
resourceVersion:
|
|
||||||
description: |-
|
|
||||||
Specific resourceVersion to which this reference is made, if any.
|
|
||||||
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#concurrency-control-and-consistency
|
|
||||||
type: string
|
|
||||||
uid:
|
|
||||||
description: |-
|
|
||||||
UID of the referent.
|
|
||||||
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#uids
|
|
||||||
type: string
|
|
||||||
type: object
|
|
||||||
x-kubernetes-map-type: atomic
|
|
||||||
script:
|
|
||||||
type: string
|
|
||||||
timeout:
|
|
||||||
format: duration
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- allowedToFail
|
|
||||||
- organizationRef
|
|
||||||
- script
|
|
||||||
- timeout
|
|
||||||
type: object
|
|
||||||
status:
|
|
||||||
description: ActionStatus defines the observed state of Action
|
|
||||||
properties:
|
|
||||||
actionId:
|
|
||||||
default: ""
|
|
||||||
type: string
|
|
||||||
conditions:
|
|
||||||
description: |-
|
|
||||||
INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
|
||||||
Important: Run "make" to regenerate code after modifying this file
|
|
||||||
items:
|
|
||||||
description: Condition contains details for one aspect of the current
|
|
||||||
state of this API Resource.
|
|
||||||
properties:
|
|
||||||
lastTransitionTime:
|
|
||||||
description: |-
|
|
||||||
lastTransitionTime is the last time the condition transitioned from one status to another.
|
|
||||||
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
|
||||||
format: date-time
|
|
||||||
type: string
|
|
||||||
message:
|
|
||||||
description: |-
|
|
||||||
message is a human readable message indicating details about the transition.
|
|
||||||
This may be an empty string.
|
|
||||||
maxLength: 32768
|
|
||||||
type: string
|
|
||||||
observedGeneration:
|
|
||||||
description: |-
|
|
||||||
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
|
||||||
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
|
||||||
with respect to the current state of the instance.
|
|
||||||
format: int64
|
|
||||||
minimum: 0
|
|
||||||
type: integer
|
|
||||||
reason:
|
|
||||||
description: |-
|
|
||||||
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
|
||||||
Producers of specific condition types may define expected values and meanings for this field,
|
|
||||||
and whether the values are considered a guaranteed API.
|
|
||||||
The value should be a CamelCase string.
|
|
||||||
This field may not be empty.
|
|
||||||
maxLength: 1024
|
|
||||||
minLength: 1
|
|
||||||
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
|
||||||
type: string
|
|
||||||
status:
|
|
||||||
description: status of the condition, one of True, False, Unknown.
|
|
||||||
enum:
|
|
||||||
- "True"
|
|
||||||
- "False"
|
|
||||||
- Unknown
|
|
||||||
type: string
|
|
||||||
type:
|
|
||||||
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
|
||||||
maxLength: 316
|
|
||||||
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
|
||||||
type: string
|
|
||||||
required:
|
|
||||||
- lastTransitionTime
|
|
||||||
- message
|
|
||||||
- reason
|
|
||||||
- status
|
|
||||||
- type
|
|
||||||
type: object
|
|
||||||
type: array
|
|
||||||
required:
|
|
||||||
- actionId
|
|
||||||
type: object
|
|
||||||
type: object
|
|
||||||
served: true
|
|
||||||
storage: true
|
|
||||||
subresources:
|
|
||||||
status: {}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user