feat: basic functionality implemented
- added Core CRD to manage DB migrations & configuration, PostgREST and GoTrue (auth) - added APIGateway CRD to manage Envoy proxy - added Dashboard CRD to manage (so far) pg-meta and (soon) studio deployments - implemented basic Envoy control plane based on K8s watcher
This commit is contained in:
parent
2fae578618
commit
647f602c79
123 changed files with 12173 additions and 581 deletions
13
api/common.go
Normal file
13
api/common.go
Normal file
|
@ -0,0 +1,13 @@
|
|||
package api
|
||||
|
||||
import (
|
||||
"iter"
|
||||
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"sigs.k8s.io/controller-runtime/pkg/client"
|
||||
)
|
||||
|
||||
type ObjectList[T metav1.Object] interface {
|
||||
client.ObjectList
|
||||
Iter() iter.Seq[T]
|
||||
}
|
95
api/v1alpha1/apigateway_types.go
Normal file
95
api/v1alpha1/apigateway_types.go
Normal file
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
Copyright 2024 Peter Kurfer.
|
||||
|
||||
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 (
|
||||
"iter"
|
||||
"maps"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&APIGateway{}, &APIGatewayList{})
|
||||
}
|
||||
|
||||
type ControlPlaneSpec struct {
|
||||
// Host is the hostname of the envoy control plane endpoint
|
||||
Host string `json:"host"`
|
||||
// Port is the port number of the envoy control plane endpoint - typically this is 18000
|
||||
// +kubebuilder:default=18000
|
||||
// +kubebuilder:validation:Maximum=65535
|
||||
Port uint16 `json:"port"`
|
||||
}
|
||||
|
||||
type EnvoySpec struct {
|
||||
// ControlPlane - configure the control plane where Envoy will retrieve its configuration from
|
||||
ControlPlane *ControlPlaneSpec `json:"controlPlane"`
|
||||
// WorkloadTemplate - customize the Envoy deployment
|
||||
WorkloadTemplate *WorkloadTemplate `json:"workloadTemplate,omitempty"`
|
||||
}
|
||||
|
||||
// APIGatewaySpec defines the desired state of APIGateway.
|
||||
type APIGatewaySpec struct {
|
||||
// Envoy - configure the envoy instance and most importantly the control-plane
|
||||
Envoy *EnvoySpec `json:"envoy"`
|
||||
// JWKSSelector - selector where the JWKS can be retrieved from to enable the API gateway to validate JWTs
|
||||
JWKSSelector *corev1.SecretKeySelector `json:"jwks"`
|
||||
}
|
||||
|
||||
// APIGatewayStatus defines the observed state of APIGateway.
|
||||
type APIGatewayStatus struct{}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
|
||||
// APIGateway is the Schema for the apigateways API.
|
||||
type APIGateway struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec APIGatewaySpec `json:"spec,omitempty"`
|
||||
Status APIGatewayStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
func (g APIGateway) JwksSecretMeta() metav1.ObjectMeta {
|
||||
return metav1.ObjectMeta{
|
||||
Name: g.Spec.JWKSSelector.Name,
|
||||
Namespace: g.Namespace,
|
||||
Labels: maps.Clone(g.Labels),
|
||||
}
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// APIGatewayList contains a list of APIGateway.
|
||||
type APIGatewayList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []APIGateway `json:"items"`
|
||||
}
|
||||
|
||||
func (l APIGatewayList) Iter() iter.Seq[*APIGateway] {
|
||||
return func(yield func(*APIGateway) bool) {
|
||||
for _, gw := range l.Items {
|
||||
if !yield(&gw) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
44
api/v1alpha1/common_types.go
Normal file
44
api/v1alpha1/common_types.go
Normal file
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
Copyright 2024 Peter Kurfer.
|
||||
|
||||
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 (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
)
|
||||
|
||||
type ImageSpec struct {
|
||||
Image string `json:"image,omitempty"`
|
||||
PullPolicy corev1.PullPolicy `json:"pullPolicy,omitempty"`
|
||||
}
|
||||
|
||||
type ContainerTemplate struct {
|
||||
ImageSpec `json:",inline"`
|
||||
ImagePullSecrets []corev1.LocalObjectReference `json:"imagePullSecrets,omitempty"`
|
||||
// SecurityContext -
|
||||
SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty"`
|
||||
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
|
||||
VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty"`
|
||||
AdditionalEnv []corev1.EnvVar `json:"additionalEnv,omitempty"`
|
||||
}
|
||||
|
||||
type WorkloadTemplate struct {
|
||||
Replicas *int32 `json:"replicas,omitempty"`
|
||||
SecurityContext *corev1.PodSecurityContext `json:"securityContext"`
|
||||
AdditionalLabels map[string]string `json:"additionalLabels,omitempty"`
|
||||
// Workload - customize the container template of the workload
|
||||
Workload *ContainerTemplate `json:"workload,omitempty"`
|
||||
}
|
|
@ -19,46 +19,366 @@ package v1alpha1
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"iter"
|
||||
"path"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
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/client"
|
||||
|
||||
"code.icb4dc0.de/prskr/supabase-operator/internal/supabase"
|
||||
)
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Core{}, &CoreList{})
|
||||
}
|
||||
|
||||
var ErrNoSuchSecretValue = errors.New("no such secret value")
|
||||
|
||||
type DatabaseRolesSecrets struct {
|
||||
Admin *corev1.LocalObjectReference `json:"supabaseAdmin,omitempty"`
|
||||
Authenticator *corev1.LocalObjectReference `json:"authenticator,omitempty"`
|
||||
AuthAdmin *corev1.LocalObjectReference `json:"supabaseAuthAdmin,omitempty"`
|
||||
FunctionsAdmin *corev1.LocalObjectReference `json:"supabaseFunctionsAdmin,omitempty"`
|
||||
StorageAdmin *corev1.LocalObjectReference `json:"supabaseStorageAdmin,omitempty"`
|
||||
}
|
||||
|
||||
type DatabaseRoles struct {
|
||||
// SelfManaged - whether the database roles are managed externally
|
||||
// when enabled the operator does not attempt to create secrets, generate passwords or whatsoever for all database roles
|
||||
// i.e. all secrets need to be provided or the instance won't work
|
||||
SelfManaged bool `json:"selfManaged,omitempty"`
|
||||
// Secrets - typed 'map' of secrets for each database role that Supabase needs
|
||||
Secrets DatabaseRolesSecrets `json:"secrets,omitempty"`
|
||||
}
|
||||
|
||||
type Database struct {
|
||||
DSN *string `json:"dsn,omitempty"`
|
||||
DSNFrom *corev1.SecretKeySelector `json:"dsnFrom,omitempty"`
|
||||
DSN *string `json:"dsn,omitempty"`
|
||||
DSNSecretRef *corev1.SecretKeySelector `json:"dsnFrom,omitempty"`
|
||||
Roles DatabaseRoles `json:"roles,omitempty"`
|
||||
}
|
||||
|
||||
func (d Database) GetDSN(ctx context.Context, client client.Client) (string, error) {
|
||||
if d.DSN != nil {
|
||||
return *d.DSN, nil
|
||||
}
|
||||
|
||||
if d.DSNFrom == nil {
|
||||
if d.DSNSecretRef == nil {
|
||||
return "", errors.New("DSN not set")
|
||||
}
|
||||
|
||||
var secret corev1.Secret
|
||||
if err := client.Get(ctx, types.NamespacedName{Name: d.DSNFrom.Name}, &secret); err != nil {
|
||||
if err := client.Get(ctx, types.NamespacedName{Name: d.DSNSecretRef.Name}, &secret); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
data, ok := secret.Data[d.DSNFrom.Key]
|
||||
data, ok := secret.Data[d.DSNSecretRef.Key]
|
||||
if !ok {
|
||||
return "", errors.New("key not found in secret")
|
||||
return "", fmt.Errorf("%w: %s", ErrNoSuchSecretValue, d.DSNSecretRef.Key)
|
||||
}
|
||||
|
||||
return string(data), nil
|
||||
}
|
||||
|
||||
func (d Database) DSNEnv(key string) corev1.EnvVar {
|
||||
return corev1.EnvVar{
|
||||
Name: key,
|
||||
ValueFrom: &corev1.EnvVarSource{
|
||||
SecretKeyRef: d.DSNSecretRef,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type JwtSpec struct {
|
||||
// Secret - JWT HMAC secret in plain text
|
||||
// This is WRITE-ONLY and will be copied to the SecretRef by the defaulter
|
||||
Secret *string `json:"secret,omitempty"`
|
||||
// SecretRef - object reference to the Secret where JWT values are stored
|
||||
SecretRef *corev1.LocalObjectReference `json:"secretRef,omitempty"`
|
||||
// SecretKey - key in secret where to read the JWT HMAC secret from
|
||||
// +kubebuilder:default=secret
|
||||
SecretKey string `json:"secretKey,omitempty"`
|
||||
// JwksKey - key in secret where to read the JWKS from
|
||||
// +kubebuilder:default=jwks.json
|
||||
JwksKey string `json:"jwksKey,omitempty"`
|
||||
// AnonKey - key in secret where to read the anon JWT from
|
||||
// +kubebuilder:default=anon_key
|
||||
AnonKey string `json:"anonKey,omitempty"`
|
||||
// ServiceKey - key in secret where to read the service JWT from
|
||||
// +kubebuilder:default=service_key
|
||||
ServiceKey string `json:"serviceKey,omitempty"`
|
||||
// Expiry - expiration time in seconds for JWTs
|
||||
// +kubebuilder:default=3600
|
||||
Expiry int `json:"expiry,omitempty"`
|
||||
}
|
||||
|
||||
func (s JwtSpec) GetJWTSecret(ctx context.Context, client client.Client) ([]byte, error) {
|
||||
var secret corev1.Secret
|
||||
if err := client.Get(ctx, types.NamespacedName{Name: s.SecretRef.Name}, &secret); err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
value, ok := secret.Data[s.SecretKey]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%w: %s", ErrNoSuchSecretValue, s.SecretKey)
|
||||
}
|
||||
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (s JwtSpec) SecretKeySelector() *corev1.SecretKeySelector {
|
||||
return &corev1.SecretKeySelector{
|
||||
LocalObjectReference: *s.SecretRef,
|
||||
Key: s.SecretKey,
|
||||
}
|
||||
}
|
||||
|
||||
func (s JwtSpec) JwksKeySelector() *corev1.SecretKeySelector {
|
||||
return &corev1.SecretKeySelector{
|
||||
LocalObjectReference: *s.SecretRef,
|
||||
Key: s.JwksKey,
|
||||
}
|
||||
}
|
||||
|
||||
func (s JwtSpec) SecretAsEnv(key string) corev1.EnvVar {
|
||||
return corev1.EnvVar{
|
||||
Name: key,
|
||||
ValueFrom: &corev1.EnvVarSource{
|
||||
SecretKeyRef: &corev1.SecretKeySelector{
|
||||
LocalObjectReference: *s.SecretRef,
|
||||
Key: s.SecretKey,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s JwtSpec) ExpiryAsEnv(key string) corev1.EnvVar {
|
||||
return corev1.EnvVar{
|
||||
Name: key,
|
||||
Value: strconv.Itoa(s.Expiry),
|
||||
}
|
||||
}
|
||||
|
||||
type PostgrestSpec struct {
|
||||
// Schemas - schema where PostgREST is looking for objects (tables, views, functions, ...)
|
||||
// +kubebuilder:default={"public","graphql_public"}
|
||||
Schemas []string `json:"schemas,omitempty"`
|
||||
// ExtraSearchPath - Extra schemas to add to the search_path of every request.
|
||||
// These schemas tables, views and functions don’t get API endpoints, they can only be referred from the database objects inside your db-schemas.
|
||||
// +kubebuilder:default={"public","extensions"}
|
||||
ExtraSearchPath []string `json:"extraSearchPath,omitempty"`
|
||||
// AnonRole - name of the anon role
|
||||
// +kubebuilder:default=anon
|
||||
AnonRole string `json:"anonRole,omitempty"`
|
||||
// MaxRows - maximum number of rows PostgREST will load at a time
|
||||
// +kubebuilder:default=1000
|
||||
MaxRows int `json:"maxRows,omitempty"`
|
||||
// WorkloadTemplate - customize the PostgREST workload
|
||||
WorkloadTemplate *WorkloadTemplate `json:"workloadTemplate,omitempty"`
|
||||
}
|
||||
|
||||
type AuthProviderMeta struct {
|
||||
// Enabled - whether the authentication provider is enabled or not
|
||||
Enabled bool `json:"enabled,omitempty"`
|
||||
}
|
||||
|
||||
func (p *AuthProviderMeta) Vars(provider string) []corev1.EnvVar {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return []corev1.EnvVar{{
|
||||
Name: fmt.Sprintf("GOTRUE_EXTERNAL_%s_ENABLED", strings.ToUpper(provider)),
|
||||
Value: strconv.FormatBool(p.Enabled),
|
||||
}}
|
||||
}
|
||||
|
||||
type EmailAuthSmtpSpec struct {
|
||||
Host string `json:"host"`
|
||||
Port uint16 `json:"port"`
|
||||
MaxFrequency *uint `json:"maxFrequency,omitempty"`
|
||||
CredentialsFrom *corev1.LocalObjectReference `json:"credentialsFrom"`
|
||||
}
|
||||
|
||||
type EmailAuthProvider struct {
|
||||
AuthProviderMeta `json:",inline"`
|
||||
AdminEmail string `json:"adminEmail"`
|
||||
SenderName *string `json:"senderName,omitempty"`
|
||||
Autoconfirm *bool `json:"autoconfirmEmail,omitempty"`
|
||||
SubjectsInvite string `json:"subjectsInvite,omitempty"`
|
||||
SubjectsConfirmation string `json:"subjectsConfirmation,omitempty"`
|
||||
SmtpSpec *EmailAuthSmtpSpec `json:"smtpSpec"`
|
||||
}
|
||||
|
||||
func (p *EmailAuthProvider) Vars(apiExternalURL string) []corev1.EnvVar {
|
||||
if p == nil || p.SmtpSpec == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
svcDefaults := supabase.ServiceConfig.Auth.Defaults
|
||||
|
||||
vars := []corev1.EnvVar{
|
||||
{Name: "GOTRUE_SMTP_HOST", Value: p.SmtpSpec.Host},
|
||||
{Name: "GOTRUE_SMTP_PORT", Value: strconv.FormatUint(uint64(p.SmtpSpec.Port), 10)},
|
||||
{
|
||||
Name: "GOTRUE_SMTP_USER",
|
||||
ValueFrom: &corev1.EnvVarSource{
|
||||
SecretKeyRef: &corev1.SecretKeySelector{
|
||||
LocalObjectReference: *p.SmtpSpec.CredentialsFrom,
|
||||
Key: corev1.BasicAuthUsernameKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "GOTRUE_SMTP_PASS",
|
||||
ValueFrom: &corev1.EnvVarSource{
|
||||
SecretKeyRef: &corev1.SecretKeySelector{
|
||||
LocalObjectReference: *p.SmtpSpec.CredentialsFrom,
|
||||
Key: corev1.BasicAuthPasswordKey,
|
||||
},
|
||||
},
|
||||
},
|
||||
{Name: "GOTRUE_SMTP_ADMIN_EMAIL", Value: p.AdminEmail},
|
||||
{Name: "MAILER_URLPATHS_INVITE", Value: path.Join(apiExternalURL, svcDefaults.MailerUrlPathsInvite)},
|
||||
{Name: "MAILER_URLPATHS_CONFIRMATION", Value: path.Join(apiExternalURL, svcDefaults.MailerUrlPathsConfirmation)},
|
||||
{Name: "MAILER_URLPATHS_RECOVERY", Value: path.Join(apiExternalURL, svcDefaults.MailerUrlPathsRecovery)},
|
||||
{Name: "MAILER_URLPATHS_EMAIL_CHANGE", Value: path.Join(apiExternalURL, svcDefaults.MailerUrlPathsEmailChange)},
|
||||
}
|
||||
|
||||
if p.SubjectsInvite != "" {
|
||||
vars = append(vars, corev1.EnvVar{Name: "MAILER_SUBJECTS_INVITE", Value: p.SubjectsInvite})
|
||||
}
|
||||
|
||||
return vars
|
||||
}
|
||||
|
||||
type PhoneAuthProvider struct {
|
||||
AuthProviderMeta `json:",inline"`
|
||||
}
|
||||
|
||||
func (p *PhoneAuthProvider) Vars() []corev1.EnvVar {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return []corev1.EnvVar{}
|
||||
}
|
||||
|
||||
type OAuthProvider struct {
|
||||
ClientID string `json:"clientID"`
|
||||
ClientSecretRef *corev1.SecretKeySelector `json:"clientSecretRef"`
|
||||
URL string `json:"url,omitempty"`
|
||||
}
|
||||
|
||||
func (p *OAuthProvider) Vars(provider, apiExternalURL string) []corev1.EnvVar {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
vars := []corev1.EnvVar{
|
||||
{
|
||||
Name: fmt.Sprintf("GOTRUE_EXTERNAL_%s_CLIENT_ID", strings.ToUpper(provider)),
|
||||
Value: p.ClientID,
|
||||
},
|
||||
{
|
||||
Name: fmt.Sprintf("GOTRUE_EXTERNAL_%s_REDIRECT_URI", strings.ToUpper(provider)),
|
||||
Value: path.Join(apiExternalURL, "/auth/v1/callback"),
|
||||
},
|
||||
{
|
||||
Name: fmt.Sprintf("GOTRUE_EXTERNAL_%s_SECRET", strings.ToUpper(provider)),
|
||||
ValueFrom: &corev1.EnvVarSource{
|
||||
SecretKeyRef: p.ClientSecretRef,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
if p.URL != "" {
|
||||
vars = append(vars, corev1.EnvVar{
|
||||
Name: fmt.Sprintf("GOTRUE_EXTERNAL_%s_URL", strings.ToUpper(provider)),
|
||||
Value: p.URL,
|
||||
})
|
||||
}
|
||||
|
||||
return vars
|
||||
}
|
||||
|
||||
type AzureAuthProvider struct {
|
||||
AuthProviderMeta `json:",inline"`
|
||||
OAuthProvider `json:",inline"`
|
||||
}
|
||||
|
||||
func (p *AzureAuthProvider) Vars(apiExternalURL string) []corev1.EnvVar {
|
||||
const providerName = "AZURE"
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return slices.Concat(
|
||||
p.AuthProviderMeta.Vars(providerName),
|
||||
p.OAuthProvider.Vars(providerName, apiExternalURL),
|
||||
)
|
||||
}
|
||||
|
||||
type GithubAuthProvider struct {
|
||||
AuthProviderMeta `json:",inline"`
|
||||
OAuthProvider `json:",inline"`
|
||||
}
|
||||
|
||||
func (p *GithubAuthProvider) Vars(apiExternalURL string) []corev1.EnvVar {
|
||||
const providerName = "GITHUB"
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return slices.Concat(
|
||||
p.AuthProviderMeta.Vars(providerName),
|
||||
p.OAuthProvider.Vars(providerName, apiExternalURL),
|
||||
)
|
||||
}
|
||||
|
||||
type AuthProviders struct {
|
||||
Email *EmailAuthProvider `json:"email,omitempty"`
|
||||
Azure *AzureAuthProvider `json:"azure,omitempty"`
|
||||
Github *GithubAuthProvider `json:"github,omitempty"`
|
||||
Phone *PhoneAuthProvider `json:"phone,omitempty"`
|
||||
}
|
||||
|
||||
func (p *AuthProviders) Vars(apiExternalURL string) []corev1.EnvVar {
|
||||
if p == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return slices.Concat(
|
||||
p.Email.Vars(apiExternalURL),
|
||||
p.Azure.Vars(apiExternalURL),
|
||||
p.Github.Vars(apiExternalURL),
|
||||
p.Phone.Vars(),
|
||||
)
|
||||
}
|
||||
|
||||
type AuthSpec struct {
|
||||
// APIExternalURL is referring to the URL where Supabase API will be available
|
||||
// Typically this is the ingress of the API gateway
|
||||
APIExternalURL string `json:"externalUrl"`
|
||||
// SiteURL is referring to the URL of the (frontend) application
|
||||
// In most Kubernetes scenarios this is the same as the APIExternalURL with a different path handler in the ingress
|
||||
SiteURL string `json:"siteUrl"`
|
||||
AdditionalRedirectUrls []string `json:"additionalRedirectUrls,omitempty"`
|
||||
DisableSignup *bool `json:"disableSignup,omitempty"`
|
||||
AnonymousUsersEnabled *bool `json:"anonymousUsersEnabled,omitempty"`
|
||||
Providers *AuthProviders `json:"providers,omitempty"`
|
||||
WorkloadTemplate *WorkloadTemplate `json:"workloadTemplate,omitempty"`
|
||||
EmailSignupDisabled *bool `json:"emailSignupDisabled,omitempty"`
|
||||
}
|
||||
|
||||
// CoreSpec defines the desired state of Core.
|
||||
type CoreSpec struct {
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
|
||||
Database Database `json:"database,omitempty"`
|
||||
JWT *JwtSpec `json:"jwt,omitempty"`
|
||||
Database Database `json:"database,omitempty"`
|
||||
Postgrest PostgrestSpec `json:"postgrest,omitempty"`
|
||||
Auth *AuthSpec `json:"auth,omitempty"`
|
||||
}
|
||||
|
||||
type MigrationStatus map[string]int64
|
||||
|
@ -72,11 +392,26 @@ func (s MigrationStatus) Record(name string) {
|
|||
s[name] = time.Now().UTC().UnixMilli()
|
||||
}
|
||||
|
||||
type DatabaseStatus struct {
|
||||
AppliedMigrations MigrationStatus `json:"appliedMigrations,omitempty"`
|
||||
Roles map[string][]byte `json:"roles,omitempty"`
|
||||
}
|
||||
|
||||
type CoreConditionType string
|
||||
|
||||
type CoreCondition struct {
|
||||
Type CoreConditionType `json:"type"`
|
||||
Status corev1.ConditionStatus `json:"status"`
|
||||
LastProbeTime metav1.Time `json:"lastProbeTime,omitempty"`
|
||||
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty"`
|
||||
Reason string `json:"reason,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// CoreStatus defines the observed state of Core.
|
||||
type CoreStatus struct {
|
||||
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
|
||||
// Important: Run "make" to regenerate code after modifying this file
|
||||
AppliedMigrations MigrationStatus `json:"appliedMigrations,omitempty"`
|
||||
Database DatabaseStatus `json:"database,omitempty"`
|
||||
Conditions []CoreCondition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
@ -100,6 +435,12 @@ type CoreList struct {
|
|||
Items []Core `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Core{}, &CoreList{})
|
||||
func (l CoreList) Iter() iter.Seq[*Core] {
|
||||
return func(yield func(*Core) bool) {
|
||||
for _, c := range l.Items {
|
||||
if !yield(&c) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
96
api/v1alpha1/dashboard_types.go
Normal file
96
api/v1alpha1/dashboard_types.go
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
Copyright 2024 Peter Kurfer.
|
||||
|
||||
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 (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
type StudioSpec struct {
|
||||
// WorkloadTemplate - customize the studio deployment
|
||||
WorkloadTemplate *WorkloadTemplate `json:"workloadTemplate,omitempty"`
|
||||
}
|
||||
|
||||
type PGMetaSpec struct {
|
||||
// WorkloadTemplate - customize the pg-meta deployment
|
||||
WorkloadTemplate *WorkloadTemplate `json:"workloadTemplate,omitempty"`
|
||||
}
|
||||
|
||||
type DashboardDbSpec struct {
|
||||
Host string `json:"host"`
|
||||
// Port - Database port, typically 5432
|
||||
// +kubebuilder:default=5432
|
||||
Port int `json:"port,omitempty"`
|
||||
DBName string `json:"dbName"`
|
||||
// DBCredentialsRef - reference to a Secret key where the DB credentials can be retrieved from
|
||||
// Credentials need to be stored in basic auth form
|
||||
DBCredentialsRef *corev1.LocalObjectReference `json:"dbCredentialsRef"`
|
||||
}
|
||||
|
||||
func (s DashboardDbSpec) UserRef() *corev1.SecretKeySelector {
|
||||
return &corev1.SecretKeySelector{
|
||||
LocalObjectReference: *s.DBCredentialsRef,
|
||||
Key: corev1.BasicAuthUsernameKey,
|
||||
}
|
||||
}
|
||||
|
||||
func (s DashboardDbSpec) PasswordRef() *corev1.SecretKeySelector {
|
||||
return &corev1.SecretKeySelector{
|
||||
LocalObjectReference: *s.DBCredentialsRef,
|
||||
Key: corev1.BasicAuthPasswordKey,
|
||||
}
|
||||
}
|
||||
|
||||
// DashboardSpec defines the desired state of Dashboard.
|
||||
type DashboardSpec struct {
|
||||
DBSpec *DashboardDbSpec `json:"db"`
|
||||
// PGMeta
|
||||
// +kubebuilder:default={}
|
||||
PGMeta *PGMetaSpec `json:"pgMeta,omitempty"`
|
||||
// Studio
|
||||
// +kubebuilder:default={}
|
||||
Studio *StudioSpec `json:"studio,omitempty"`
|
||||
}
|
||||
|
||||
// DashboardStatus defines the observed state of Dashboard.
|
||||
type DashboardStatus struct{}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
|
||||
// Dashboard is the Schema for the dashboards API.
|
||||
type Dashboard struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec DashboardSpec `json:"spec,omitempty"`
|
||||
Status DashboardStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// DashboardList contains a list of Dashboard.
|
||||
type DashboardList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []Dashboard `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&Dashboard{}, &DashboardList{})
|
||||
}
|
|
@ -21,15 +21,283 @@ limitations under the License.
|
|||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/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 *APIGateway) DeepCopyInto(out *APIGateway) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGateway.
|
||||
func (in *APIGateway) DeepCopy() *APIGateway {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(APIGateway)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *APIGateway) 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 *APIGatewayList) DeepCopyInto(out *APIGatewayList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]APIGateway, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGatewayList.
|
||||
func (in *APIGatewayList) DeepCopy() *APIGatewayList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(APIGatewayList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *APIGatewayList) 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 *APIGatewaySpec) DeepCopyInto(out *APIGatewaySpec) {
|
||||
*out = *in
|
||||
if in.Envoy != nil {
|
||||
in, out := &in.Envoy, &out.Envoy
|
||||
*out = new(EnvoySpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.JWKSSelector != nil {
|
||||
in, out := &in.JWKSSelector, &out.JWKSSelector
|
||||
*out = new(v1.SecretKeySelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGatewaySpec.
|
||||
func (in *APIGatewaySpec) DeepCopy() *APIGatewaySpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(APIGatewaySpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *APIGatewayStatus) DeepCopyInto(out *APIGatewayStatus) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new APIGatewayStatus.
|
||||
func (in *APIGatewayStatus) DeepCopy() *APIGatewayStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(APIGatewayStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AuthProviderMeta) DeepCopyInto(out *AuthProviderMeta) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthProviderMeta.
|
||||
func (in *AuthProviderMeta) DeepCopy() *AuthProviderMeta {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AuthProviderMeta)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AuthProviders) DeepCopyInto(out *AuthProviders) {
|
||||
*out = *in
|
||||
if in.Email != nil {
|
||||
in, out := &in.Email, &out.Email
|
||||
*out = new(EmailAuthProvider)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Azure != nil {
|
||||
in, out := &in.Azure, &out.Azure
|
||||
*out = new(AzureAuthProvider)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Github != nil {
|
||||
in, out := &in.Github, &out.Github
|
||||
*out = new(GithubAuthProvider)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Phone != nil {
|
||||
in, out := &in.Phone, &out.Phone
|
||||
*out = new(PhoneAuthProvider)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthProviders.
|
||||
func (in *AuthProviders) DeepCopy() *AuthProviders {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AuthProviders)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AuthSpec) DeepCopyInto(out *AuthSpec) {
|
||||
*out = *in
|
||||
if in.AdditionalRedirectUrls != nil {
|
||||
in, out := &in.AdditionalRedirectUrls, &out.AdditionalRedirectUrls
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.DisableSignup != nil {
|
||||
in, out := &in.DisableSignup, &out.DisableSignup
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.AnonymousUsersEnabled != nil {
|
||||
in, out := &in.AnonymousUsersEnabled, &out.AnonymousUsersEnabled
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.Providers != nil {
|
||||
in, out := &in.Providers, &out.Providers
|
||||
*out = new(AuthProviders)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.WorkloadTemplate != nil {
|
||||
in, out := &in.WorkloadTemplate, &out.WorkloadTemplate
|
||||
*out = new(WorkloadTemplate)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.EmailSignupDisabled != nil {
|
||||
in, out := &in.EmailSignupDisabled, &out.EmailSignupDisabled
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthSpec.
|
||||
func (in *AuthSpec) DeepCopy() *AuthSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AuthSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *AzureAuthProvider) DeepCopyInto(out *AzureAuthProvider) {
|
||||
*out = *in
|
||||
out.AuthProviderMeta = in.AuthProviderMeta
|
||||
in.OAuthProvider.DeepCopyInto(&out.OAuthProvider)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AzureAuthProvider.
|
||||
func (in *AzureAuthProvider) DeepCopy() *AzureAuthProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(AzureAuthProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ContainerTemplate) DeepCopyInto(out *ContainerTemplate) {
|
||||
*out = *in
|
||||
out.ImageSpec = in.ImageSpec
|
||||
if in.ImagePullSecrets != nil {
|
||||
in, out := &in.ImagePullSecrets, &out.ImagePullSecrets
|
||||
*out = make([]v1.LocalObjectReference, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.SecurityContext != nil {
|
||||
in, out := &in.SecurityContext, &out.SecurityContext
|
||||
*out = new(v1.SecurityContext)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.Resources.DeepCopyInto(&out.Resources)
|
||||
if in.VolumeMounts != nil {
|
||||
in, out := &in.VolumeMounts, &out.VolumeMounts
|
||||
*out = make([]v1.VolumeMount, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.AdditionalEnv != nil {
|
||||
in, out := &in.AdditionalEnv, &out.AdditionalEnv
|
||||
*out = make([]v1.EnvVar, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ContainerTemplate.
|
||||
func (in *ContainerTemplate) DeepCopy() *ContainerTemplate {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ContainerTemplate)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ControlPlaneSpec) DeepCopyInto(out *ControlPlaneSpec) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneSpec.
|
||||
func (in *ControlPlaneSpec) DeepCopy() *ControlPlaneSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ControlPlaneSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Core) DeepCopyInto(out *Core) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
out.Spec = in.Spec
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
|
@ -51,6 +319,23 @@ func (in *Core) DeepCopyObject() runtime.Object {
|
|||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CoreCondition) DeepCopyInto(out *CoreCondition) {
|
||||
*out = *in
|
||||
in.LastProbeTime.DeepCopyInto(&out.LastProbeTime)
|
||||
in.LastTransitionTime.DeepCopyInto(&out.LastTransitionTime)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CoreCondition.
|
||||
func (in *CoreCondition) DeepCopy() *CoreCondition {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(CoreCondition)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CoreList) DeepCopyInto(out *CoreList) {
|
||||
*out = *in
|
||||
|
@ -86,7 +371,18 @@ func (in *CoreList) DeepCopyObject() runtime.Object {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CoreSpec) DeepCopyInto(out *CoreSpec) {
|
||||
*out = *in
|
||||
out.Database = in.Database
|
||||
if in.JWT != nil {
|
||||
in, out := &in.JWT, &out.JWT
|
||||
*out = new(JwtSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.Database.DeepCopyInto(&out.Database)
|
||||
in.Postgrest.DeepCopyInto(&out.Postgrest)
|
||||
if in.Auth != nil {
|
||||
in, out := &in.Auth, &out.Auth
|
||||
*out = new(AuthSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CoreSpec.
|
||||
|
@ -102,11 +398,12 @@ func (in *CoreSpec) DeepCopy() *CoreSpec {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *CoreStatus) DeepCopyInto(out *CoreStatus) {
|
||||
*out = *in
|
||||
if in.AppliedMigrations != nil {
|
||||
in, out := &in.AppliedMigrations, &out.AppliedMigrations
|
||||
*out = make(map[string]uint64, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
in.Database.DeepCopyInto(&out.Database)
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]CoreCondition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,9 +418,144 @@ func (in *CoreStatus) DeepCopy() *CoreStatus {
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Dashboard) DeepCopyInto(out *Dashboard) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
out.Status = in.Status
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Dashboard.
|
||||
func (in *Dashboard) DeepCopy() *Dashboard {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(Dashboard)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *Dashboard) 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 *DashboardDbSpec) DeepCopyInto(out *DashboardDbSpec) {
|
||||
*out = *in
|
||||
if in.DBCredentialsRef != nil {
|
||||
in, out := &in.DBCredentialsRef, &out.DBCredentialsRef
|
||||
*out = new(v1.LocalObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardDbSpec.
|
||||
func (in *DashboardDbSpec) DeepCopy() *DashboardDbSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DashboardDbSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DashboardList) DeepCopyInto(out *DashboardList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]Dashboard, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardList.
|
||||
func (in *DashboardList) DeepCopy() *DashboardList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DashboardList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *DashboardList) 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 *DashboardSpec) DeepCopyInto(out *DashboardSpec) {
|
||||
*out = *in
|
||||
if in.DBSpec != nil {
|
||||
in, out := &in.DBSpec, &out.DBSpec
|
||||
*out = new(DashboardDbSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.PGMeta != nil {
|
||||
in, out := &in.PGMeta, &out.PGMeta
|
||||
*out = new(PGMetaSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.Studio != nil {
|
||||
in, out := &in.Studio, &out.Studio
|
||||
*out = new(StudioSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardSpec.
|
||||
func (in *DashboardSpec) DeepCopy() *DashboardSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DashboardSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DashboardStatus) DeepCopyInto(out *DashboardStatus) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DashboardStatus.
|
||||
func (in *DashboardStatus) DeepCopy() *DashboardStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DashboardStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *Database) DeepCopyInto(out *Database) {
|
||||
*out = *in
|
||||
if in.DSN != nil {
|
||||
in, out := &in.DSN, &out.DSN
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.DSNSecretRef != nil {
|
||||
in, out := &in.DSNSecretRef, &out.DSNSecretRef
|
||||
*out = new(v1.SecretKeySelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
in.Roles.DeepCopyInto(&out.Roles)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Database.
|
||||
|
@ -135,3 +567,399 @@ func (in *Database) DeepCopy() *Database {
|
|||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DatabaseRoles) DeepCopyInto(out *DatabaseRoles) {
|
||||
*out = *in
|
||||
in.Secrets.DeepCopyInto(&out.Secrets)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatabaseRoles.
|
||||
func (in *DatabaseRoles) DeepCopy() *DatabaseRoles {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DatabaseRoles)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DatabaseRolesSecrets) DeepCopyInto(out *DatabaseRolesSecrets) {
|
||||
*out = *in
|
||||
if in.Admin != nil {
|
||||
in, out := &in.Admin, &out.Admin
|
||||
*out = new(v1.LocalObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.Authenticator != nil {
|
||||
in, out := &in.Authenticator, &out.Authenticator
|
||||
*out = new(v1.LocalObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.AuthAdmin != nil {
|
||||
in, out := &in.AuthAdmin, &out.AuthAdmin
|
||||
*out = new(v1.LocalObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.FunctionsAdmin != nil {
|
||||
in, out := &in.FunctionsAdmin, &out.FunctionsAdmin
|
||||
*out = new(v1.LocalObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
if in.StorageAdmin != nil {
|
||||
in, out := &in.StorageAdmin, &out.StorageAdmin
|
||||
*out = new(v1.LocalObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatabaseRolesSecrets.
|
||||
func (in *DatabaseRolesSecrets) DeepCopy() *DatabaseRolesSecrets {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DatabaseRolesSecrets)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *DatabaseStatus) DeepCopyInto(out *DatabaseStatus) {
|
||||
*out = *in
|
||||
if in.AppliedMigrations != nil {
|
||||
in, out := &in.AppliedMigrations, &out.AppliedMigrations
|
||||
*out = make(MigrationStatus, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Roles != nil {
|
||||
in, out := &in.Roles, &out.Roles
|
||||
*out = make(map[string][]byte, len(*in))
|
||||
for key, val := range *in {
|
||||
var outVal []byte
|
||||
if val == nil {
|
||||
(*out)[key] = nil
|
||||
} else {
|
||||
inVal := (*in)[key]
|
||||
in, out := &inVal, &outVal
|
||||
*out = make([]byte, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
(*out)[key] = outVal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatabaseStatus.
|
||||
func (in *DatabaseStatus) DeepCopy() *DatabaseStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(DatabaseStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *EmailAuthProvider) DeepCopyInto(out *EmailAuthProvider) {
|
||||
*out = *in
|
||||
out.AuthProviderMeta = in.AuthProviderMeta
|
||||
if in.SenderName != nil {
|
||||
in, out := &in.SenderName, &out.SenderName
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Autoconfirm != nil {
|
||||
in, out := &in.Autoconfirm, &out.Autoconfirm
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
if in.SmtpSpec != nil {
|
||||
in, out := &in.SmtpSpec, &out.SmtpSpec
|
||||
*out = new(EmailAuthSmtpSpec)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmailAuthProvider.
|
||||
func (in *EmailAuthProvider) DeepCopy() *EmailAuthProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(EmailAuthProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *EmailAuthSmtpSpec) DeepCopyInto(out *EmailAuthSmtpSpec) {
|
||||
*out = *in
|
||||
if in.MaxFrequency != nil {
|
||||
in, out := &in.MaxFrequency, &out.MaxFrequency
|
||||
*out = new(uint)
|
||||
**out = **in
|
||||
}
|
||||
if in.CredentialsFrom != nil {
|
||||
in, out := &in.CredentialsFrom, &out.CredentialsFrom
|
||||
*out = new(v1.LocalObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EmailAuthSmtpSpec.
|
||||
func (in *EmailAuthSmtpSpec) DeepCopy() *EmailAuthSmtpSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(EmailAuthSmtpSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *EnvoySpec) DeepCopyInto(out *EnvoySpec) {
|
||||
*out = *in
|
||||
if in.ControlPlane != nil {
|
||||
in, out := &in.ControlPlane, &out.ControlPlane
|
||||
*out = new(ControlPlaneSpec)
|
||||
**out = **in
|
||||
}
|
||||
if in.WorkloadTemplate != nil {
|
||||
in, out := &in.WorkloadTemplate, &out.WorkloadTemplate
|
||||
*out = new(WorkloadTemplate)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EnvoySpec.
|
||||
func (in *EnvoySpec) DeepCopy() *EnvoySpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(EnvoySpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GithubAuthProvider) DeepCopyInto(out *GithubAuthProvider) {
|
||||
*out = *in
|
||||
out.AuthProviderMeta = in.AuthProviderMeta
|
||||
in.OAuthProvider.DeepCopyInto(&out.OAuthProvider)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GithubAuthProvider.
|
||||
func (in *GithubAuthProvider) DeepCopy() *GithubAuthProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(GithubAuthProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ImageSpec) DeepCopyInto(out *ImageSpec) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ImageSpec.
|
||||
func (in *ImageSpec) DeepCopy() *ImageSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ImageSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *JwtSpec) DeepCopyInto(out *JwtSpec) {
|
||||
*out = *in
|
||||
if in.Secret != nil {
|
||||
in, out := &in.Secret, &out.Secret
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.SecretRef != nil {
|
||||
in, out := &in.SecretRef, &out.SecretRef
|
||||
*out = new(v1.LocalObjectReference)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JwtSpec.
|
||||
func (in *JwtSpec) DeepCopy() *JwtSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(JwtSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in MigrationStatus) DeepCopyInto(out *MigrationStatus) {
|
||||
{
|
||||
in := &in
|
||||
*out = make(MigrationStatus, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MigrationStatus.
|
||||
func (in MigrationStatus) DeepCopy() MigrationStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(MigrationStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return *out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OAuthProvider) DeepCopyInto(out *OAuthProvider) {
|
||||
*out = *in
|
||||
if in.ClientSecretRef != nil {
|
||||
in, out := &in.ClientSecretRef, &out.ClientSecretRef
|
||||
*out = new(v1.SecretKeySelector)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OAuthProvider.
|
||||
func (in *OAuthProvider) DeepCopy() *OAuthProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OAuthProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PGMetaSpec) DeepCopyInto(out *PGMetaSpec) {
|
||||
*out = *in
|
||||
if in.WorkloadTemplate != nil {
|
||||
in, out := &in.WorkloadTemplate, &out.WorkloadTemplate
|
||||
*out = new(WorkloadTemplate)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PGMetaSpec.
|
||||
func (in *PGMetaSpec) DeepCopy() *PGMetaSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PGMetaSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PhoneAuthProvider) DeepCopyInto(out *PhoneAuthProvider) {
|
||||
*out = *in
|
||||
out.AuthProviderMeta = in.AuthProviderMeta
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PhoneAuthProvider.
|
||||
func (in *PhoneAuthProvider) DeepCopy() *PhoneAuthProvider {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PhoneAuthProvider)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *PostgrestSpec) DeepCopyInto(out *PostgrestSpec) {
|
||||
*out = *in
|
||||
if in.Schemas != nil {
|
||||
in, out := &in.Schemas, &out.Schemas
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.ExtraSearchPath != nil {
|
||||
in, out := &in.ExtraSearchPath, &out.ExtraSearchPath
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.WorkloadTemplate != nil {
|
||||
in, out := &in.WorkloadTemplate, &out.WorkloadTemplate
|
||||
*out = new(WorkloadTemplate)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PostgrestSpec.
|
||||
func (in *PostgrestSpec) DeepCopy() *PostgrestSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(PostgrestSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *StudioSpec) DeepCopyInto(out *StudioSpec) {
|
||||
*out = *in
|
||||
if in.WorkloadTemplate != nil {
|
||||
in, out := &in.WorkloadTemplate, &out.WorkloadTemplate
|
||||
*out = new(WorkloadTemplate)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StudioSpec.
|
||||
func (in *StudioSpec) DeepCopy() *StudioSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(StudioSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *WorkloadTemplate) DeepCopyInto(out *WorkloadTemplate) {
|
||||
*out = *in
|
||||
if in.Replicas != nil {
|
||||
in, out := &in.Replicas, &out.Replicas
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.SecurityContext != nil {
|
||||
in, out := &in.SecurityContext, &out.SecurityContext
|
||||
*out = new(v1.PodSecurityContext)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
if in.AdditionalLabels != nil {
|
||||
in, out := &in.AdditionalLabels, &out.AdditionalLabels
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Workload != nil {
|
||||
in, out := &in.Workload, &out.Workload
|
||||
*out = new(ContainerTemplate)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadTemplate.
|
||||
func (in *WorkloadTemplate) DeepCopy() *WorkloadTemplate {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(WorkloadTemplate)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue