helm

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 31, 2026 License: Apache-2.0 Imports: 37 Imported by: 0

Documentation

Index

Constants

View Source
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"
)
View Source
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"
)
View Source
const (

	// OpenBaoKeyShares / OpenBaoKeyThreshold 기본값은 1/1 이다.
	// auto-unseal 구성에서는 threshold 를 채우는 데 필요한 모든 조각이
	// 어차피 같은 Secret 안에 있으므로, 분할이 런타임 보안을 높이지 않고
	// 복잡도만 늘린다. 오프라인 백업본을 여러 관리자에게 나누려는 조직만
	// 이 값을 올리면 된다.
	OpenBaoKeyShares    = 1
	OpenBaoKeyThreshold = 1
)
View Source
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"
)
View Source
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 이다 — 설치 경로와 조회 경로(연결정보 안내)가 같은 이름을 봐야 하는데, 양쪽에 각각 적어 두면 한쪽만 바뀌었을 때 조용히 어긋난다.

View Source
const ArgoCDSecretName = "argocd-secret" // #nosec G101 -- Secret 리소스 이름

ArgoCDSecretName 은 ArgoCD 가 읽는 Secret 이름이다. admin 해시와 OIDC client secret 이 한 Secret 에 공존하므로 ESO 가 단독 소유한다.

View Source
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 을 만들어 넣는다.

View Source
const JenkinsGiteaCredentialID = "nullus-gitea"

JenkinsGiteaCredentialID 는 Jenkins 에 등록되는 Gitea 자격증명 식별자다.

CI/CD 모듈의 job 설정이 같은 이름을 참조한다(cicd/usecase 의 giteaCredentialID). 모듈 간 직접 import 는 금지되므로 값을 각자 두되, 갈라지면 job 이 브랜치를 하나도 찾지 못하므로 계약 테스트로 묶는다.

Variables

View Source
var ErrRunnerTokenDiscovery = errors.New("gitlab runner 등록 토큰을 얻지 못했습니다")

ErrRunnerTokenDiscovery 는 Runner 등록 토큰을 얻지 못했음을 알리는 sentinel 이다.

과거에는 이 실패를 무시하고 스텝을 completed 로 마킹했다. 그러면 CI 실행기가 없는데도 스택이 completed 로 끝나 파이프라인이 한 건도 돌지 않는 상태가 조용히 만들어진다. 설치 실패로 드러내야 재시도 경로를 탈 수 있다.

Functions

func DefaultValues

func DefaultValues(stepName string) map[string]any

func SSOSecretName

func SSOSecretName(clientID string) string

SSOSecretName 은 client secret 이 복제될 Kubernetes Secret 이름이다.

func StepForRelease

func StepForRelease(releaseName string) string

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

func DefaultChartSpecForStep(step string) (ChartSpec, bool)

DefaultChartSpecForStep 은 단계의 기본 차트 스펙을 돌려준다.

설치가 실제로 어떤 차트를 쓰는지 다른 패키지에서 확인할 수 있도록 공개한다 — 화면에 안내하는 버전과 어긋나지 않는지 계약 테스트가 이 값을 본다.

type HelmInstaller

type HelmInstaller struct {
	// contains filtered or unexported fields
}

func NewHelmInstaller

func NewHelmInstaller(kubeconfig []byte) *HelmInstaller

func (*HelmInstaller) GetValues

func (h *HelmInstaller) GetValues(ctx context.Context, releaseName, namespace string) (map[string]any, error)

func (*HelmInstaller) Install

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

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 (o *Orchestrator) StepRuntimeLogs(ctx context.Context, stackID, step string) (infos []string, warns []string)

func (*Orchestrator) VerifyDeployment

func (o *Orchestrator) VerifyDeployment(ctx context.Context, stackID string) error

type OrchestratorOption

type OrchestratorOption func(*Orchestrator)

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 안의 키 하나에 대응한다.

type SecretWriter

type SecretWriter interface {
	PutToken(ctx context.Context, path, value string) error
	GetToken(ctx context.Context, path string) (string, error)
}

SecretWriter 는 OpenBao 에 값을 기록하고 읽는 최소 인터페이스다.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL