Documentation
¶
Index ¶
- Constants
- Variables
- func DefaultValues(stepName string) map[string]any
- func SSOSecretName(clientID string) string
- func StepForRelease(releaseName string) string
- type ChartSpec
- type HelmInstaller
- func (h *HelmInstaller) GetValues(ctx context.Context, releaseName, namespace string) (map[string]any, error)
- func (h *HelmInstaller) Install(ctx context.Context, req port.HelmInstallRequest) (*port.HelmInstallResult, error)
- func (h *HelmInstaller) ListReleases(ctx context.Context, namespace string) ([]port.ReleaseInfo, error)
- func (h *HelmInstaller) Status(ctx context.Context, releaseName, namespace string) (*port.HelmInstallResult, error)
- func (h *HelmInstaller) Uninstall(ctx context.Context, releaseName, namespace string) error
- func (h *HelmInstaller) Upgrade(ctx context.Context, req port.HelmUpgradeRequest) (*port.HelmUpgradeResult, error)
- type ManagedSecret
- type Orchestrator
- func (o *Orchestrator) ExecuteStep(ctx context.Context, stackID, step, phase string) error
- func (o *Orchestrator) InstallExternalSecrets(ctx context.Context, namespace string) error
- func (o *Orchestrator) IsStepEnabled(step string) bool
- func (o *Orchestrator) PreflightNamespace(ctx context.Context, namespace string) error
- func (o *Orchestrator) ProvisionSecrets(ctx context.Context, namespace, env, orgID string, writer SecretWriter) error
- func (o *Orchestrator) ResumeFromStep(stackID, step string)
- func (o *Orchestrator) RevokeOpenBaoRootToken(ctx context.Context, namespace string) error
- func (o *Orchestrator) RollbackDeployment(ctx context.Context, stackID string) error
- func (o *Orchestrator) SetNamespace(namespace string)
- func (o *Orchestrator) SetSSOProvisionerFactory(factory port.SSOProvisionerFactory)
- func (o *Orchestrator) SetSecretScope(env, orgID string)
- func (o *Orchestrator) SetStackConfig(config domain.StackConfig)
- func (o *Orchestrator) StartStepRuntimeTail(ctx context.Context, stackID, step string, emit func(level, message string)) (stop func())
- func (o *Orchestrator) StepRuntimeLogs(ctx context.Context, stackID, step string) (infos []string, warns []string)
- func (o *Orchestrator) VerifyDeployment(ctx context.Context, stackID string) error
- type OrchestratorOption
- func WithHelmStepMetadataRepository(repo port.HelmStepMetadataRepository) OrchestratorOption
- func WithImageProjectName(name string) OrchestratorOption
- func WithResourceDefaultRepository(repo port.ResourceDefaultRepository) OrchestratorOption
- func WithSharedClusterScopedComponents(enabled bool) OrchestratorOption
- func WithToolOIDCIssuer(issuer string) OrchestratorOption
- type RollbackManager
- type SecretEntry
- type SecretWriter
Constants ¶
const ( // ESOChartName / ESOChartRepo / ESOChartVersion 은 공식 External Secrets // Operator 차트다. 컨트롤러·웹훅·cert-controller 를 코드 수정 없이 그대로 // 사용하며, Nullus 가 작성하는 것은 SecretStore/ExternalSecret 뿐이다. ESOChartName = "external-secrets" ESOChartRepo = "https://charts.external-secrets.io" ESOChartVersion = "2.7.0" // ESOSecretStoreName 은 스택 네임스페이스에 만드는 SecretStore 이름이다. // 스택이 단일 네임스페이스에 설치되므로 ClusterSecretStore 는 쓰지 않는다. ESOSecretStoreName = "nullus-openbao" )
const ( // OpenBaoKVMount 는 KV v2 시크릿 엔진의 마운트 이름이다. // // 경로 규약(`kv/nullus/{env}/{org}/...`)과 실제 마운트를 일치시키기 위해 // "secret" 이 아니라 "kv" 로 마운트한다. 운영 모드는 dev 모드와 달리 // 엔진이 자동 마운트되지 않으므로 부트스트랩에서 명시적으로 활성화한다. OpenBaoKVMount = "kv" // OpenBao Kubernetes Auth role 이름 OpenBaoControllerRole = "nullus-controller" OpenBaoESORole = "nullus-eso" // role 에 바인딩되는 ServiceAccount 이름 OpenBaoControllerServiceAccount = "nullus-controller" OpenBaoESOServiceAccount = "external-secrets" )
const ( // OpenBaoKeyShares / OpenBaoKeyThreshold 기본값은 1/1 이다. // auto-unseal 구성에서는 threshold 를 채우는 데 필요한 모든 조각이 // 어차피 같은 Secret 안에 있으므로, 분할이 런타임 보안을 높이지 않고 // 복잡도만 늘린다. 오프라인 백업본을 여러 관리자에게 나누려는 조직만 // 이 값을 올리면 된다. OpenBaoKeyThreshold = 1 )
const ( // OpenBaoImageRepository / OpenBaoImageTag 는 OpenBao 이미지를 고정한다. // 에어갭 번들은 재현 가능해야 하므로 latest 같은 mutable 태그를 쓰지 않는다. OpenBaoImageRepository = "openbao/openbao" OpenBaoImageTag = "2.5.5" // OpenBaoKubectlImage 는 init Job 이 K8s Secret 을 만들 때 사용하는 이미지다. // OpenBao 이미지에는 kubectl 이 없어 별도 컨테이너가 필요하다. OpenBaoKubectlImage = "docker.io/bitnamilegacy/kubectl:1.33.4" // OpenBaoUnsealKeysSecret 은 init Job 이 만든 unseal key 와 root token 을 담는다. // 이 Secret 과 OpenBao PVC 는 생애주기를 함께한다 — 한쪽만 남으면 재설치 시 // 금고를 열 수 없게 되므로 삭제도 항상 함께 수행한다. OpenBaoUnsealKeysSecret = "openbao-unseal-keys" // OpenBaoDataStorageSize 는 file 스토리지 백엔드용 PVC 크기다. OpenBaoDataStorageSize = "5Gi" )
const ( ProvisionedPostgresSecret = domain.ProvisionedPostgresSecret ProvisionedMinIOSecret = domain.ProvisionedMinIOSecret ProvisionedGitLabRootSecret = "gitlab-initial-root-password" // #nosec G101 -- Secret 리소스 이름 ProvisionedObjectStorageSecret = domain.ProvisionedObjectStorageSecret // Container Registry 전용 스토리지 설정. Rails 의 object_store 와 형식이 // 달라(Docker distribution 스키마) 같은 Secret 에 담을 수 없다. ProvisionedRegistryStorageSecret = domain.ProvisionedRegistryStorageSecret RegistryStorageSecretKey = "config" RegistryStorageBucket = "gitlab-registry" // MinIORootUser 는 비밀이 아니지만 차트의 existingSecret 이 같은 Secret 안에서 // 요구하므로 함께 프로비저닝한다. MinIORootUser = domain.MinIORootUser )
프로비저닝된 Secret 이름. 차트 values 가 existingSecret 으로 참조한다.
값의 단일 출처는 domain 이다 — 설치 경로와 조회 경로(연결정보 안내)가 같은 이름을 봐야 하는데, 양쪽에 각각 적어 두면 한쪽만 바뀌었을 때 조용히 어긋난다.
const ArgoCDSecretName = "argocd-secret" // #nosec G101 -- Secret 리소스 이름
ArgoCDSecretName 은 ArgoCD 가 읽는 Secret 이름이다. admin 해시와 OIDC client secret 이 한 Secret 에 공존하므로 ESO 가 단독 소유한다.
const GitLabOIDCSecretName = "gitlab-oidc-provider" // #nosec G101 -- Secret 리소스 이름
GitLabOIDCSecretName 은 GitLab 이 omniauth provider 로 읽는 Secret 이름이다.
GitLab 은 provider 설정을 client secret 하나가 아니라 "블록 전체" 로 받는다. 그래서 다른 도구처럼 client-secret 키만 담은 Secret 으로는 안 되고, ESO 의 target.template 으로 provider YAML 을 만들어 넣는다.
const JenkinsGiteaCredentialID = "nullus-gitea"
JenkinsGiteaCredentialID 는 Jenkins 에 등록되는 Gitea 자격증명 식별자다.
CI/CD 모듈의 job 설정이 같은 이름을 참조한다(cicd/usecase 의 giteaCredentialID). 모듈 간 직접 import 는 금지되므로 값을 각자 두되, 갈라지면 job 이 브랜치를 하나도 찾지 못하므로 계약 테스트로 묶는다.
Variables ¶
var ErrRunnerTokenDiscovery = errors.New("gitlab runner 등록 토큰을 얻지 못했습니다")
ErrRunnerTokenDiscovery 는 Runner 등록 토큰을 얻지 못했음을 알리는 sentinel 이다.
과거에는 이 실패를 무시하고 스텝을 completed 로 마킹했다. 그러면 CI 실행기가 없는데도 스택이 completed 로 끝나 파이프라인이 한 건도 돌지 않는 상태가 조용히 만들어진다. 설치 실패로 드러내야 재시도 경로를 탈 수 있다.
Functions ¶
func DefaultValues ¶
func SSOSecretName ¶
SSOSecretName 은 client secret 이 복제될 Kubernetes Secret 이름이다.
func StepForRelease ¶
StepForRelease 는 릴리스를 만든 설치 단계를 돌려준다.
이 값이 비면 편집한 values 를 어느 오버라이드 키로 저장할지 알 수 없고, 그러면 다음 재배포에서 사용자의 편집이 조용히 사라진다.
Types ¶
type ChartSpec ¶
type ChartSpec struct {
ReleaseName string
ChartName string
RepoURL string
Version string
Namespace string
Values map[string]any
Wait bool
}
func DefaultChartSpecForStep ¶
DefaultChartSpecForStep 은 단계의 기본 차트 스펙을 돌려준다.
설치가 실제로 어떤 차트를 쓰는지 다른 패키지에서 확인할 수 있도록 공개한다 — 화면에 안내하는 버전과 어긋나지 않는지 계약 테스트가 이 값을 본다.
type HelmInstaller ¶
type HelmInstaller struct {
// contains filtered or unexported fields
}
func NewHelmInstaller ¶
func NewHelmInstaller(kubeconfig []byte) *HelmInstaller
func (*HelmInstaller) Install ¶
func (h *HelmInstaller) Install(ctx context.Context, req port.HelmInstallRequest) (*port.HelmInstallResult, error)
func (*HelmInstaller) ListReleases ¶
func (h *HelmInstaller) ListReleases(ctx context.Context, namespace string) ([]port.ReleaseInfo, error)
func (*HelmInstaller) Status ¶
func (h *HelmInstaller) Status(ctx context.Context, releaseName, namespace string) (*port.HelmInstallResult, error)
func (*HelmInstaller) Uninstall ¶
func (h *HelmInstaller) Uninstall(ctx context.Context, releaseName, namespace string) error
func (*HelmInstaller) Upgrade ¶
func (h *HelmInstaller) Upgrade(ctx context.Context, req port.HelmUpgradeRequest) (*port.HelmUpgradeResult, error)
type ManagedSecret ¶
type ManagedSecret struct {
TargetSecret string
Consumer string
RestartRequired bool
Entries []SecretEntry
// TemplateData 가 있으면 ExternalSecret 의 target.template 으로 렌더링한다.
// 값 안에서 {{ .키 }} 로 Entries 의 TargetKey 를 참조한다.
TemplateData map[string]string
}
ManagedSecret 은 ESO 가 소유하는 대상 Secret 하나를 기술한다.
RestartRequired 는 회전 후 반영 전략의 스펙이다. 소비 방식에 따라 재시작 필요 여부가 달라진다 — Runner 는 기동 시 config 를 1회만 읽지만 ArgoCD 의 repository Secret 은 매 요청 시점에 읽는다.
type Orchestrator ¶
type Orchestrator struct {
// contains filtered or unexported fields
}
func NewOrchestrator ¶
func NewOrchestrator(installer port.HelmInstaller, kubeconfig []byte, namespace string, opts ...OrchestratorOption) *Orchestrator
func (*Orchestrator) ExecuteStep ¶
func (o *Orchestrator) ExecuteStep(ctx context.Context, stackID, step, phase string) error
func (*Orchestrator) InstallExternalSecrets ¶
func (o *Orchestrator) InstallExternalSecrets(ctx context.Context, namespace string) error
InstallExternalSecrets 는 ESO 설치 전 과정을 하나의 경로로 묶는다.
차트 설치 → 준비 대기 → SecretStore 적용까지 여기서 처리하므로, 오케스트레이터와 통합 테스트가 같은 코드를 통과한다. CRD 소유권 보정도 이 안에서 이뤄져 우회 경로가 생기지 않는다.
func (*Orchestrator) IsStepEnabled ¶
func (o *Orchestrator) IsStepEnabled(step string) bool
func (*Orchestrator) PreflightNamespace ¶
func (o *Orchestrator) PreflightNamespace(ctx context.Context, namespace string) error
PreflightNamespace 는 설치를 시작하기 전에 그 자리가 비어 있는지 본다.
이전 설치의 볼륨이 남아 있으면 새 설치가 옛 데이터베이스를 물려받는다. 그 안의 비밀번호는 이번에 새로 만든 Secret 과 다르고, 그 사실은 한참 뒤에 엉뚱한 도구의 오류로 드러난다 — PostgreSQL 은 Gitea 의 28P01 로, Harbor 는 프로비저닝 401 로 나왔다. 둘 다 20분을 태운 뒤였다.
여기서 멈추면 몇 초 만에 알 수 있다.
func (*Orchestrator) ProvisionSecrets ¶
func (o *Orchestrator) ProvisionSecrets( ctx context.Context, namespace, env, orgID string, writer SecretWriter, ) error
ProvisionSecrets 는 시크릿을 생성해 OpenBao 에 기록하고 ExternalSecret 을 적용한 뒤, ESO 가 실제 Kubernetes Secret 을 만들 때까지 기다린다.
대기가 필수다. ExternalSecret 을 apply 해도 ESO 가 Secret 을 만들기까지 시간이 걸리고, 그 전에 후속 Helm 설치가 existingSecret 을 참조하면 파드가 기동에 실패한다.
이미 값이 있으면 보존한다. 재설치·스텝 재시도로 비밀번호가 바뀌면 기존 데이터에 접근할 수 없게 되기 때문이다.
func (*Orchestrator) ResumeFromStep ¶
func (o *Orchestrator) ResumeFromStep(stackID, step string)
ResumeFromStep initializes ordering for a new executor created during a continued deployment, so the failed step can be reapplied directly.
func (*Orchestrator) RevokeOpenBaoRootToken ¶
func (o *Orchestrator) RevokeOpenBaoRootToken(ctx context.Context, namespace string) error
RevokeOpenBaoRootToken 은 root token 을 폐기하고 Secret 에서도 제거한다.
Kubernetes Auth 가 실제로 동작한다는 것이 확인된 뒤에 호출해야 한다. 그 전에 폐기하면 인증 경로가 하나도 남지 않는다.
폐기해도 복구할 수 있다 — unseal key threshold 를 충족하면 `bao operator generate-root` 로 재발급할 수 있고, 키는 같은 클러스터의 openbao-unseal-keys Secret 에 있다.
func (*Orchestrator) RollbackDeployment ¶
func (o *Orchestrator) RollbackDeployment(ctx context.Context, stackID string) error
func (*Orchestrator) SetNamespace ¶
func (o *Orchestrator) SetNamespace(namespace string)
func (*Orchestrator) SetSSOProvisionerFactory ¶
func (o *Orchestrator) SetSSOProvisionerFactory(factory port.SSOProvisionerFactory)
SetSSOProvisionerFactory 는 스택별 SSO provisioner 생성기를 주입한다.
func (*Orchestrator) SetSecretScope ¶
func (o *Orchestrator) SetSecretScope(env, orgID string)
SetSecretScope 는 OpenBao 경로 접두사에 쓰이는 환경/조직을 설정한다. install_stack 이 스택 컨텍스트를 알고 있으므로 거기서 주입한다.
func (*Orchestrator) SetStackConfig ¶
func (o *Orchestrator) SetStackConfig(config domain.StackConfig)
func (*Orchestrator) StartStepRuntimeTail ¶
func (o *Orchestrator) StartStepRuntimeTail(ctx context.Context, stackID, step string, emit func(level, message string)) (stop func())
func (*Orchestrator) StepRuntimeLogs ¶
func (*Orchestrator) VerifyDeployment ¶
func (o *Orchestrator) VerifyDeployment(ctx context.Context, stackID string) error
type OrchestratorOption ¶
type OrchestratorOption func(*Orchestrator)
func WithHelmStepMetadataRepository ¶
func WithHelmStepMetadataRepository(repo port.HelmStepMetadataRepository) OrchestratorOption
func WithImageProjectName ¶
func WithImageProjectName(name string) OrchestratorOption
WithImageProjectName 은 레지스트리 프로젝트 이름을 주입한다.
CI/CD 모듈의 그룹 경로(NULLUS_SCM_GROUP)와 같은 값이어야 한다 — 다르면 프로젝트는 만들어지는데 CI 가 push 하는 주소는 다른 프로젝트를 가리켜 "project not found" 로 막힌다.
func WithResourceDefaultRepository ¶
func WithResourceDefaultRepository(repo port.ResourceDefaultRepository) OrchestratorOption
func WithSharedClusterScopedComponents ¶
func WithSharedClusterScopedComponents(enabled bool) OrchestratorOption
func WithToolOIDCIssuer ¶
func WithToolOIDCIssuer(issuer string) OrchestratorOption
WithToolOIDCIssuer 는 설치되는 OSS 에 넣을 Keycloak issuer 를 주입한다.
포털이 로그인한 Keycloak 과 오리진이 같아야 SSO 세션 쿠키가 실려 도구로 재인증 없이 넘어간다. 그래서 이 값은 스택의 access_domain 이 아니라 플랫폼 설정에서 온다 — 플랫폼 Keycloak 은 스택마다가 아니라 하나뿐이기 때문이다.
type RollbackManager ¶
type RollbackManager struct {
// contains filtered or unexported fields
}
func (*RollbackManager) Push ¶
func (rm *RollbackManager) Push(releaseName string)
func (*RollbackManager) RollbackAll ¶
func (rm *RollbackManager) RollbackAll(ctx context.Context, installer port.HelmInstaller, namespace string) error
type SecretEntry ¶
type SecretEntry struct {
// PathSuffix 는 kv/nullus/{env}/{org}/ 뒤에 붙는 OpenBao 경로다.
PathSuffix string
// TargetKey 는 Kubernetes Secret 안의 키 이름이다. 차트가 요구하는 이름과
// 정확히 일치해야 한다.
TargetKey string
// Fixed 가 비어 있지 않으면 랜덤 생성 대신 이 값을 쓴다.
// 사용자명처럼 비밀이 아니지만 차트가 같은 Secret 안에서 요구하는 값에 쓴다.
Fixed string
// DeriveFrom 과 Derive 가 있으면 랜덤 생성 대신 다른 엔트리의 값에서 계산한다.
// bcrypt 해시처럼 평문과 짝을 이뤄야 하는 값에 쓴다 — 따로 생성하면 사용자가
// 안내받은 비밀번호로 로그인할 수 없다.
//
// 원본 엔트리가 이 엔트리보다 앞에 있어야 한다(같은 순서로 처리된다).
DeriveFrom string
Derive func(source string) (string, error)
}
SecretEntry 는 대상 Secret 안의 키 하나에 대응한다.
Source Files
¶
- applied-resources.go
- cert-manager.go
- cluster-scoped-adoption.go
- database-connection-check.go
- external-secrets.go
- gateway-bridge.go
- gateway-tls.go
- gitea-provisioning.go
- gitlab-runner.go
- harbor-provisioning.go
- helm-values.go
- helm_step_metadata.go
- installer.go
- kubectl.go
- manifest-builders.go
- nexus-provisioning.go
- object-storage-buckets.go
- oidc-values.go
- openbao-bootstrap.go
- openbao-init.go
- openbao-values.go
- orchestrator.go
- otel-collector.go
- platform-owned-values.go
- pod-monitor.go
- postgres-role-sync.go
- preflight.go
- release-values.go
- resource-defaults.go
- rollback.go
- secret-provisioning.go
- service-monitors.go
- sso-provisioning.go
- values.go