port

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: 5 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrImageDeletionUnsupported = errors.New("이 레지스트리는 이미지 저장소 삭제를 지원하지 않습니다")

ErrImageDeletionUnsupported 는 이 레지스트리에서 이미지 저장소를 지울 수단이 없음을 알린다.

조용히 건너뛰지 않는 이유는, 사용자가 "이미지도 삭제" 를 골랐는데 아무 일도 일어나지 않으면 지워진 줄 알고 넘어가기 때문이다. Harbor·Nexus 는 삭제에 관리자 자격증명이 따로 필요해 파이프라인 삭제 경로에서는 아직 다루지 않는다.

View Source
var ErrSCMUserNotFound = errors.New("SCM 사용자 계정을 찾지 못했습니다")

ErrSCMUserNotFound 는 그 이메일의 SCM 계정이 아직 없다는 뜻이다.

실패가 아니라 "아직" 이다 — OIDC 첫 로그인 전에는 계정이 존재하지 않는다. 호출부는 이것을 경고로 옮겨 담아야 한다.

View Source
var ErrStackToolsUnavailable = errors.New("스택의 도구에 닿을 수 없습니다")

ErrStackToolsUnavailable 은 이 스택의 도구에 닿을 수 없다는 뜻이다.

스택이 지워졌거나 아직 설치 중일 때다. 둘 다 "지금은 그 도구들에 아무것도 할 수 없다" 는 같은 상황이고, 호출부는 그것을 실패가 아니라 **할 수 없는 일**로 다뤄야 한다 — 스택이 사라진 파이프라인을 영영 못 지우게 되면 좀비가 남는다.

Functions

This section is empty.

Types

type AccessTokenSpec

type AccessTokenSpec struct {
	Name   string
	Scopes []string
	// ExpiresInDays 가 0 이면 구현체 기본값을 쓴다.
	ExpiresInDays int
}

AccessTokenSpec 은 프로젝트 범위 토큰 발급 요청이다.

type BuildDelegate

type BuildDelegate interface {
	// DelegateBuild 는 러너의 실행을 시작시키고 그 실행의 주소를 돌려준다.
	DelegateBuild(ctx context.Context, opts DelegateBuildOpts) (runURL string, err error)
}

BuildDelegate 는 이미지 빌드를 스택의 CI 러너에 넘긴다.

ImagePreparer 와 짝을 이루는 반대편이다. ImagePreparer 는 플랫폼이 직접 빌드하는 장애 대응 경로(emergency_direct)이고, 이쪽은 스택 컴포넌트가 실행하는 일반 경로(stack_integrated)다 — CI 가 빌드해 레지스트리에 올리고 CD 도구가 클러스터에 반영한다. 플랫폼은 실행을 시작시키고 결과를 들여올 뿐 git clone·docker build·kubectl apply 를 하지 않는다.

type CDApplicationDeleter

type CDApplicationDeleter interface {
	// DeleteApplication 은 애플리케이션이 이미 없으면 성공으로 본다 —
	// 삭제의 목표는 "없는 상태" 이고, 없음을 오류로 올리면 재시도가 끝나지 않는다.
	DeleteApplication(ctx context.Context, kubeconfig []byte, namespace, name string) error
}

CDApplicationDeleter 는 CD 도구가 배포한 애플리케이션을 지운다.

도구 이름을 계약에 넣지 않는다. Argo CD 든 다른 것이든 "배포된 애플리케이션을 지운다" 는 같은 일이고, 도구가 바뀌면 구현체만 갈아 끼우면 된다.

애플리케이션만 지우면 Deployment·Service·HTTPRoute 가 클러스터에 남아 앱이 계속 돈다. 구현체는 그 도구의 방식대로 배포된 리소스까지 함께 걷어내야 한다 (Argo CD 는 정리 finalizer 를 붙인다).

type CIBuild

type CIBuild struct {
	Number int
	// Result 는 CI 가 보고한 결과다(SUCCESS/FAILURE/ABORTED). 실행 중이면 빈 값이다.
	Result   string
	Building bool
	// StartedAt 은 빌드 시작 시각, Duration 은 실행 시간이다.
	// 실행 중인 빌드의 Duration 은 0 이다.
	StartedAt time.Time
	Duration  time.Duration
	// Stages 는 실행 안의 단계다. CI 가 단계 정보를 주지 않으면 비어 있다 —
	// 비어 있는 것과 "모두 성공" 은 다르다.
	Stages []CIStage
}

CIBuild 는 CI 서버가 실행한 빌드 하나다.

type CIBuildReader

type CIBuildReader interface {
	ListBuilds(ctx context.Context, jobName, branch string, limit int) ([]CIBuild, error)
}

CIBuildReader 는 CI 서버에서 빌드 이력을 읽는다.

플랫폼이 직접 배포하는 경로와 달리, GitOps 경로의 실행 기록은 CI 서버가 갖고 있다. 이것을 들이지 않으면 빌드가 성공해도 화면의 실행 통계가 영원히 0 으로 남는다.

type CIBuildTrigger

type CIBuildTrigger interface {
	TriggerBuild(ctx context.Context, jobName, branch string) error
}

CIBuildTrigger 는 CI 서버의 job 을 지금 실행시킨다.

webhook 은 커밋이 있을 때만 돈다. 사용자가 화면에서 "배포 실행" 을 누르는 것은 커밋 없이 지금 실행하겠다는 뜻이라, 트리거가 따로 필요하다.

type CICDGoldenPathRepository

type CICDGoldenPathRepository interface {
	GetByID(ctx context.Context, id string) (*domain.CICDGoldenPath, error)
	List(ctx context.Context) ([]*domain.CICDGoldenPath, error)
	Create(ctx context.Context, goldenPath *domain.CICDGoldenPath) error
	Update(ctx context.Context, goldenPath *domain.CICDGoldenPath) error
	Delete(ctx context.Context, id string) error
}

CICDGoldenPathRepository defines the interface for CI/CD Golden Path persistence.

type CICredentialResolver

type CICredentialResolver interface {
	ResolveCICredential(ctx context.Context, spec SCMTokenSpec) (user, secret string, err error)
}

CICredentialResolver 는 스택별 CI 서버 접속 자격증명을 돌려준다.

기동 시점에 고정할 수 없다 — CI 서버는 스택마다 따로 서고 관리자 비밀번호도 스택마다 다르게 생성된다(provisioning_secrets 가 OpenBao 에 넣는다). 고정 문자열을 쓰면 비어 있거나 다른 스택의 자격증명으로 붙게 된다.

SCMTokenSpec 을 재사용한다 — 스택·클러스터·조직·환경이라는 조회 축이 SCM 토큰과 완전히 같기 때문이다.

type CIJob

type CIJob struct {
	Name string
	URL  string
}

CIJob 은 만들어진 job 이다.

type CIJobProvisioner

type CIJobProvisioner interface {
	// EnsureJob 은 job 을 만들거나 이미 있으면 그대로 둔다(멱등).
	EnsureJob(ctx context.Context, spec CIJobSpec) (*CIJob, error)
	// DeleteJob 은 job 을 지운다. 이미 없으면 성공으로 본다.
	DeleteJob(ctx context.Context, name string) error
}

CIJobProvisioner 는 CI 서버에 job 을 만든다.

SCMProvisioner 와 분리한다. GitLab CI·GitHub Actions 는 파이프라인 정의를 푸시하면 자동으로 감지하지만, Jenkins 는 job 이 먼저 존재해야 한다 — Jenkinsfile 만 커밋해서는 아무 일도 일어나지 않는다. 그 차이를 흡수하는 자리이므로 이 포트를 지원하지 않는 플랫폼에서는 nil 이고, 호출부는 nil 이면 건너뛴다(기존 GitLab/GitHub 경로 무영향).

type CIJobSpec

type CIJobSpec struct {
	// Name 은 job 이름이다. 앱 이름과 같게 두어 화면에서 짝을 찾기 쉽게 한다.
	Name string
	// RepoCloneURL 은 CI 가 스캔할 저장소 주소다.
	RepoCloneURL string
	// RepoOwner / RepoName 은 organization 소스가 요구하는 분해된 형태다.
	RepoOwner string
	RepoName  string
	// ServerURL 은 SCM 서버의 루트 주소다. Gitea 소스는 리포 주소가 아니라
	// 서버 주소를 받아 API 로 브랜치를 훑는다.
	ServerURL string
	// CredentialID 는 CI 서버에 등록된 SCM 자격증명 식별자다.
	// 비어 있으면 익명으로 스캔한다 — private 리포에서는 실패한다.
	CredentialID string
	// PipelinePath 는 파이프라인 정의 파일의 리포 내 경로다.
	PipelinePath string
}

CIJobSpec 은 CI 서버에 만들 job 하나의 요청이다.

type CIPlatform

type CIPlatform string

CIPlatform 은 파이프라인을 실행하는 CI 플랫폼이다.

SCM 과 별개의 축이다. GitLab·GitHub 은 SCM 이 CI 를 겸하지만 Gitea 는 그렇지 않다 — 소스는 Gitea, 빌드는 Jenkins 처럼 갈린다. 하나로 묶어 두면 Gitea 스택에 .gitlab-ci.yml 이 깔리고 Jenkins 는 읽을 파일이 없어 영영 돌지 않는다.

const (
	// CIPlatformGitLabCI / CIPlatformGitHubActions 는 SCM 이 겸하는 CI 다.
	CIPlatformGitLabCI      CIPlatform = "gitlab-ci"
	CIPlatformGitHubActions CIPlatform = "github-actions"
	// CIPlatformJenkins 는 SCM 과 독립적으로 도는 CI 다.
	CIPlatformJenkins CIPlatform = "jenkins"
)

func DefaultCIPlatformFor

func DefaultCIPlatformFor(platform SCMPlatform) CIPlatform

DefaultCIPlatformFor 는 CI 를 명시하지 않았을 때 SCM 이 함의하는 CI 다.

Gitea 는 자체 CI 를 쓰지 않으므로 Jenkins 로 본다 — Gitea 스택에 .gitlab-ci.yml 을 깔면 아무것도 그것을 읽지 않는다.

type CIStage

type CIStage struct {
	Name      string
	Status    CIStageStatus
	StartedAt time.Time
	Duration  time.Duration
}

CIStage 는 실행 하나 안의 단계다.

type CIStageStatus

type CIStageStatus string

CIStageStatus 는 단계 상태의 정규화된 어휘다.

CI 마다 어휘가 다르다 — Jenkins 는 SUCCESS/FAILED/IN_PROGRESS/NOT_EXECUTED, GitLab 은 success/failed/running/pending/skipped, GitHub Actions 는 status 와 conclusion 두 필드로 나눠 표현한다.

이 변환을 어댑터 경계에서 끝낸다. 도메인과 화면이 CI 별 어휘를 알게 되면 OSS 를 하나 늘릴 때마다 위쪽 계층이 모두 바뀐다.

const (
	CIStageSuccess CIStageStatus = "success"
	CIStageFailed  CIStageStatus = "failed"
	CIStageRunning CIStageStatus = "running"
	CIStageQueued  CIStageStatus = "queued"
	// CIStageSkipped 는 조건 때문에 실행되지 않은 단계다.
	// 실패와 구분해야 한다 — 건너뛴 것은 잘못된 것이 아니다.
	CIStageSkipped CIStageStatus = "skipped"
	// CIStageUnknown 은 CI 가 상태를 알려주지 않은 경우다.
	// 성공으로 넘겨짚지 않는다 — 실행되지 않은 일을 성공이라 말하면 안 된다.
	CIStageUnknown CIStageStatus = "unknown"
)

func NormalizeStageStatus

func NormalizeStageStatus(raw string) CIStageStatus

NormalizeStageStatus 는 CI 가 쓰는 표현을 정규화된 어휘로 옮긴다.

어댑터가 자기 CI 의 표현을 여기 넘긴다. 모르는 값은 unknown 이다 — 넘겨짚으면 돌지 않은 단계가 성공으로 보인다.

type ClusterTarget

type ClusterTarget struct {
	Kubeconfig  []byte
	ClusterName string
}

type ClusterTargetProvider

type ClusterTargetProvider interface {
	GetTarget(ctx context.Context, clusterID string) (*ClusterTarget, error)
}

type CommitFile

type CommitFile struct {
	Path    string
	Content string
}

CommitFile 은 커밋에 포함할 파일 하나다.

type CommitSpec

type CommitSpec struct {
	Branch  string
	Message string
	Files   []CommitFile
}

CommitSpec 은 여러 파일을 한 커밋으로 올리는 요청이다.

type DelegateBuildOpts

type DelegateBuildOpts struct {
	StackID string
	// JobName 은 CI 서버의 job 이름이다. 프로비저닝이 앱 이름으로 만든다.
	JobName string
	// Branch 는 실행할 브랜치다. multibranch job 은 브랜치가 하위 job 이라
	// 이것이 없으면 무엇을 실행할지 정해지지 않는다.
	Branch string
	// DeploymentID 는 진행 상황을 기록할 배포 기록이다.
	DeploymentID string
	// StepIndex 는 이 작업이 기록될 단계 번호다.
	StepIndex int
}

DelegateBuildOpts 는 어느 스택의 어느 job 을 실행할지다.

type DeploymentRepository

type DeploymentRepository interface {
	Create(ctx context.Context, deployment *domain.Deployment) error
	GetByID(ctx context.Context, id string) (*domain.Deployment, error)
	ListByPipelineID(ctx context.Context, pipelineID string) ([]*domain.Deployment, error)
	Update(ctx context.Context, deployment *domain.Deployment) error
}

DeploymentRepository defines the interface for deployment persistence.

type GroupSpec

type GroupSpec struct {
	Name        string
	Path        string
	Description string
}

GroupSpec 은 그룹 생성 요청이다.

type ImagePreparer

type ImagePreparer interface {
	PrepareImage(ctx context.Context, opts PrepareImageOpts) (imageRef string, err error)
}

type ImageRegistryResolver

type ImageRegistryResolver interface {
	Resolve(ctx context.Context, spec ImageTargetSpec) (*ImageTarget, error)
}

ImageRegistryResolver 는 스택 구성에 맞는 이미지 저장 위치를 결정한다.

type ImageRepositoryDeleter

type ImageRepositoryDeleter interface {
	DeleteImageRepository(ctx context.Context, target *ImageTarget) error
}

ImageRepositoryDeleter 는 레지스트리에서 이미지 저장소를 통째로 지운다.

태그 하나가 아니라 저장소 전체가 대상이다. 파이프라인을 지우는 맥락에서는 그 앱의 이미지가 전부 필요 없어지기 때문이다.

type ImageTarget

type ImageTarget struct {
	Kind RegistryKind
	// Host 는 레지스트리 호스트다 (예: "registry.nullus.local").
	Host string
	// Repository 는 태그를 뺀 완전한 이미지 경로다
	// (예: "registry.nullus.local/acme/myapp").
	Repository string
	// UsernameVar / PasswordVar 는 CI 가 로그인에 쓸 변수 이름이다.
	// GitLab 프로젝트 레지스트리는 내장 변수를, 외부 레지스트리는
	// 파이프라인에 등록된 변수를 가리킨다.
	UsernameVar string
	PasswordVar string
	// RequiredVariables 는 파이프라인에 미리 등록돼야 하는 변수들이다.
	// 내장 변수만 쓰는 구성에서는 비어 있다.
	RequiredVariables []string
}

ImageTarget 은 CI 가 이미지를 올릴 위치와 인증 방법이다.

로그인 명령을 문자열로 담지 않는다 — 셸 조각이 포트에 새면 CI 플랫폼을 바꿀 때 포트까지 흔들린다. 렌더러가 이 구조를 보고 스크립트를 만든다.

type ImageTargetSpec

type ImageTargetSpec struct {
	// AppName 은 애플리케이션 이름이다.
	AppName string
	// SCMProjectPath 는 앱의 SCM 프로젝트 전체 경로다 (예: "acme/myapp").
	// SCM 프로젝트 레지스트리를 쓰는 구성에서만 의미가 있다.
	SCMProjectPath string
	// SCMRegistryURL 은 SCM 이 알려준 프로젝트 레지스트리 경로다.
	SCMRegistryURL string
	// OrgPath 는 조직 그룹 경로다. Harbor 프로젝트 이름 등에 쓴다.
	OrgPath string
}

ImageTargetSpec 은 이미지 저장 위치를 묻는 요청이다.

type KubeconfigProvider

type KubeconfigProvider interface {
	GetKubeconfig(ctx context.Context, clusterID string) ([]byte, error)
}

type ManifestApplier

type ManifestApplier interface {
	Apply(ctx context.Context, kubeconfig []byte, manifests []string) error
	ApplyWithTracking(ctx context.Context, kubeconfig []byte, manifests []string, deploymentID string, stepOffset ...int) error
}

type OrgMemberProvisioner

type OrgMemberProvisioner interface {
	// EnsureOrgMember 는 이메일로 찾은 사용자를 조직에 넣는다(멱등).
	EnsureOrgMember(ctx context.Context, org, email string) error
}

OrgMemberProvisioner 는 사람을 조직에 넣는다.

플랫폼이 만든 저장소는 자동화 계정 소유의 private 조직 안에 있어서, 그대로 두면 정작 그 저장소에 소스를 밀어야 할 사람이 보지도 못한다. 지원하지 않는 플랫폼에서는 nil 이며, 호출부는 nil 이면 건너뛴다.

type PipelineConfigurator

type PipelineConfigurator interface {
	// SetProjectVariable 은 변수를 등록하거나 이미 있으면 갱신한다.
	SetProjectVariable(ctx context.Context, projectID string, v ProjectVariable) error
	// CreateProjectAccessToken 은 프로젝트 범위 토큰을 발급한다.
	// 값은 발급 시점에만 읽을 수 있다.
	CreateProjectAccessToken(ctx context.Context, projectID string, spec AccessTokenSpec) (string, error)
}

PipelineConfigurator 는 파이프라인 실행에 필요한 설정을 프로젝트에 건다.

SCMProvisioner 와 분리한다 — 저장소 프로비저닝과 CI 설정은 플랫폼에 따라 제공 주체가 다를 수 있다(예: GitHub + 외부 CI).

type PipelineCredentialPlane

type PipelineCredentialPlane interface {
	Provision(ctx context.Context, app string, vars []PipelineVariable) (manifest string, err error)
}

PipelineCredentialPlane 은 파이프라인 자격증명을 준비하고 그것을 클러스터에 반영할 매니페스트를 돌려준다.

적용은 하지 않는다 — 클러스터 접근은 유스케이스가 한곳에서 맡는다.

type PipelineRepository

type PipelineRepository interface {
	Create(ctx context.Context, pipeline *domain.Pipeline) error
	GetByID(ctx context.Context, id string) (*domain.Pipeline, error)
	List(ctx context.Context, orgID string) ([]*domain.Pipeline, error)
	ListByStackID(ctx context.Context, stackID string) ([]*domain.Pipeline, error)
	Update(ctx context.Context, pipeline *domain.Pipeline) error
	Delete(ctx context.Context, id string) error
}

PipelineRepository defines the interface for pipeline persistence.

type PipelineTemplateRepository

type PipelineTemplateRepository interface {
	GetByID(ctx context.Context, id string) (*domain.PipelineTemplate, error)
	List(ctx context.Context) ([]*domain.PipelineTemplate, error)
	Create(ctx context.Context, tmpl *domain.PipelineTemplate) error
	Update(ctx context.Context, tmpl *domain.PipelineTemplate) error
	Delete(ctx context.Context, id string) error
}

PipelineTemplateRepository defines the interface for pipeline template persistence.

type PipelineVariable

type PipelineVariable struct {
	Key   string
	Value string
}

PipelineVariable 은 파이프라인이 환경변수로 읽을 값 하나다.

type PrepareImageOpts

type PrepareImageOpts struct {
	GitRepoURL       string
	DockerfilePath   string
	DockerContext    string
	ImageName        string
	ClusterName      string
	DeploymentID     string
	RegistryURL      string
	RegistryUsername string
	RegistryPassword string
}

type ProjectSpec

type ProjectSpec struct {
	Name string
	Path string
	// GroupID 는 생성 시 네임스페이스 지정에 쓴다(숫자 ID).
	GroupID string
	// GroupPath 는 조회 시 경로 조합에 쓴다("{GroupPath}/{Path}").
	// 비면 개인 네임스페이스로 간주해 Path 만으로 조회한다.
	GroupPath   string
	Description string
	// Visibility 는 private | internal | public. 비면 private.
	Visibility string
	// InitReadme 가 true 면 기본 브랜치가 즉시 생성된다.
	// 브랜치가 없으면 파일 커밋이 실패하므로 첫 커밋 전에는 켜야 한다.
	InitReadme bool
}

ProjectSpec 은 프로젝트 생성 요청이다.

GroupID 가 비면 인증 사용자의 개인 네임스페이스에 만들어진다.

type ProjectVariable

type ProjectVariable struct {
	Key   string
	Value string
	// Masked 는 job 로그에서 값을 가린다. 자격증명에는 반드시 켠다.
	Masked bool
	// Protected 를 켜면 보호 브랜치에서만 노출된다.
	Protected bool
}

ProjectVariable 은 파이프라인에 등록할 CI/CD 변수다.

type RegistryCredentialResolver

type RegistryCredentialResolver interface {
	Resolve(ctx context.Context, variables []string) (map[string]string, error)
}

RegistryCredentialResolver 는 CI 가 레지스트리 로그인에 쓸 변수 값을 푼다.

요청한 변수 중 아는 것만 채워 돌려준다. 모르는 것은 손대지 않는다 — 조용히 빈 값을 채우면 CI 가 엉뚱한 자격증명으로 로그인을 시도한다.

type RegistryKind

type RegistryKind string

RegistryKind 는 이미지 레지스트리 백엔드의 종류다.

스택 구성에 따라 이미지가 저장될 곳이 달라진다. GitLab 스택이면 SCM 프로젝트에 딸린 레지스트리를, Harbor 를 고른 스택이면 Harbor 프로젝트를 쓴다. CI 스크립트를 특정 레지스트리에 맞춰 쓰지 않기 위해 이 구분을 포트로 올린다.

const (
	// RegistryKindSCMProject 는 소스 저장소 플랫폼이 프로젝트마다 제공하는
	// 레지스트리다 (GitLab Container Registry). 저장소와 수명이 같다.
	RegistryKindSCMProject RegistryKind = "scm_project"
	// RegistryKindHarbor 는 독립 설치된 Harbor 다.
	RegistryKindHarbor RegistryKind = "harbor"
	// RegistryKindNexus 는 독립 설치된 Nexus 의 Docker 커넥터다.
	RegistryKindNexus RegistryKind = "nexus"
	// RegistryKindGHCR 은 GitHub Container Registry 다.
	//
	// 다른 종류와 달리 push 자격증명을 등록할 필요가 없다 — GitHub Actions 의
	// 내장 GITHUB_TOKEN 이 packages:write 권한을 가질 수 있다.
	RegistryKindGHCR RegistryKind = "ghcr"
	// RegistryKindExternal 은 그 밖의 클러스터 외부 레지스트리다 (ECR 등).
	RegistryKindExternal RegistryKind = "external"
)

type SCMBundle

type SCMBundle struct {
	Provisioner SCMProvisioner
	Pipeline    PipelineConfigurator
	Registry    ImageRegistryResolver
	// Images 는 이미지 저장소를 지울 수단이다. 지원하지 않는 레지스트리에서는
	// nil 이며, 호출부는 이를 ErrImageDeletionUnsupported 와 같게 다뤄야 한다
	// — 조용히 건너뛰면 사용자는 이미지가 지워진 줄 안다.
	Images ImageRepositoryDeleter

	// CIJobs 는 CI 서버에 job 을 만드는 수단이다.
	//
	// GitLab CI·GitHub Actions 는 파이프라인 정의를 푸시하면 자동 감지하므로
	// nil 이다. Jenkins 는 job 이 먼저 존재해야 하므로 이 자리가 채워진다.
	// 호출부는 nil 이면 건너뛴다 — 기존 경로 무영향.
	CIJobs CIJobProvisioner
	// Webhooks 는 저장소에 push webhook 을 거는 수단이다.
	// Jenkins multibranch 가 새 커밋을 알려면 필요하다. 지원하지 않으면 nil.
	Webhooks SCMWebhookProvisioner
	// CITrigger 는 CI 서버의 job 을 지금 실행시킨다. 지원하지 않으면 nil.
	//
	// 스택에 묶인 파이프라인의 "배포 실행" 이 이 자리로 온다 — 플랫폼이
	// 빌드하지 않고 러너에게 넘긴다.
	CITrigger CIBuildTrigger
	// CIBuilds 는 CI 서버의 빌드 이력을 읽는다. 지원하지 않으면 nil.
	CIBuilds CIBuildReader
	// CIBaseURL 은 CI 서버의 주소다. webhook 대상 주소를 만드는 데 쓴다.
	CIBaseURL string
	// SCMInClusterURL 은 클러스터 안에서 SCM 에 닿는 주소다.
	//
	// Provisioner 의 base URL 과 구분한다 — 그쪽은 API 서버가 쓰는 주소라
	// 로컬 실행에서 우회 주소(localhost 포트포워드 등)일 수 있다. 반면 이 값은
	// Jenkins·Argo CD 처럼 클러스터 안에서 도는 소비자가 쓰므로 항상 서비스
	// DNS 여야 한다. 둘을 같은 값으로 두면 job 이
	// "Unknown server: http://localhost:3000" 으로 죽는다.
	SCMInClusterURL string
	// Credentials 는 CI 변수 저장소가 없는 SCM(Gitea)에서 파이프라인 자격증명을
	// OpenBao → ESO → K8s Secret 평면으로 나른다. 지원하지 않으면 nil.
	Credentials PipelineCredentialPlane

	// CDApplications 는 CD 도구가 배포한 애플리케이션을 지우는 수단이다.
	// 지원하지 않는 도구에서는 nil 이며, 호출부는 그것을 밝히고 넘어간다.
	CDApplications CDApplicationDeleter

	// OrgMembers 는 사람을 조직에 넣는 수단이다. 지원하지 않으면 nil.
	//
	// 플랫폼이 만든 저장소는 자동화 계정 소유의 private 조직 안에 있어서,
	// 그대로 두면 정작 소스를 밀어야 할 사람이 보지도 못한다.
	OrgMembers OrgMemberProvisioner

	// RegistryCredentials 는 스택이 설치한 레지스트리(Harbor·Nexus)의 자격증명을
	// 푼다. 그 값은 스택 설치가 OpenBao 에 만들어 두므로 사용자에게 다시 받을
	// 이유가 없다. 플랫폼이 소유하지 않는 레지스트리에서는 아무것도 돌려주지 않는다.
	RegistryCredentials RegistryCredentialResolver

	// Platform 은 이 묶음이 향하는 SCM 플랫폼이다.
	// 파이프라인 파일 형식이 여기서 갈리므로 렌더러까지 전달돼야 한다.
	Platform SCMPlatform
	// RepoAccessToken 은 플랫폼이 리포 범위 토큰 발급을 지원하지 않을 때
	// Argo CD·이미지 pull 인증에 재사용할 토큰이다.
	//
	// GitLab 에서는 비어 있다 — 프로젝트마다 최소 권한 토큰을 따로 발급한다.
	// GitHub 에는 리포 단위 토큰 API 가 없어 조직 PAT 를 그대로 쓴다.
	RepoAccessToken string

	// GroupPath 는 프로젝트가 만들어질 네임스페이스다.
	// GitLab 은 그룹 경로, GitHub 은 organization/사용자 이름이다.
	GroupPath string
	// CDNamespace 는 CD 도구가 설치된 네임스페이스다.
	//
	// 애플리케이션 리소스는 **여기**에 산다. 배포 대상 네임스페이스(앱이 서는
	// 곳)와 다르다 — 둘을 혼동하면 삭제가 없는 곳을 뒤지고 성공으로 끝난다.
	CDNamespace string
	// ClusterID 는 Application 을 적용할 클러스터다.
	ClusterID string
	// AccessDomain / GatewayName 은 배포된 앱을 외부에 노출할 때 쓴다.
	// 비어 있으면 앱은 클러스터 내부에서만 접근 가능하다.
	AccessDomain string
	GatewayName  string
}

SCMBundle 은 특정 스택에 묶인 프로비저닝 도구 묶음이다.

GitLab 주소·토큰·레지스트리 종류가 모두 스택마다 다르므로 기동 시점에 하나로 만들 수 없다. 요청 시점에 스택을 보고 조립한다.

type SCMBundleFactory

type SCMBundleFactory interface {
	For(ctx context.Context, stackID string) (*SCMBundle, error)
}

SCMBundleFactory 는 스택에 맞는 도구 묶음을 조립한다.

type SCMConnection

type SCMConnection struct {
	Platform SCMPlatform
	// Owner 는 리포지토리가 만들어질 GitHub Organization 또는 사용자 계정이다.
	Owner string
	// APIBaseURL 은 GitHub Enterprise Server 의 API 주소다.
	// 비면 어댑터가 github.com 을 쓴다.
	APIBaseURL string
}

SCMConnection 은 외부 SCM 에 붙기 위한 조직 단위 설정이다.

스택 안에 설치되는 GitLab 과 달리 GitHub 은 주소도 소유자도 우리가 정할 수 없다. 사용자가 등록한 값을 읽어야만 어느 org 에 리포를 만들지 알 수 있다.

type SCMConnectionReader

type SCMConnectionReader interface {
	// GetConnection 은 설정을 읽는다. 등록된 것이 없으면 nil, nil 을 돌려준다.
	GetConnection(ctx context.Context, orgID string, platform SCMPlatform) (*SCMConnection, error)
}

SCMConnectionReader 는 조직에 등록된 SCM 연동 설정을 읽는다.

type SCMGroup

type SCMGroup struct {
	ID       string `json:"id"`
	Name     string `json:"name"`
	FullPath string `json:"full_path"`
	WebURL   string `json:"web_url"`
}

SCMGroup 은 소스 저장소 플랫폼의 그룹(네임스페이스)이다.

type SCMPlatform

type SCMPlatform string

SCMPlatform 은 스택이 쓰는 소스 저장소 플랫폼이다.

저장소를 만드는 방법도, 파이프라인 파일 형식도, 토큰을 얻는 경로도 플랫폼마다 다르다. 어댑터를 고른 뒤에도 렌더러까지 이 값이 따라가야 해서 포트로 올린다.

const (
	// SCMPlatformGitLab 은 Nullus 가 스택에 직접 설치한 GitLab 이다.
	SCMPlatformGitLab SCMPlatform = "gitlab"
	// SCMPlatformGitHub 은 외부 SaaS 인 GitHub(또는 GitHub Enterprise Server)다.
	SCMPlatformGitHub SCMPlatform = "github"
	// SCMPlatformGitea 는 스택 안에 설치되는 Gitea 다. GitHub 과 달리 주소가
	// 클러스터 내부 서비스 DNS 이고 조직도 우리가 만든다.
	SCMPlatformGitea SCMPlatform = "gitea"
)

type SCMProject

type SCMProject struct {
	ID            string `json:"id"`
	Name          string `json:"name"`
	FullPath      string `json:"full_path"`
	WebURL        string `json:"web_url"`
	HTTPCloneURL  string `json:"http_clone_url"`
	RegistryURL   string `json:"registry_url"`
	DefaultBranch string `json:"default_branch"`
	// Created 는 이번 호출이 저장소를 새로 만들었는지다.
	//
	// 스캐폴딩을 덮어쓸지 판단하는 데 쓴다. CommitFiles 는 upsert 라 이미 쓰이던
	// 저장소에 다시 커밋하면 CI 가 갱신해 둔 이미지 태그가 초기값으로 되돌아가고,
	// 사용자가 고친 Dockerfile·워크플로·매니페스트도 함께 사라진다.
	Created bool `json:"created"`
}

SCMProject 는 프로비저닝된 프로젝트다.

RegistryURL 은 이 프로젝트에 종속된 컨테이너 레지스트리 경로다. GitLab 의 Container/Package Registry 는 프로젝트 단위로 존재하므로, 공용 베이스 이미지를 두려면 그것을 소유할 프로젝트가 반드시 필요하다.

type SCMProvisioner

type SCMProvisioner interface {
	EnsureGroup(ctx context.Context, spec GroupSpec) (*SCMGroup, error)
	EnsureProject(ctx context.Context, spec ProjectSpec) (*SCMProject, error)
	// CommitFiles 는 파일이 이미 있으면 갱신한다(upsert).
	CommitFiles(ctx context.Context, projectID string, spec CommitSpec) error
	// DeleteProject 는 저장소를 지운다. 이미 없으면 성공으로 본다.
	//
	// 되돌릴 수 없다. 사용자가 명시적으로 요청했을 때만 호출해야 하며,
	// 파이프라인 삭제의 기본 동작이어서는 안 된다 — 소스 코드는 사용자 자산이다.
	DeleteProject(ctx context.Context, projectID string) error
}

SCMProvisioner 는 소스 저장소 플랫폼에 그룹·프로젝트·파일을 만든다.

Ensure* 는 멱등하다 — 이미 있으면 조회 결과를 그대로 돌려준다. 스택 설치는 여러 번 재시도될 수 있으므로 생성 API 를 그대로 노출하지 않는다.

type SCMTokenIssuer

type SCMTokenIssuer interface {
	EnsureToken(ctx context.Context, spec SCMTokenSpec) (string, error)
}

SCMTokenIssuer 는 SCM 플랫폼의 API 토큰을 확보한다.

GitLab 은 PAT 값을 생성 시점에만 돌려주므로, 발급한 값을 시크릿 저장소에 보관하고 이후에는 그것을 재사용한다. 저장된 값이 없을 때만 새로 발급한다.

type SCMTokenSpec

type SCMTokenSpec struct {
	// StackID 는 시크릿 저장소를 고르는 키다.
	//
	// OpenBao 는 스택마다 배포되므로 전역 주소가 하나일 수 없다.
	// 스택 범위로 접근해야 해당 스택의 OpenBao 에 저장된다.
	StackID string
	// ClusterID 는 kubeconfig 를 찾는 키다.
	ClusterID string
	// Namespace 는 SCM(GitLab)이 설치된 네임스페이스다.
	Namespace string
	// OrgID / Env 는 시크릿 저장 경로를 구성한다.
	OrgID string
	Env   string
	// Force 가 true 면 저장된 토큰을 무시하고 새로 발급한다.
	// 토큰이 만료되거나 폐기돼 401 을 받은 호출자가 쓴다.
	Force bool
}

SCMTokenSpec 은 SCM API 토큰 확보 요청이다.

type SCMWebhookProvisioner

type SCMWebhookProvisioner interface {
	EnsureWebhook(ctx context.Context, projectID, targetURL, secret string) error
}

SCMWebhookProvisioner 는 저장소에 webhook 을 건다.

Jenkins multibranch job 은 스스로 폴링하지 않는 한 새 커밋을 모른다. 폴링은 지연이 크고 리포가 늘수록 부하가 커지므로 push webhook 을 건다.

type StackReader

type StackReader interface {
	// GetStackSummary retrieves minimal stack information by ID.
	// Returns nil and no error if the stack does not exist.
	GetStackSummary(ctx context.Context, stackID string) (*StackSummary, error)
}

StackReader provides read-only access to Stack context data. This is a Port (in Hexagonal Architecture terms) that the CI/CD context uses to validate cross-context references without importing the Stack domain directly.

type StackSummary

type StackSummary struct {
	ID        string `json:"id"`
	OrgID     string `json:"org_id"`
	ClusterID string `json:"cluster_id"`
	State     string `json:"state"` // "completed", "failed", etc.

	// Name 은 스택 이름이다. 스택이 만든 게이트웨이 이름이 여기서 나온다
	// (`<이름>-gateway`). 도메인에서 유추하면 존재하지 않는 이름이 만들어진다.
	Name string `json:"name"`

	// Namespace 는 스택이 설치된 네임스페이스다. GitLab/Argo CD 의 클러스터 내
	// 주소를 만들 때 쓴다.
	Namespace string `json:"namespace"`
	// SourceRepository / ContainerRegistry 는 스택이 고른 도구 이름이다
	// (예: "GitLab CE", "GitLab Registry", "Harbor").
	// 이미지 저장 위치를 결정하는 근거가 된다.
	SourceRepository  string `json:"source_repository"`
	ContainerRegistry string `json:"container_registry"`
	// AccessDomain 은 스택의 외부 접근 도메인이다. 비어 있을 수 있다.
	AccessDomain string `json:"access_domain"`
	// OTLPEndpoint 는 스택 OpenTelemetry Collector 의 클러스터 내 주소다
	// (host:port). 수집기를 고르지 않은 스택에서는 비어 있다.
	//
	// 배포되는 앱에 넣어 줄 값이라 CI/CD 가 알아야 하는데, 릴리스명·차트명으로
	// 주소를 조립하는 규칙은 Stack 컨텍스트의 것이다. 그래서 조립된 결과만
	// 받아 온다 — 여기서 규칙을 흉내 내면 차트가 바뀔 때 조용히 어긋난다.
	OTLPEndpoint string `json:"otlp_endpoint"`
}

StackSummary contains the minimal information the CI/CD module needs from the Stack context. This avoids importing stack/domain directly, keeping the Bounded Context boundary intact.

type WorkloadDeleter

type WorkloadDeleter interface {
	DeleteByLabel(ctx context.Context, kubeconfig []byte, namespace, selector string) error
}

WorkloadDeleter 는 라벨로 찾은 워크로드를 지운다.

Argo CD 로 배포한 앱은 Application 을 지우면 컨트롤러가 함께 걷어내지만, 매니페스트를 직접 적용하는 경로는 지워 줄 주체가 없다. 그쪽 워크로드는 이것으로 정리한다.

Jump to

Keyboard shortcuts

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