mirror of
https://github.com/GlueOps/autoglue.git
synced 2026-02-13 04:40:05 +01:00
139 lines
5.3 KiB
Go
139 lines
5.3 KiB
Go
package dto
|
|
|
|
import (
|
|
"encoding/json"
|
|
|
|
"github.com/go-playground/validator/v10"
|
|
)
|
|
|
|
// RawJSON is a swagger-friendly wrapper for json.RawMessage.
|
|
type RawJSON = json.RawMessage
|
|
|
|
var Validate = validator.New()
|
|
|
|
func init() {
|
|
_ = Validate.RegisterValidation("awsarn", func(fl validator.FieldLevel) bool {
|
|
v := fl.Field().String()
|
|
return len(v) > 10 && len(v) < 2048 && len(v) >= 4 && v[:4] == "arn:"
|
|
})
|
|
}
|
|
|
|
/*** Shapes for secrets ***/
|
|
|
|
type AWSCredential struct {
|
|
AccessKeyID string `json:"access_key_id" validate:"required,alphanum,len=20"`
|
|
SecretAccessKey string `json:"secret_access_key" validate:"required"`
|
|
Region string `json:"region" validate:"omitempty"`
|
|
}
|
|
|
|
type BasicAuth struct {
|
|
Username string `json:"username" validate:"required"`
|
|
Password string `json:"password" validate:"required"`
|
|
}
|
|
|
|
type APIToken struct {
|
|
Token string `json:"token" validate:"required"`
|
|
}
|
|
|
|
type OAuth2Credential struct {
|
|
ClientID string `json:"client_id" validate:"required"`
|
|
ClientSecret string `json:"client_secret" validate:"required"`
|
|
RefreshToken string `json:"refresh_token" validate:"required"`
|
|
}
|
|
|
|
/*** Shapes for scopes ***/
|
|
|
|
type AWSProviderScope struct{}
|
|
|
|
type AWSServiceScope struct {
|
|
Service string `json:"service" validate:"required,oneof=route53 s3 ec2 iam rds dynamodb"`
|
|
}
|
|
|
|
type AWSResourceScope struct {
|
|
ARN string `json:"arn" validate:"required,awsarn"`
|
|
}
|
|
|
|
/*** Registries ***/
|
|
|
|
type ProviderDef struct {
|
|
New func() any
|
|
Validate func(any) error
|
|
}
|
|
|
|
type ScopeDef struct {
|
|
New func() any
|
|
Validate func(any) error
|
|
Specificity int // 0=provider, 1=service, 2=resource
|
|
}
|
|
|
|
// Secret shapes per provider/kind/version
|
|
|
|
var CredentialRegistry = map[string]map[string]map[int]ProviderDef{
|
|
"aws": {
|
|
"aws_access_key": {
|
|
1: {New: func() any { return &AWSCredential{} }, Validate: func(x any) error { return Validate.Struct(x) }},
|
|
},
|
|
},
|
|
"cloudflare": {"api_token": {1: {New: func() any { return &APIToken{} }, Validate: func(x any) error { return Validate.Struct(x) }}}},
|
|
"hetzner": {"api_token": {1: {New: func() any { return &APIToken{} }, Validate: func(x any) error { return Validate.Struct(x) }}}},
|
|
"digitalocean": {"api_token": {1: {New: func() any { return &APIToken{} }, Validate: func(x any) error { return Validate.Struct(x) }}}},
|
|
"generic": {
|
|
"basic_auth": {1: {New: func() any { return &BasicAuth{} }, Validate: func(x any) error { return Validate.Struct(x) }}},
|
|
"oauth2": {1: {New: func() any { return &OAuth2Credential{} }, Validate: func(x any) error { return Validate.Struct(x) }}},
|
|
},
|
|
}
|
|
|
|
// Scope shapes per provider/scopeKind/version
|
|
|
|
var ScopeRegistry = map[string]map[string]map[int]ScopeDef{
|
|
"aws": {
|
|
"provider": {1: {New: func() any { return &AWSProviderScope{} }, Validate: func(any) error { return nil }, Specificity: 0}},
|
|
"service": {1: {New: func() any { return &AWSServiceScope{} }, Validate: func(x any) error { return Validate.Struct(x) }, Specificity: 1}},
|
|
"resource": {1: {New: func() any { return &AWSResourceScope{} }, Validate: func(x any) error { return Validate.Struct(x) }, Specificity: 2}},
|
|
},
|
|
}
|
|
|
|
/*** API DTOs used by swagger ***/
|
|
|
|
// CreateCredentialRequest represents the POST /credentials payload
|
|
type CreateCredentialRequest struct {
|
|
Provider string `json:"provider" validate:"required,oneof=aws cloudflare hetzner digitalocean generic"`
|
|
Kind string `json:"kind" validate:"required"` // aws_access_key, api_token, basic_auth, oauth2
|
|
SchemaVersion int `json:"schema_version" validate:"required,gte=1"` // secret schema version
|
|
Name string `json:"name" validate:"omitempty,max=100"` // human label
|
|
ScopeKind string `json:"scope_kind" validate:"required,oneof=provider service resource"`
|
|
ScopeVersion int `json:"scope_version" validate:"required,gte=1"` // scope schema version
|
|
Scope RawJSON `json:"scope" validate:"required" swaggertype:"object"` // {"service":"route53"} or {"arn":"..."}
|
|
AccountID string `json:"account_id,omitempty" validate:"omitempty,max=32"`
|
|
Region string `json:"region,omitempty" validate:"omitempty,max=32"`
|
|
Secret RawJSON `json:"secret" validate:"required" swaggertype:"object"` // encrypted later
|
|
}
|
|
|
|
// UpdateCredentialRequest represents PATCH /credentials/{id}
|
|
type UpdateCredentialRequest struct {
|
|
Name *string `json:"name,omitempty"`
|
|
AccountID *string `json:"account_id,omitempty"`
|
|
Region *string `json:"region,omitempty"`
|
|
ScopeKind *string `json:"scope_kind,omitempty"`
|
|
ScopeVersion *int `json:"scope_version,omitempty"`
|
|
Scope *RawJSON `json:"scope,omitempty" swaggertype:"object"`
|
|
Secret *RawJSON `json:"secret,omitempty" swaggertype:"object"` // set if rotating
|
|
|
|
}
|
|
|
|
// CredentialOut is what we return (no secrets)
|
|
type CredentialOut struct {
|
|
ID string `json:"id"`
|
|
Provider string `json:"provider"`
|
|
Kind string `json:"kind"`
|
|
SchemaVersion int `json:"schema_version"`
|
|
Name string `json:"name"`
|
|
ScopeKind string `json:"scope_kind"`
|
|
ScopeVersion int `json:"scope_version"`
|
|
Scope RawJSON `json:"scope" swaggertype:"object"`
|
|
AccountID string `json:"account_id,omitempty"`
|
|
Region string `json:"region,omitempty"`
|
|
CreatedAt string `json:"created_at"`
|
|
UpdatedAt string `json:"updated_at"`
|
|
}
|