feat: add terraform-local package type for local registry

- New package type "terraform-local" for hosting terraform providers
  without an upstream registry
- Upload via PUT /api/v2/remotes/{name}/files/{path}, returns 409 on
  duplicate (overwrites not allowed)
- Download via GET on same path, or via v1 proxy route
- Provider registers as fully immutable, no upstream rewriting
- v1 proxy handler serves local files directly for local repo types
- Database CRUD for local_files table
This commit is contained in:
2026-06-21 23:01:59 +10:00
parent b46c116f6b
commit 2f1e3830da
6 changed files with 328 additions and 7 deletions
@@ -0,0 +1,49 @@
package terraformlocal
import (
"context"
"net/http"
"path"
"strings"
"git.unkin.net/unkin/artifactapi/internal/provider"
"git.unkin.net/unkin/artifactapi/pkg/models"
)
func init() {
provider.Register(&Provider{})
}
type Provider struct{}
func (p *Provider) Type() models.PackageType { return models.PackageTerraformLocal }
func (p *Provider) Classify(_ string) provider.Mutability {
return provider.Immutable
}
var contentTypeMap = map[string]string{
".zip": "application/zip",
".json": "application/json",
".sig": "application/octet-stream",
}
func (p *Provider) ContentType(filePath string) string {
ext := path.Ext(strings.ToLower(filePath))
if ct, ok := contentTypeMap[ext]; ok {
return ct
}
return "application/octet-stream"
}
func (p *Provider) UpstreamURL(_ models.Remote, _ string) string {
return ""
}
func (p *Provider) RewriteResponse(_ []byte, _ models.Remote, _ string) ([]byte, error) {
return nil, nil
}
func (p *Provider) AuthHeaders(_ context.Context, _ models.Remote) (http.Header, error) {
return http.Header{}, nil
}