Add terraform state registry (#36710)
Adds terraform/opentofu state registry with locking. Implements: https://github.com/go-gitea/gitea/issues/33644. I also checked [encrypted state](https://opentofu.org/docs/language/state/encryption), it works out of the box. Docs PR: https://gitea.com/gitea/docs/pulls/357 --------- Co-authored-by: Andras Elso <elso.andras@gmail.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
+78
-10
@@ -8,6 +8,7 @@ import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
org_model "code.gitea.io/gitea/models/organization"
|
||||
@@ -18,13 +19,13 @@ import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/modules/container"
|
||||
"code.gitea.io/gitea/modules/httplib"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/optional"
|
||||
alpine_module "code.gitea.io/gitea/modules/packages/alpine"
|
||||
arch_module "code.gitea.io/gitea/modules/packages/arch"
|
||||
container_module "code.gitea.io/gitea/modules/packages/container"
|
||||
debian_module "code.gitea.io/gitea/modules/packages/debian"
|
||||
rpm_module "code.gitea.io/gitea/modules/packages/rpm"
|
||||
terraform_module "code.gitea.io/gitea/modules/packages/terraform"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/templates"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
@@ -35,6 +36,8 @@ import (
|
||||
"code.gitea.io/gitea/services/forms"
|
||||
packages_service "code.gitea.io/gitea/services/packages"
|
||||
container_service "code.gitea.io/gitea/services/packages/container"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -315,6 +318,11 @@ func ViewPackageVersion(ctx *context.Context) {
|
||||
}
|
||||
ctx.Data["LatestVersions"] = pvs
|
||||
ctx.Data["TotalVersionCount"] = pvsTotal
|
||||
ctx.Data["PackageVersionViewData"], err = packages_service.GetSpecManager().Get(pd.Package.Type).GetViewPackageVersionData(ctx, pd)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetViewPackageVersionData", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Data["CanWritePackages"] = ctx.Package.AccessMode >= perm.AccessModeWrite || ctx.IsUserSiteAdmin()
|
||||
|
||||
@@ -498,14 +506,18 @@ func packageSettingsPostActionDelete(ctx *context.Context) {
|
||||
ctx.Redirect(pd.PackageSettingsLink())
|
||||
return
|
||||
}
|
||||
|
||||
if err := packages_service.RemovePackage(ctx, ctx.Doer, pd.Package); err != nil {
|
||||
log.Error("Error deleting package: %v", err)
|
||||
ctx.Flash.Error(ctx.Tr("packages.settings.delete.error"))
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("packages.settings.delete.success"))
|
||||
errTr := util.ErrorAsTranslatable(err)
|
||||
if errTr == nil {
|
||||
ctx.ServerError("RemovePackage", err)
|
||||
return
|
||||
}
|
||||
ctx.Flash.Error(errTr.Translate(ctx.Locale))
|
||||
ctx.Redirect(pd.PackageSettingsLink())
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("packages.settings.delete.success"))
|
||||
ctx.Redirect(ctx.Package.Owner.HomeLink() + "/-/packages")
|
||||
}
|
||||
|
||||
@@ -518,18 +530,21 @@ func PackageVersionDelete(ctx *context.Context) {
|
||||
}
|
||||
|
||||
if err := packages_service.RemovePackageVersion(ctx, ctx.Doer, pd.Version); err != nil {
|
||||
log.Error("Error deleting package version: %v", err)
|
||||
ctx.Flash.Error(ctx.Tr("packages.settings.delete.error"))
|
||||
errTr := util.ErrorAsTranslatable(err)
|
||||
if errTr == nil {
|
||||
ctx.ServerError("RemovePackageVersion", err)
|
||||
return
|
||||
}
|
||||
ctx.Flash.Error(errTr.Translate(ctx.Locale))
|
||||
} else {
|
||||
ctx.Flash.Success(ctx.Tr("packages.settings.delete.version.success"))
|
||||
}
|
||||
|
||||
redirectURL := ctx.Package.Owner.HomeLink() + "/-/packages"
|
||||
// redirect to the package if there are still versions available
|
||||
redirectURL := ctx.Package.Owner.HomeLink() + "/-/packages"
|
||||
if has, _ := packages_model.ExistVersion(ctx, &packages_model.PackageSearchOptions{PackageID: pd.Package.ID, IsInternal: optional.Some(false)}); has {
|
||||
redirectURL = pd.PackageWebLink()
|
||||
}
|
||||
|
||||
ctx.Redirect(redirectURL)
|
||||
}
|
||||
|
||||
@@ -553,3 +568,56 @@ func DownloadPackageFile(ctx *context.Context) {
|
||||
|
||||
packages_helper.ServePackageFile(ctx, s, u, pf)
|
||||
}
|
||||
|
||||
// ActionPackageTerraformLock locks a terraform state
|
||||
func ActionPackageTerraformLock(ctx *context.Context) {
|
||||
pd := ctx.Package.Descriptor
|
||||
if pd.Package.Type != packages_model.TypeTerraformState {
|
||||
ctx.NotFound(nil)
|
||||
return
|
||||
}
|
||||
|
||||
existingLock, err := terraform_module.GetLock(ctx, pd.Package.ID)
|
||||
if err != nil {
|
||||
ctx.ServerError("GetLock", err)
|
||||
return
|
||||
}
|
||||
if existingLock.IsLocked() {
|
||||
ctx.Flash.Error(ctx.Tr("packages.terraform.lock.error.already_locked"))
|
||||
ctx.Redirect(pd.VersionWebLink())
|
||||
return
|
||||
}
|
||||
|
||||
lockID := uuid.New().String()
|
||||
lockInfo := &terraform_module.LockInfo{
|
||||
ID: lockID,
|
||||
Operation: "Manual UI Lock",
|
||||
Who: ctx.Doer.Name,
|
||||
Created: time.Now(),
|
||||
}
|
||||
|
||||
if err := terraform_module.SetLock(ctx, pd.Package.ID, lockInfo); err != nil {
|
||||
ctx.ServerError("SetLock", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("packages.terraform.lock.success"))
|
||||
ctx.Redirect(pd.VersionWebLink())
|
||||
}
|
||||
|
||||
// ActionPackageTerraformUnlock unlocks a terraform state
|
||||
func ActionPackageTerraformUnlock(ctx *context.Context) {
|
||||
pd := ctx.Package.Descriptor
|
||||
if pd.Package.Type != packages_model.TypeTerraformState {
|
||||
ctx.NotFound(nil)
|
||||
return
|
||||
}
|
||||
|
||||
if err := terraform_module.RemoveLock(ctx, pd.Package.ID); err != nil {
|
||||
ctx.ServerError("RemoveLock", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Flash.Success(ctx.Tr("packages.terraform.unlock.success"))
|
||||
ctx.Redirect(pd.VersionWebLink())
|
||||
}
|
||||
|
||||
@@ -1073,6 +1073,10 @@ func registerWebRoutes(m *web.Router, webAuth *AuthMiddleware) {
|
||||
m.Get("", user.ViewPackageVersion)
|
||||
m.Post("", reqPackageAccess(perm.AccessModeWrite), user.PackageVersionDelete)
|
||||
m.Get("/{version_sub}", user.ViewPackageVersion)
|
||||
m.Group("/terraform", func() {
|
||||
m.Post("/lock", user.ActionPackageTerraformLock)
|
||||
m.Post("/unlock", user.ActionPackageTerraformUnlock)
|
||||
}, reqPackageAccess(perm.AccessModeWrite))
|
||||
m.Get("/files/{fileid}", user.DownloadPackageFile)
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user