move everything to src
All checks were successful
Build and Publish / build-release (push) Successful in 8m29s

This commit is contained in:
2026-04-07 12:33:54 -05:00
parent 080a33f76f
commit d5c3485fd2
98 changed files with 75 additions and 76 deletions

View File

@@ -0,0 +1,100 @@
/*
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.
// 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) ConnectionRef(ctx context.Context, refresolver *RefResolver) (*ConnectionRef, error) {
org, err := refresolver.OrganizationRef(ctx, &d.Spec.OrganizationRef, d.Namespace)
if err != nil {
return nil, err
}
return &org.Spec.ConnectionRef, 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{})
}

View File

@@ -0,0 +1,122 @@
/*
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.
// 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) ConnectionRef(ctx context.Context, refresolver *RefResolver) (*ConnectionRef, 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.Spec.ConnectionRef, 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{})
}

View File

@@ -0,0 +1,32 @@
package v1alpha1
const (
ConditionTypeReady string = "Ready"
ConditionTypePATUpToDate string = "PATUpToDate"
ConditionReasonRolesChanged string = "RolesChanged"
ConditionReasonPATUpToDate string = "UpToDate"
ConditionReasonDeploymentNotReady string = "DeploymentNotReady"
ConditionReasonDeploymentReady string = "DeploymentReady"
ConditionReasonRestoreBackup string = "RestoreBackup"
ConditionReasonRestoreNotComplete string = "RestoreNotComplete"
ConditionReasonRestoreComplete string = "RestoreComplete"
ConditionReasonJobComplete string = "JobComplete"
ConditionReasonJobSuspended string = "JobSuspended"
ConditionReasonJobFailed string = "JobFailed"
ConditionReasonJobRunning string = "JobRunning"
ConditionReasonCronJobScheduled string = "CronJobScheduled"
ConditionReasonCronJobFailed string = "CronJobScheduled"
ConditionReasonCronJobRunning string = "CronJobRunning"
ConditionReasonCronJobSuccess string = "CronJobSucess"
ConditionReasonConnectionFailed string = "ConnectionFailed"
ConditionReasonCreated string = "Created"
ConditionReasonHealthy string = "Healthy"
ConditionReasonFailed string = "Failed"
)

View File

@@ -0,0 +1,122 @@
/*
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 (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"context"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/meta"
)
// 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 PAT struct {
TokenSecretKey corev1.SecretKeySelector `json:"tokenSecretKey"`
}
type JWT struct {
JWTSecretKey corev1.SecretKeySelector `json:"jwtSecretKey"`
Scopes []string `json:"scopes"`
}
type UserPassword struct {
Username string `json:"username"`
PasswordSecretKey corev1.SecretKeySelector `json:"passwordSecretKey"`
Scopes []string `json:"scopes"`
}
// +kubebuilder:validation:XValidation:rule="[has(self.pat), has(self.password), has(self.jwt)].filter(x, x).size() == 1",message="exactly one of pat, password, or jwt must be specified"
type Authentication struct {
PAT *PAT `json:"pat,omitempty"`
Password *UserPassword `json:"password,omitempty"`
JWT *JWT `json:"jwt,omitempty"`
}
// ConnectionSpec defines the desired state of Connection
type ConnectionSpec struct {
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
// Important: Run "make" to regenerate code after modifying this file
Host string `json:"host"`
Port *uint16 `json:"port,omitempty"`
// +kubebuilder:default=true
Secure bool `json:"secure"`
// +kubebuilder:default=false
InsecureSkipVerifyTLS bool `json:"insecureSkipVerifyTLS"`
Authentication Authentication `json:"authentication"`
}
// ConnectionStatus defines the observed state of Connection
type ConnectionStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
// Conditions for the Connection object.
// +optional
// +operator-sdk:csv:customresourcedefinitions:type=status,xDescriptors={"urn:alm:descriptor:io.kubernetes.conditions"}
Conditions []metav1.Condition `json:"conditions,omitempty"`
}
func (d *ConnectionStatus) SetCondition(condition metav1.Condition) {
if d.Conditions == nil {
d.Conditions = make([]metav1.Condition, 0)
}
meta.SetStatusCondition(&d.Conditions, condition)
}
func (d *Connection) IsBeingDeleted() bool {
return !d.DeletionTimestamp.IsZero()
}
func (d *Connection) IsReady() bool {
return meta.IsStatusConditionTrue(d.Status.Conditions, ConditionTypeReady)
}
func (d *Connection) ConnectionRef(_ context.Context, _ *RefResolver) (*ConnectionRef, error) {
return &ConnectionRef{
ObjectReference: corev1.ObjectReference{
Kind: d.Kind,
Namespace: d.Namespace,
Name: d.Name,
},
}, nil
}
// +kubebuilder:object:root=true
// +kubebuilder:subresource:status
// Connection is the Schema for the connections API
type Connection struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ConnectionSpec `json:"spec,omitempty"`
Status ConnectionStatus `json:"status,omitempty"`
}
// +kubebuilder:object:root=true
// ConnectionList contains a list of Connection
type ConnectionList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata,omitempty"`
Items []Connection `json:"items"`
}
func init() {
SchemeBuilder.Register(&Connection{}, &ConnectionList{})
}

View File

@@ -0,0 +1,97 @@
/*
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.
// 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) ConnectionRef(ctx context.Context, refresolver *RefResolver) (*ConnectionRef, error) {
org, err := refresolver.OrganizationRef(ctx, &d.Spec.OrganizationRef, d.Namespace)
if err != nil {
return nil, err
}
return &org.Spec.ConnectionRef, 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{})
}

View File

@@ -0,0 +1,36 @@
/*
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 contains API Schema definitions for the zitadel v1alpha1 API group
// +kubebuilder:object:generate=true
// +groupName=zitadel.github.com
package v1alpha1
import (
"k8s.io/apimachinery/pkg/runtime/schema"
"sigs.k8s.io/controller-runtime/pkg/scheme"
)
var (
// GroupVersion is group version used to register these objects
GroupVersion = schema.GroupVersion{Group: "zitadel.github.com", Version: "v1alpha1"}
// SchemeBuilder is used to add go types to the GroupVersionKind scheme
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
// AddToScheme adds the types in this group-version to the given scheme.
AddToScheme = SchemeBuilder.AddToScheme
)

View File

@@ -0,0 +1,156 @@
/*
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 Authorization struct {
ProjectRef ProjectRef `json:"projectRef"`
RoleKeys []string `json:"roleKeys,omitempty"`
}
type OrganizationResource struct {
OrgID string `json:"orgId"`
}
type ProjectResource struct {
ProjectID string `json:"projectId"`
}
type ProjectGrantResource struct {
ProjectID string `json:"projectId"`
OrgID string `json:"orgId"`
}
type InstanceResource struct{}
// +kubebuilder:validation:XValidation:rule="[has(self.organization), has(self.instance), has(self.project), has(self.projectGrant)].filter(x, x).size() == 1",message="exactly one of organization, instance, project, or projectGrant must be specified"
type Resource struct {
// +optional
Organization *OrganizationResource `json:"organization,omitempty"`
// +optional
Instance *InstanceResource `json:"instance,omitempty"`
// +optional
Project *ProjectResource `json:"project,omitempty"`
// +optional
ProjectGrant *ProjectGrantResource `json:"projectGrant,omitempty"`
}
type InternalPermissions struct {
Resource Resource `json:"resource"`
// +kubebuilder:validation:MaxItems=50
Roles []string `json:"roles,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"`
Authorizations []Authorization `json:"authorizations,omitempty"`
// +kubebuilder:validation:MaxItems=100
InternalPermissions []InternalPermissions `json:"internalPermissions,omitempty"`
Metadata []map[string]string `json:"metadata,omitempty"`
Username string `json:"username"`
}
// 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"`
UserId *string `json:"userId,omitempty"`
KeyId *string `json:"keyId,omitempty"`
PATId *string `json:"patId,omitempty"`
}
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) ConnectionRef(ctx context.Context, refresolver *RefResolver) (*ConnectionRef, error) {
org, err := refresolver.OrganizationRef(ctx, &d.Spec.OrganizationRef, d.Namespace)
if err != nil {
return nil, err
}
return &org.Spec.ConnectionRef, 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{})
}

View File

@@ -0,0 +1,149 @@
/*
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.
// +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"`
OIDCAppName string `json:"oidcAppName"`
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"`
BackChannelLogoutUri string `json:"backChannelLogoutUri,omitempty"`
}
// 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"`
AppId *string `json:"appId"`
ClientId *string `json:"clientId,omitempty"`
}
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) ConnectionRef(ctx context.Context, refresolver *RefResolver) (*ConnectionRef, 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.Spec.ConnectionRef, 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{})
}

View File

@@ -0,0 +1,92 @@
/*
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.
// 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
ConnectionRef ConnectionRef `json:"connectionRef" webhook:"inmutable"`
OrganzationName string `json:"organizationName"`
}
// 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"`
OrganizationId *string `json:"organizationId,omitempty"`
}
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) ConnectionRef(_ context.Context, _ *RefResolver) (*ConnectionRef, error) {
return &d.Spec.ConnectionRef, 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{})
}

View File

@@ -0,0 +1,117 @@
/*
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 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"`
ProjectName string `json:"projectName"`
}
// 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"`
ProjectId *string `json:"projectId,omitempty"`
}
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) ConnectionRef(ctx context.Context, refresolver *RefResolver) (*ConnectionRef, error) {
org, err := refresolver.OrganizationRef(ctx, &d.Spec.OrganizationRef, d.Namespace)
if err != nil {
return nil, err
}
return &org.Spec.ConnectionRef, 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{})
}

35
api/v1alpha1/ref_types.go Normal file
View File

@@ -0,0 +1,35 @@
package v1alpha1
import (
corev1 "k8s.io/api/core/v1"
)
type ConnectionRef struct {
// ObjectReference is a reference to a object.
// +operator-sdk:csv:customresourcedefinitions:type=spec
corev1.ObjectReference `json:",inline"`
}
type OIDCAppRef 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"`
}

143
api/v1alpha1/refresolver.go Normal file
View File

@@ -0,0 +1,143 @@
package v1alpha1
import (
"context"
"fmt"
corev1 "k8s.io/api/core/v1"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types"
"sigs.k8s.io/controller-runtime/pkg/client"
)
// +kubebuilder:object:generate=false
type RefResolver struct {
client client.Client
}
func NewRefResolver(client client.Client) *RefResolver {
return &RefResolver{
client: client,
}
}
func (r *RefResolver) OIDCAppRef(ctx context.Context, ref *OIDCAppRef,
namespace string) (*OIDCApp, error) {
if ref.Kind != "" && ref.Kind != "OIDCApp" {
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 OIDCApp
if err := r.client.Get(ctx, key, &zitadel); err != nil {
return nil, err
}
return &zitadel, nil
}
func (r *RefResolver) ActionRef(ctx context.Context, ref *ActionRef,
namespace string) (*Action, error) {
if ref.Kind != "" && ref.Kind != "Action" {
return nil, fmt.Errorf("Unsupported reference kind: '%s'", ref.Kind)
}
key := types.NamespacedName{
Name: ref.Name,
Namespace: namespace,
}
if ref.Namespace != "" {
key.Namespace = ref.Namespace
}
var zitadel Action
if err := r.client.Get(ctx, key, &zitadel); err != nil {
return nil, err
}
return &zitadel, nil
}
func (r *RefResolver) ProjectRef(ctx context.Context, ref *ProjectRef,
namespace string) (*Project, error) {
if ref.Kind != "" && ref.Kind != "Project" {
return nil, fmt.Errorf("Unsupported reference kind: '%s'", ref.Kind)
}
key := types.NamespacedName{
Name: ref.Name,
Namespace: namespace,
}
if ref.Namespace != "" {
key.Namespace = ref.Namespace
}
var zitadel Project
if err := r.client.Get(ctx, key, &zitadel); err != nil {
return nil, err
}
return &zitadel, nil
}
func (r *RefResolver) OrganizationRef(ctx context.Context, ref *OrganizationRef,
namespace string) (*Organization, error) {
if ref.Kind != "" && ref.Kind != "Organization" {
return nil, fmt.Errorf("Unsupported reference kind: '%s'", ref.Kind)
}
key := types.NamespacedName{
Name: ref.Name,
Namespace: namespace,
}
if ref.Namespace != "" {
key.Namespace = ref.Namespace
}
var zitadel Organization
if err := r.client.Get(ctx, key, &zitadel); err != nil {
return nil, err
}
return &zitadel, nil
}
func (r *RefResolver) ConnectionRef(ctx context.Context, ref *ConnectionRef, namespace string) (*Connection, error) {
if ref.Kind != "" && ref.Kind != "Connection" {
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 connection Connection
if err := r.client.Get(ctx, key, &connection); err != nil {
return nil, err
}
return &connection, nil
}
func (r *RefResolver) SecretKeyRef(ctx context.Context, selector corev1.SecretKeySelector,
namespace string) (string, error) {
nn := types.NamespacedName{
Name: selector.Name,
Namespace: namespace,
}
var secret v1.Secret
if err := r.client.Get(ctx, nn, &secret); err != nil {
return "", fmt.Errorf("error getting secret: %v", err)
}
data, ok := secret.Data[selector.Key]
if !ok {
return "", fmt.Errorf("secret key \"%s\" not found", selector.Key)
}
return string(data), nil
}

File diff suppressed because it is too large Load Diff