Add initial admin
[ZITADOPER-1]
This commit is contained in:
@@ -39,7 +39,7 @@ spec:
|
|||||||
- ACCESS_TOKEN_TYPE_BEARER
|
- ACCESS_TOKEN_TYPE_BEARER
|
||||||
- ACCESS_TOKEN_TYPE_JWT
|
- ACCESS_TOKEN_TYPE_JWT
|
||||||
type: string
|
type: string
|
||||||
zitadelClusterRef:
|
organizationRef:
|
||||||
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||||
Important: Run "make" to regenerate code after modifying this file'
|
Important: Run "make" to regenerate code after modifying this file'
|
||||||
properties:
|
properties:
|
||||||
@@ -79,7 +79,7 @@ spec:
|
|||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
required:
|
required:
|
||||||
- accessTokenType
|
- accessTokenType
|
||||||
- zitadelClusterRef
|
- organizationRef
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
description: MachineUserStatus defines the observed state of MachineUser
|
description: MachineUserStatus defines the observed state of MachineUser
|
||||||
|
|||||||
@@ -77,10 +77,13 @@ spec:
|
|||||||
externalSecure:
|
externalSecure:
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
host:
|
firstOrgName:
|
||||||
|
default: DEFAULT
|
||||||
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||||
Important: Run "make" to regenerate code after modifying this file'
|
Important: Run "make" to regenerate code after modifying this file'
|
||||||
type: string
|
type: string
|
||||||
|
host:
|
||||||
|
type: string
|
||||||
image:
|
image:
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
@@ -165,6 +168,7 @@ spec:
|
|||||||
- crdbClusterRef
|
- crdbClusterRef
|
||||||
- externalPort
|
- externalPort
|
||||||
- externalSecure
|
- externalSecure
|
||||||
|
- firstOrgName
|
||||||
- host
|
- host
|
||||||
- image
|
- image
|
||||||
- purpose
|
- purpose
|
||||||
@@ -247,12 +251,16 @@ spec:
|
|||||||
defaultInstanceId:
|
defaultInstanceId:
|
||||||
default: ""
|
default: ""
|
||||||
type: string
|
type: string
|
||||||
|
initialAdminId:
|
||||||
|
default: ""
|
||||||
|
type: string
|
||||||
replicas:
|
replicas:
|
||||||
default: 3
|
default: 3
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
required:
|
required:
|
||||||
- defaultInstanceId
|
- defaultInstanceId
|
||||||
|
- initialAdminId
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package v1alpha1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -82,10 +83,17 @@ func (d *APIApp) ZitadelClusterRef(ctx context.Context, refresolver *RefResolver
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
org, err := refresolver.OrganizationRef(ctx, &project.Spec.OrganizationRef, d.Namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if org.Status.OrgId == "" {
|
||||||
|
return nil, fmt.Errorf("Organization has not been created yet...")
|
||||||
|
}
|
||||||
ref, err := org.ZitadelClusterRef(ctx, refresolver)
|
ref, err := org.ZitadelClusterRef(ctx, refresolver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package v1alpha1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
@@ -31,7 +33,7 @@ type MachineUserSpec struct {
|
|||||||
// Important: Run "make" to regenerate code after modifying this file
|
// Important: Run "make" to regenerate code after modifying this file
|
||||||
// +kubebuilder:validation:Required
|
// +kubebuilder:validation:Required
|
||||||
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
// +operator-sdk:csv:customresourcedefinitions:type=spec
|
||||||
ZitadelClusterRef ZitadelClusterRef `json:"zitadelClusterRef" webhook:"inmutable"`
|
OrganizationRef OrganizationRef `json:"organizationRef" webhook:"inmutable"`
|
||||||
// +kubebuilder:validation:Enum=ACCESS_TOKEN_TYPE_BEARER;ACCESS_TOKEN_TYPE_JWT
|
// +kubebuilder:validation:Enum=ACCESS_TOKEN_TYPE_BEARER;ACCESS_TOKEN_TYPE_JWT
|
||||||
AccessTokenType string `json:"accessTokenType"`
|
AccessTokenType string `json:"accessTokenType"`
|
||||||
}
|
}
|
||||||
@@ -77,7 +79,19 @@ func (d *MachineUser) IsReady() bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (d *MachineUser) ZitadelClusterRef(ctx context.Context, refresolver *RefResolver) (*ZitadelClusterRef, error) {
|
func (d *MachineUser) ZitadelClusterRef(ctx context.Context, refresolver *RefResolver) (*ZitadelClusterRef, error) {
|
||||||
return &d.Spec.ZitadelClusterRef, nil
|
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
|
//+kubebuilder:object:root=true
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ package v1alpha1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
)
|
)
|
||||||
@@ -103,10 +105,18 @@ func (d *OIDCApp) ZitadelClusterRef(ctx context.Context, refresolver *RefResolve
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
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)
|
org, err := refresolver.OrganizationRef(ctx, &project.Spec.OrganizationRef, d.Namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if org.Status.OrgId == "" {
|
||||||
|
return nil, fmt.Errorf("Organization has not been created yet...")
|
||||||
|
}
|
||||||
ref, err := org.ZitadelClusterRef(ctx, refresolver)
|
ref, err := org.ZitadelClusterRef(ctx, refresolver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package v1alpha1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/meta"
|
"k8s.io/apimachinery/pkg/api/meta"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
@@ -94,6 +95,10 @@ func (d *Project) ZitadelClusterRef(ctx context.Context, refresolver *RefResolve
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if org.Status.OrgId == "" {
|
||||||
|
return nil, fmt.Errorf("Organization has not been created yet...")
|
||||||
|
}
|
||||||
|
|
||||||
ref, err := org.ZitadelClusterRef(ctx, refresolver)
|
ref, err := org.ZitadelClusterRef(ctx, refresolver)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|||||||
@@ -34,7 +34,9 @@ type Image struct {
|
|||||||
type ZitadelClusterSpec struct {
|
type ZitadelClusterSpec struct {
|
||||||
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
// INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||||
// Important: Run "make" to regenerate code after modifying this file
|
// Important: Run "make" to regenerate code after modifying this file
|
||||||
Host string `json:"host"`
|
// +kubebuilder:default="DEFAULT"
|
||||||
|
FirstOrgName string `json:"firstOrgName"`
|
||||||
|
Host string `json:"host"`
|
||||||
// +kubebuilder:default=443
|
// +kubebuilder:default=443
|
||||||
ExternalPort int64 `json:"externalPort"`
|
ExternalPort int64 `json:"externalPort"`
|
||||||
// +kubebuilder:default=true
|
// +kubebuilder:default=true
|
||||||
@@ -67,6 +69,8 @@ type ZitadelClusterStatus struct {
|
|||||||
Replicas int32 `json:"replicas,omitempty"`
|
Replicas int32 `json:"replicas,omitempty"`
|
||||||
// +kubebuilder:default=""
|
// +kubebuilder:default=""
|
||||||
DefaultInstanceId string `json:"defaultInstanceId"`
|
DefaultInstanceId string `json:"defaultInstanceId"`
|
||||||
|
// +kubebuilder:default=""
|
||||||
|
InitialAdminId string `json:"initialAdminId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetCondition sets a status condition
|
// SetCondition sets a status condition
|
||||||
|
|||||||
@@ -216,7 +216,7 @@ func (in *MachineUserList) DeepCopyObject() runtime.Object {
|
|||||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||||
func (in *MachineUserSpec) DeepCopyInto(out *MachineUserSpec) {
|
func (in *MachineUserSpec) DeepCopyInto(out *MachineUserSpec) {
|
||||||
*out = *in
|
*out = *in
|
||||||
out.ZitadelClusterRef = in.ZitadelClusterRef
|
out.OrganizationRef = in.OrganizationRef
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineUserSpec.
|
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MachineUserSpec.
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ spec:
|
|||||||
- ACCESS_TOKEN_TYPE_BEARER
|
- ACCESS_TOKEN_TYPE_BEARER
|
||||||
- ACCESS_TOKEN_TYPE_JWT
|
- ACCESS_TOKEN_TYPE_JWT
|
||||||
type: string
|
type: string
|
||||||
zitadelClusterRef:
|
organizationRef:
|
||||||
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||||
Important: Run "make" to regenerate code after modifying this file'
|
Important: Run "make" to regenerate code after modifying this file'
|
||||||
properties:
|
properties:
|
||||||
@@ -80,7 +80,7 @@ spec:
|
|||||||
x-kubernetes-map-type: atomic
|
x-kubernetes-map-type: atomic
|
||||||
required:
|
required:
|
||||||
- accessTokenType
|
- accessTokenType
|
||||||
- zitadelClusterRef
|
- organizationRef
|
||||||
type: object
|
type: object
|
||||||
status:
|
status:
|
||||||
description: MachineUserStatus defines the observed state of MachineUser
|
description: MachineUserStatus defines the observed state of MachineUser
|
||||||
|
|||||||
@@ -78,10 +78,13 @@ spec:
|
|||||||
externalSecure:
|
externalSecure:
|
||||||
default: true
|
default: true
|
||||||
type: boolean
|
type: boolean
|
||||||
host:
|
firstOrgName:
|
||||||
|
default: DEFAULT
|
||||||
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
description: 'INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
|
||||||
Important: Run "make" to regenerate code after modifying this file'
|
Important: Run "make" to regenerate code after modifying this file'
|
||||||
type: string
|
type: string
|
||||||
|
host:
|
||||||
|
type: string
|
||||||
image:
|
image:
|
||||||
properties:
|
properties:
|
||||||
name:
|
name:
|
||||||
@@ -166,6 +169,7 @@ spec:
|
|||||||
- crdbClusterRef
|
- crdbClusterRef
|
||||||
- externalPort
|
- externalPort
|
||||||
- externalSecure
|
- externalSecure
|
||||||
|
- firstOrgName
|
||||||
- host
|
- host
|
||||||
- image
|
- image
|
||||||
- purpose
|
- purpose
|
||||||
@@ -248,12 +252,16 @@ spec:
|
|||||||
defaultInstanceId:
|
defaultInstanceId:
|
||||||
default: ""
|
default: ""
|
||||||
type: string
|
type: string
|
||||||
|
initialAdminId:
|
||||||
|
default: ""
|
||||||
|
type: string
|
||||||
replicas:
|
replicas:
|
||||||
default: 3
|
default: 3
|
||||||
format: int32
|
format: int32
|
||||||
type: integer
|
type: integer
|
||||||
required:
|
required:
|
||||||
- defaultInstanceId
|
- defaultInstanceId
|
||||||
|
- initialAdminId
|
||||||
type: object
|
type: object
|
||||||
type: object
|
type: object
|
||||||
served: true
|
served: true
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import (
|
|||||||
condition "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/condition"
|
condition "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/condition"
|
||||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/controller/zitadel"
|
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/controller/zitadel"
|
||||||
"github.com/zitadel/zitadel-go/v2/pkg/client/management"
|
"github.com/zitadel/zitadel-go/v2/pkg/client/management"
|
||||||
|
"github.com/zitadel/zitadel-go/v2/pkg/client/middleware"
|
||||||
"github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/authn"
|
"github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/authn"
|
||||||
pb "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/management"
|
pb "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/management"
|
||||||
user "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/user"
|
user "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/user"
|
||||||
@@ -85,12 +86,27 @@ func newWrappedMachineUserReconciler(client client.Client, refResolver *zitadelv
|
|||||||
|
|
||||||
func (wr *wrappedMachineUserReconciler) Reconcile(ctx context.Context, ztdClient *management.Client) error {
|
func (wr *wrappedMachineUserReconciler) Reconcile(ctx context.Context, ztdClient *management.Client) error {
|
||||||
// TODO: update machine user
|
// TODO: update machine user
|
||||||
zitadel, err := wr.refResolver.ZitadelCluster(ctx, &wr.MachineUser.Spec.ZitadelClusterRef, wr.MachineUser.Namespace)
|
org, err := wr.refResolver.OrganizationRef(ctx, &wr.MachineUser.Spec.OrganizationRef, wr.MachineUser.Namespace)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if wr.MachineUser.Status.UserId != "" {
|
||||||
|
_, err = ztdClient.UpdateMachine(middleware.SetOrgID(ctx, org.Status.OrgId),
|
||||||
|
&pb.UpdateMachineRequest{
|
||||||
|
UserId: wr.MachineUser.Status.UserId,
|
||||||
|
Name: wr.MachineUser.Name,
|
||||||
|
Description: wr.MachineUser.Name,
|
||||||
|
AccessTokenType: user.AccessTokenType(user.AccessTokenType_value[wr.MachineUser.Spec.AccessTokenType]),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if !strings.Contains(err.Error(), "No changes") {
|
||||||
|
return fmt.Errorf("Error updating OIDCApp: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
resp, err := ztdClient.AddMachineUser(ctx,
|
resp, err := ztdClient.AddMachineUser(middleware.SetOrgID(ctx, org.Status.OrgId),
|
||||||
&pb.AddMachineUserRequest{
|
&pb.AddMachineUserRequest{
|
||||||
Name: wr.MachineUser.Name,
|
Name: wr.MachineUser.Name,
|
||||||
UserName: wr.MachineUser.Name,
|
UserName: wr.MachineUser.Name,
|
||||||
@@ -121,17 +137,18 @@ func (wr *wrappedMachineUserReconciler) Reconcile(ctx context.Context, ztdClient
|
|||||||
return fmt.Errorf("Error Adding MachineKey: %v", err)
|
return fmt.Errorf("Error Adding MachineKey: %v", err)
|
||||||
}
|
}
|
||||||
key := types.NamespacedName{
|
key := types.NamespacedName{
|
||||||
Name: wr.MachineUser.Name + "-key-secret",
|
Name: wr.MachineUser.Name + "-machinekey-secret",
|
||||||
Namespace: wr.MachineUser.Namespace,
|
Namespace: wr.MachineUser.Namespace,
|
||||||
}
|
}
|
||||||
secret, err := wr.Builder.BuildSecret(builder.SecretOpts{
|
secret, err := wr.Builder.BuildSecret(
|
||||||
Zitadel: zitadel,
|
builder.SecretOpts{
|
||||||
Key: key,
|
Key: key,
|
||||||
Immutable: true,
|
Immutable: true,
|
||||||
Data: map[string][]byte{
|
Data: map[string][]byte{
|
||||||
"key": respKey.KeyDetails,
|
"key.json": respKey.KeyDetails,
|
||||||
},
|
},
|
||||||
}, wr.MachineUser)
|
}, wr.MachineUser)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error building Secret: %v", err)
|
return fmt.Errorf("error building Secret: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ func (wr *wrappedOIDCAppReconciler) Reconcile(ctx context.Context, ztdClient *ma
|
|||||||
ProjectId: project.Status.ProjectId,
|
ProjectId: project.Status.ProjectId,
|
||||||
AppId: string(wr.OIDCApp.Status.AppId),
|
AppId: string(wr.OIDCApp.Status.AppId),
|
||||||
})
|
})
|
||||||
|
// TODO: fix flow
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Error getting OIDCApp: %v", err)
|
return fmt.Errorf("Error getting OIDCApp: %v", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,10 @@ func newWrappedOrganizationReconciler(client client.Client, refResolver *zitadel
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (wr *wrappedOrganizationReconciler) Reconcile(ctx context.Context, ztdClient *management.Client) error {
|
func (wr *wrappedOrganizationReconciler) Reconcile(ctx context.Context, ztdClient *management.Client) error {
|
||||||
resp, err := ztdClient.AddOrg(ctx, &pb.AddOrgRequest{Name: wr.organization.Name})
|
// TODO: check if org exists first
|
||||||
|
resp, err := ztdClient.AddOrg(ctx, &pb.AddOrgRequest{
|
||||||
|
Name: wr.organization.Name,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if strings.Contains(err.Error(), "AlreadyExists") {
|
if strings.Contains(err.Error(), "AlreadyExists") {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
zitadelv1alpha1 "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/api/v1alpha1"
|
||||||
|
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/admin"
|
||||||
builder "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder"
|
builder "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/builder"
|
||||||
condition "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/condition"
|
condition "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/condition"
|
||||||
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/configuration"
|
"bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/configuration"
|
||||||
@@ -39,9 +40,12 @@ import (
|
|||||||
systemapiaccount "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/systemapi"
|
systemapiaccount "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/systemapi"
|
||||||
zitadelClient "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/zitadel"
|
zitadelClient "bitbucket.org/topmanage-software-engineering/zitadel-k8s-operator/src/pkg/zitadel"
|
||||||
"github.com/hashicorp/go-multierror"
|
"github.com/hashicorp/go-multierror"
|
||||||
|
"github.com/zitadel/zitadel-go/v2/pkg/client/middleware"
|
||||||
"github.com/zitadel/zitadel-go/v2/pkg/client/system"
|
"github.com/zitadel/zitadel-go/v2/pkg/client/system"
|
||||||
authn "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/authn"
|
authn "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/authn"
|
||||||
|
"github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/management"
|
||||||
pb "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/system"
|
pb "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/system"
|
||||||
|
"github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/user"
|
||||||
appsv1 "k8s.io/api/apps/v1"
|
appsv1 "k8s.io/api/apps/v1"
|
||||||
batchv1 "k8s.io/api/batch/v1"
|
batchv1 "k8s.io/api/batch/v1"
|
||||||
corev1 "k8s.io/api/core/v1"
|
corev1 "k8s.io/api/core/v1"
|
||||||
@@ -148,6 +152,14 @@ func (r *ZitadelClusterReconciler) Reconcile(ctx context.Context, req ctrl.Reque
|
|||||||
Name: "DefaultInstance",
|
Name: "DefaultInstance",
|
||||||
Reconcile: r.reconcileDefaultInstance,
|
Reconcile: r.reconcileDefaultInstance,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "InitialAdminSecret",
|
||||||
|
Reconcile: r.reconcileInitialAdminPassword,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "InitialAdmin",
|
||||||
|
Reconcile: r.reconcileInitialHumanUser,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, p := range phases {
|
for _, p := range phases {
|
||||||
@@ -390,8 +402,8 @@ func (r *ZitadelClusterReconciler) reconcileDefaultInstance(ctx context.Context,
|
|||||||
if strings.Contains(err.Error(), "Instance not found") {
|
if strings.Contains(err.Error(), "Instance not found") {
|
||||||
// if Instance doesn't exist, then create and assign secrets
|
// if Instance doesn't exist, then create and assign secrets
|
||||||
resp, err := ztdClient.CreateInstance(ctx, &pb.CreateInstanceRequest{
|
resp, err := ztdClient.CreateInstance(ctx, &pb.CreateInstanceRequest{
|
||||||
InstanceName: "DEFAULT",
|
InstanceName: zitadel.Spec.FirstOrgName,
|
||||||
FirstOrgName: "DEFAULT",
|
FirstOrgName: zitadel.Spec.FirstOrgName,
|
||||||
CustomDomain: zitadel.Spec.Host,
|
CustomDomain: zitadel.Spec.Host,
|
||||||
Owner: &pb.CreateInstanceRequest_Machine_{Machine: &pb.CreateInstanceRequest_Machine{
|
Owner: &pb.CreateInstanceRequest_Machine_{Machine: &pb.CreateInstanceRequest_Machine{
|
||||||
Name: "k8s-operator",
|
Name: "k8s-operator",
|
||||||
@@ -436,6 +448,89 @@ func (r *ZitadelClusterReconciler) reconcileDefaultInstance(ctx context.Context,
|
|||||||
return ctrl.Result{}, nil
|
return ctrl.Result{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ZitadelClusterReconciler) reconcileInitialAdminPassword(ctx context.Context, zitadel *zitadelv1alpha1.ZitadelCluster) (ctrl.Result, error) {
|
||||||
|
secretName := admin.AdminPasswordSecretName(zitadel)
|
||||||
|
key := types.NamespacedName{
|
||||||
|
Name: secretName,
|
||||||
|
Namespace: zitadel.Namespace,
|
||||||
|
}
|
||||||
|
_, err := r.SecretReconciler.ReconcileRandomPassword(ctx, key, systemapiaccount.Key, zitadel)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
return ctrl.Result{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ZitadelClusterReconciler) reconcileInitialHumanUser(ctx context.Context, zitadel *zitadelv1alpha1.ZitadelCluster) (ctrl.Result, error) {
|
||||||
|
managementClient, err := zitadelClient.NewClient(ctx, zitadel, *r.RefResolver)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
defer managementClient.Connection.Close()
|
||||||
|
|
||||||
|
secretName := admin.AdminPasswordSecretName(zitadel)
|
||||||
|
key := types.NamespacedName{
|
||||||
|
Name: secretName,
|
||||||
|
Namespace: zitadel.Namespace,
|
||||||
|
}
|
||||||
|
password, err := r.SecretReconciler.ReconcileRandomPassword(ctx, key, admin.Key, zitadel)
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
org, err := managementClient.GetMyOrg(ctx, &management.GetMyOrgRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, fmt.Errorf("Error getting org: %v", err)
|
||||||
|
}
|
||||||
|
users, err := managementClient.ListUsers(middleware.SetOrgID(ctx, org.Org.Id), &management.ListUsersRequest{})
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, fmt.Errorf("Error getting users: %v", err)
|
||||||
|
}
|
||||||
|
userid := zitadel.Status.InitialAdminId
|
||||||
|
for _, u := range users.Result {
|
||||||
|
if admin.AccountName == u.UserName {
|
||||||
|
userid = u.Id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if userid == "" {
|
||||||
|
resp, err := managementClient.AddHumanUser(middleware.SetOrgID(ctx, org.Org.Id), &management.AddHumanUserRequest{
|
||||||
|
UserName: admin.AccountName,
|
||||||
|
Profile: &management.AddHumanUserRequest_Profile{
|
||||||
|
FirstName: admin.AccountName,
|
||||||
|
LastName: admin.AccountName,
|
||||||
|
NickName: admin.AccountName,
|
||||||
|
DisplayName: admin.AccountName,
|
||||||
|
Gender: user.Gender_GENDER_DIVERSE,
|
||||||
|
PreferredLanguage: "en",
|
||||||
|
},
|
||||||
|
InitialPassword: password,
|
||||||
|
Email: &management.AddHumanUserRequest_Email{
|
||||||
|
Email: "test@test.com",
|
||||||
|
IsEmailVerified: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
userid = resp.UserId
|
||||||
|
if err != nil {
|
||||||
|
return ctrl.Result{}, fmt.Errorf("Error adding human user: %v", err)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
|
||||||
|
if _, err = managementClient.AddOrgMember(middleware.SetOrgID(ctx, org.Org.Id), &management.AddOrgMemberRequest{
|
||||||
|
UserId: userid,
|
||||||
|
Roles: []string{
|
||||||
|
"IAM_OWNER",
|
||||||
|
},
|
||||||
|
}); err != nil {
|
||||||
|
return ctrl.Result{}, fmt.Errorf("Error adding org member: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
patch := client.MergeFrom(zitadel.DeepCopy())
|
||||||
|
zitadel.Status.InitialAdminId = userid
|
||||||
|
return ctrl.Result{}, r.Status().Patch(ctx, zitadel, patch)
|
||||||
|
}
|
||||||
func GetIssuer(zitadel *zitadelv1alpha1.ZitadelCluster) string {
|
func GetIssuer(zitadel *zitadelv1alpha1.ZitadelCluster) string {
|
||||||
scheme := "http"
|
scheme := "http"
|
||||||
if zitadel.Spec.ExternalSecure {
|
if zitadel.Spec.ExternalSecure {
|
||||||
|
|||||||
Reference in New Issue
Block a user