diff --git a/cmd/rig/cmd/project/get_settings.go b/cmd/rig/cmd/project/get_settings.go index 2c95154e6..147b99aec 100644 --- a/cmd/rig/cmd/project/get_settings.go +++ b/cmd/rig/cmd/project/get_settings.go @@ -25,12 +25,12 @@ func ProjectGetSettings(ctx context.Context, cmd *cobra.Command, args []string, } dockerRegistries := []table.Row{} - for i, r := range set.GetDockerRegistries().GetHosts() { + for i, r := range set.GetDockerRegistries() { if i == 0 { dockerRegistries = append(dockerRegistries, table.Row{"Docker Registries", r}) continue } - dockerRegistries = append(dockerRegistries, table.Row{"", r}) + dockerRegistries = append(dockerRegistries, table.Row{"", r.GetHost()}) } t := table.NewWriter() diff --git a/cmd/rig/cmd/project/update_settings.go b/cmd/rig/cmd/project/update_settings.go index eacafb216..dfaedc1f7 100644 --- a/cmd/rig/cmd/project/update_settings.go +++ b/cmd/rig/cmd/project/update_settings.go @@ -251,11 +251,16 @@ func promptEmailProvider(s *settings.Settings) (*settings.Update, error) { } func promptDeleteDockerRegistry(s *settings.Settings) (*settings.Update, error) { - if len(s.GetDockerRegistries().GetHosts()) == 0 { + if len(s.GetDockerRegistries()) == 0 { return nil, nil } - _, res, err := utils.PromptSelect("Choose a registry to delete:", s.GetDockerRegistries().GetHosts(), false) + var hosts []string + for _, r := range s.GetDockerRegistries() { + hosts = append(hosts, r.GetHost()) + } + + _, res, err := utils.PromptSelect("Choose a registry to delete:", hosts, false) if err != nil { return nil, err } @@ -288,9 +293,9 @@ func promptAddDockerRegistry(s *settings.Settings) (*settings.Update, error) { return nil, err } - reg := &settings.DockerRegistry{ + reg := &settings.AddDockerRegistry{ Host: host, - Field: &settings.DockerRegistry_Credentials{ + Field: &settings.AddDockerRegistry_Credentials{ Credentials: &settings.DockerRegistryCredentials{ Username: username, Password: password, @@ -430,7 +435,7 @@ func parseSettingsUpdate() (*settings.Update, error) { }, nil case utils.FormatField(settingsAddDockerRegistry.String()): jsonValue := []byte(value) - reg := settings.DockerRegistry{} + reg := settings.AddDockerRegistry{} if err := protojson.Unmarshal(jsonValue, ®); err != nil { return nil, err } diff --git a/deploy/docker-compose/docker-compose.yaml b/deploy/docker-compose/docker-compose.yaml index 45f1f8b07..d5f38f32c 100644 --- a/deploy/docker-compose/docker-compose.yaml +++ b/deploy/docker-compose/docker-compose.yaml @@ -7,8 +7,6 @@ services: MONGO_INITDB_ROOT_USERNAME: mongodb MONGO_INITDB_ROOT_PASSWORD: mongodb MONGO_INITDB_DATABASE: rig - networks: - - rig ports: - 27017:27017 volumes: @@ -18,8 +16,6 @@ services: minio: image: quay.io/minio/minio:latest command: server --console-address ":9001" /data - networks: - - rig ports: - "9000:9000" - "9001:9001" @@ -66,13 +62,10 @@ services: - /var/run/docker.sock:/var/run/docker.sock - ../../configs/server-config.yaml:/etc/rig/server-config.yaml - networks: - - rig - - default - networks: - rig: - external: true + default: + name: rig + volumes: mongodb-data: minio-data: diff --git a/internal/client/docker/capsule.go b/internal/client/docker/capsule.go index f454725a8..559d16633 100644 --- a/internal/client/docker/capsule.go +++ b/internal/client/docker/capsule.go @@ -36,7 +36,7 @@ func (c *Client) UpsertCapsule(ctx context.Context, capsuleName string, cc *clus return err } - image, err := c.ensureImage(ctx, cc.Image) + image, err := c.ensureImage(ctx, cc.Image, cc.RegistryAuth) if err != nil { return err } diff --git a/internal/client/docker/client.go b/internal/client/docker/client.go index 80133037d..edb001711 100644 --- a/internal/client/docker/client.go +++ b/internal/client/docker/client.go @@ -3,6 +3,8 @@ package docker import ( "bytes" "context" + "encoding/base64" + "encoding/json" "fmt" "io" "strings" @@ -12,14 +14,16 @@ import ( "github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/network" + "github.com/docker/docker/api/types/registry" "github.com/docker/docker/client" "github.com/docker/docker/pkg/stdcopy" + v1 "github.com/opencontainers/image-spec/specs-go/v1" "github.com/rigdev/rig-go-api/api/v1/capsule" "github.com/rigdev/rig/internal/config" + "github.com/rigdev/rig/internal/gateway/cluster" "github.com/rigdev/rig/pkg/auth" "github.com/rigdev/rig/pkg/errors" "github.com/rigdev/rig/pkg/iterator" - v1 "github.com/opencontainers/image-spec/specs-go/v1" "go.uber.org/zap" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -177,7 +181,7 @@ func (c *Client) ensureNetwork(ctx context.Context) (string, error) { return projectID.String(), nil } -func (c *Client) ensureImage(ctx context.Context, image string) (string, error) { +func (c *Client) ensureImage(ctx context.Context, image string, auth *cluster.RegistryAuth) (string, error) { if strings.IndexByte(image, ':') < 0 { image += ":latest" } @@ -195,7 +199,30 @@ func (c *Client) ensureImage(ctx context.Context, image string) (string, error) if len(is) == 0 { c.logger.Debug("pulling image", zap.String("image", image)) - r, err := c.dc.ImagePull(ctx, image, types.ImagePullOptions{}) + opts := types.ImagePullOptions{} + + if auth != nil { + ac := registry.AuthConfig{ + ServerAddress: auth.Host, + Username: auth.RegistrySecret.GetUsername(), + Password: auth.RegistrySecret.GetPassword(), + Auth: base64.StdEncoding.EncodeToString( + []byte(fmt.Sprint( + auth.RegistrySecret.GetUsername(), + ":", + auth.RegistrySecret.GetPassword()), + ), + ), + } + secret, err := json.Marshal(ac) + if err != nil { + return "", err + } + + opts.RegistryAuth = base64.StdEncoding.EncodeToString(secret) + } + + r, err := c.dc.ImagePull(ctx, image, opts) if err != nil { return "", err } diff --git a/internal/client/docker/service.go b/internal/client/docker/service.go index a4d42e184..550be0d60 100644 --- a/internal/client/docker/service.go +++ b/internal/client/docker/service.go @@ -25,7 +25,7 @@ func (c *Client) upsertService(ctx context.Context, capsuleName string, pc *prox cfg := strconv.QuoteToASCII(string(bs)) - image, err := c.ensureImage(ctx, fmt.Sprint("ghcr.io/rigdev/rig:", build.Version())) + image, err := c.ensureImage(ctx, fmt.Sprint("ghcr.io/rigdev/rig:", build.Version()), nil) if err != nil { return err } diff --git a/internal/client/k8s/k8s.go b/internal/client/k8s/k8s.go index e5c1f6ee7..e9968110d 100644 --- a/internal/client/k8s/k8s.go +++ b/internal/client/k8s/k8s.go @@ -7,7 +7,6 @@ import ( "path" "github.com/rigdev/rig/internal/gateway/cluster" - "github.com/rigdev/rig/internal/service/project" "go.uber.org/zap" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -18,13 +17,12 @@ import ( type Client struct { logger *zap.Logger cs *kubernetes.Clientset - ps project.Service mcs *metricsclient.Clientset } var _ cluster.Gateway = &Client{} -func New(logger *zap.Logger, ps project.Service) (*Client, error) { +func New(logger *zap.Logger) (*Client, error) { var ( restCfg *rest.Config err error @@ -52,7 +50,6 @@ func New(logger *zap.Logger, ps project.Service) (*Client, error) { logger: logger, cs: cs, mcs: mcs, - ps: ps, }, nil } diff --git a/internal/client/k8s/upsert_capsule.go b/internal/client/k8s/upsert_capsule.go index 5f5da97f7..3aa122679 100644 --- a/internal/client/k8s/upsert_capsule.go +++ b/internal/client/k8s/upsert_capsule.go @@ -3,6 +3,8 @@ package k8s import ( "context" "crypto/sha256" + "encoding/base64" + "encoding/json" "fmt" "strconv" @@ -36,11 +38,7 @@ func (c *Client) UpsertCapsule(ctx context.Context, capsuleName string, cc *clus return err } - bs, err := c.ps.GetProjectDockerSecret(ctx) - if err != nil { - return err - } - if err := c.reconcilePullSecret(ctx, ns, bs); err != nil { + if err := c.reconcilePullSecret(ctx, ns, cc.RegistryAuth); err != nil { return err } @@ -59,7 +57,7 @@ func (c *Client) UpsertCapsule(ctx context.Context, capsuleName string, cc *clus if err := c.reconcileEnvSecret(ctx, capsuleName, ns, cc); err != nil { return err } - if err := c.reconcileDeployment(ctx, capsuleName, ns, len(bs) > 0, cc); err != nil { + if err := c.reconcileDeployment(ctx, capsuleName, ns, cc.RegistryAuth != nil, cc); err != nil { return err } @@ -76,21 +74,38 @@ func (c *Client) reconcileProjectNamespace(ctx context.Context, namespace string return nil } -func (c *Client) reconcilePullSecret(ctx context.Context, namespace string, data []byte) error { - if len(data) == 0 { +func (c *Client) reconcilePullSecret(ctx context.Context, namespace string, auth *cluster.RegistryAuth) error { + if auth == nil { if err := c.deletePullSecret(ctx, namespace); err != nil { return err } return nil } + bs, err := json.Marshal(map[string]interface{}{ + "auths": map[string]interface{}{ + auth.Host: map[string]interface{}{ + "auth": base64.StdEncoding.EncodeToString( + []byte(fmt.Sprint( + auth.RegistrySecret.GetUsername(), + ":", + auth.RegistrySecret.GetPassword()), + ), + ), + }, + }, + }) + if err != nil { + return err + } + s := acsv1.Secret(fmt.Sprintf("%s-pull", namespace), namespace). WithType(v1.SecretTypeDockerConfigJson). - WithData(map[string][]byte{".dockerconfigjson": data}) - _, err := c.cs.CoreV1().Secrets(namespace).Apply(ctx, s, applyOpts()) - if err != nil { + WithData(map[string][]byte{".dockerconfigjson": bs}) + if _, err := c.cs.CoreV1().Secrets(namespace).Apply(ctx, s, applyOpts()); err != nil { return fmt.Errorf("could not apply pull secret: %w", err) } + return nil } diff --git a/internal/gateway/cluster/gateway.go b/internal/gateway/cluster/gateway.go index 4393cd8ca..3d17acaa5 100644 --- a/internal/gateway/cluster/gateway.go +++ b/internal/gateway/cluster/gateway.go @@ -5,6 +5,7 @@ import ( "github.com/rigdev/rig-go-api/api/v1/capsule" "github.com/rigdev/rig/gen/go/proxy" + "github.com/rigdev/rig/gen/go/registry" "github.com/rigdev/rig/pkg/auth" "github.com/rigdev/rig/pkg/iterator" ) @@ -21,6 +22,12 @@ type Capsule struct { Metadata map[string]string BuildID string JWTMethod *proxy.JWTMethod + RegistryAuth *RegistryAuth +} + +type RegistryAuth struct { + Host string + RegistrySecret *registry.Secret } type Gateway interface { diff --git a/internal/service/capsule/rollout.go b/internal/service/capsule/rollout.go index 0ad50fa25..cdfe4c533 100644 --- a/internal/service/capsule/rollout.go +++ b/internal/service/capsule/rollout.go @@ -7,6 +7,7 @@ import ( "reflect" "time" + "github.com/distribution/distribution/v3/reference" "github.com/golang-jwt/jwt" "github.com/rigdev/rig-go-api/api/v1/capsule" "github.com/rigdev/rig-go-api/model" @@ -239,6 +240,9 @@ func (j *rolloutJob) Run(ctx context.Context) error { rs := proto.Clone(oldRS).(*rollout.Status) err = j.run(ctx, c, rc, rs, version, logger) + if err != nil { + rs.Status.Message = errors.MessageOf(err) + } if proto.Equal(rs, oldRS) { rs.ScheduledAt = timestamppb.New(time.Now().Add(3 * time.Second)) @@ -425,6 +429,22 @@ func (j *rolloutJob) run( Network: rc.GetNetwork(), } + ref, err := reference.ParseDockerRef(b.GetBuildId()) + if err != nil { + return errors.InvalidArgumentErrorf("%v", err) + } + + host := reference.Domain(ref) + if ds, err := j.s.ps.GetProjectDockerSecret(ctx, host); errors.IsNotFound(err) { + } else if err != nil { + return err + } else { + cc.RegistryAuth = &cluster.RegistryAuth{ + Host: host, + RegistrySecret: ds, + } + } + if cc.ContainerSettings == nil { cc.ContainerSettings = &capsule.ContainerSettings{} } diff --git a/internal/service/capsule/service.go b/internal/service/capsule/service.go index 1b409e9a7..10343bcf3 100644 --- a/internal/service/capsule/service.go +++ b/internal/service/capsule/service.go @@ -8,6 +8,7 @@ import ( "github.com/rigdev/rig/internal/gateway/cluster" "github.com/rigdev/rig/internal/repository" "github.com/rigdev/rig/internal/service/auth" + "github.com/rigdev/rig/internal/service/project" "github.com/rigdev/rig/pkg/errors" "github.com/rigdev/rig/pkg/iterator" "github.com/rigdev/rig/pkg/uuid" @@ -21,15 +22,17 @@ type Service struct { sr repository.Secret cg cluster.Gateway as *auth.Service + ps project.Service q *Queue[Job] } -func NewService(cr repository.Capsule, sr repository.Secret, cg cluster.Gateway, as *auth.Service, logger *zap.Logger) *Service { +func NewService(cr repository.Capsule, sr repository.Secret, cg cluster.Gateway, as *auth.Service, ps project.Service, logger *zap.Logger) *Service { s := &Service{ cr: cr, sr: sr, cg: cg, as: as, + ps: ps, q: NewQueue[Job](), logger: logger, } diff --git a/internal/service/project/docker_registries.go b/internal/service/project/docker_registries.go index 5185cfe3a..77bc14147 100644 --- a/internal/service/project/docker_registries.go +++ b/internal/service/project/docker_registries.go @@ -6,27 +6,38 @@ import ( "encoding/base64" "encoding/json" "fmt" + "reflect" project_settings "github.com/rigdev/rig-go-api/api/v1/project/settings" + "github.com/rigdev/rig/gen/go/registry" + "github.com/rigdev/rig/pkg/errors" "github.com/rigdev/rig/pkg/uuid" + "google.golang.org/protobuf/proto" ) -func (s *service) GetProjectDockerSecret(ctx context.Context) ([]byte, error) { +func (s *service) GetProjectDockerSecret(ctx context.Context, host string) (*registry.Secret, error) { ps, err := s.GetProjectSettings(ctx) if err != nil { return nil, err } - stringSid := ps.DockerRegistries.GetSecretId() - if stringSid == "" { - return nil, nil - } + for _, p := range ps.GetDockerRegistries() { + if p.GetHost() == host { + bs, err := s.rs.Get(ctx, uuid.UUID(p.GetSecretId())) + if err != nil { + return nil, err + } - bs, err := s.rs.Get(ctx, uuid.UUID(stringSid)) - if err != nil { - return nil, err + rs := ®istry.Secret{} + if err := proto.Unmarshal(bs, rs); err != nil { + return nil, err + } + + return rs, nil + } } - return bs, nil + + return nil, errors.NotFoundErrorf("registry host not found") } func (s *service) applyAddDockerRegistry( @@ -34,94 +45,59 @@ func (s *service) applyAddDockerRegistry( set *project_settings.Settings, reg *project_settings.Update_AddDockerRegistry, ) error { - cfg := createDockerConfigJSON(reg) - if set.DockerRegistries == nil { - set.DockerRegistries = &project_settings.DockerRegistries{} - } - - if sid := set.DockerRegistries.GetSecretId(); sid != "" { - id := uuid.UUID(sid) - - existingCFG, err := s.getDockerSecret(ctx, id) - if err != nil { - return err - } - - existingCFG.merge(cfg) - if err := s.updateDockerSecret(ctx, existingCFG, id); err != nil { - return err - } - } else { - id, err := s.createDockerSecret(ctx, cfg) - if err != nil { - return err + for _, h := range set.GetDockerRegistries() { + if reg.AddDockerRegistry.GetHost() == h.GetHost() { + return errors.AlreadyExistsErrorf("registry host already exists") } - set.DockerRegistries.SecretId = id.String() } - found := false - for _, h := range set.DockerRegistries.GetHosts() { - if h == reg.AddDockerRegistry.GetHost() { - found = true - } + rs, err := createRegistrySecret(reg) + if err != nil { + return err } - if !found { - set.DockerRegistries.Hosts = append(set.DockerRegistries.Hosts, reg.AddDockerRegistry.GetHost()) + + id, err := s.createDockerSecret(ctx, rs) + if err != nil { + return err } + set.DockerRegistries = append(set.DockerRegistries, &project_settings.DockerRegistry{ + Host: reg.AddDockerRegistry.GetHost(), + SecretId: id.String(), + }) + return nil } func (s *service) applyDeleteDockerRegistry( ctx context.Context, set *project_settings.Settings, - del *project_settings.Update_DeleteDockerRegistry, + reg *project_settings.Update_DeleteDockerRegistry, ) error { - if set.DockerRegistries == nil { - return nil - } - sid := set.DockerRegistries.GetSecretId() - if sid == "" { - return nil - } - - id := uuid.UUID(sid) - - existingCFG, err := s.getDockerSecret(ctx, id) - if err != nil { - return err - } - if _, ok := existingCFG.Auths[del.DeleteDockerRegistry]; ok { - delete(existingCFG.Auths, del.DeleteDockerRegistry) - if len(existingCFG.Auths) == 0 { - if err := s.deleteDockerSecret(ctx, id); err != nil { + for i, h := range set.GetDockerRegistries() { + if reg.DeleteDockerRegistry == h.GetHost() { + secretID, err := uuid.Parse(h.GetSecretId()) + if err != nil { return err } - } else { - if err := s.updateDockerSecret(ctx, existingCFG, id); err != nil { + + if err := s.deleteDockerSecret(ctx, secretID); err != nil { return err } - } - } - var hs []string - for _, h := range set.DockerRegistries.GetHosts() { - if h == del.DeleteDockerRegistry { - continue + set.DockerRegistries = append( + set.GetDockerRegistries()[:i], + set.GetDockerRegistries()[i+1:]..., + ) + return nil } - hs = append(hs, h) - } - if len(hs) == 0 { - set.DockerRegistries = nil - } else { - set.DockerRegistries.Hosts = hs } - return nil + return errors.NotFoundErrorf("registry not found") } -func (s *service) createDockerSecret(ctx context.Context, reg *dockerConfigJSON) (*uuid.UUID, error) { - bs, err := json.Marshal(reg) +func (s *service) createDockerSecret(ctx context.Context, rs *registry.Secret) (*uuid.UUID, error) { + bs, err := proto.Marshal(rs) if err != nil { return nil, fmt.Errorf("could not marshal docker config: %w", err) } @@ -135,71 +111,57 @@ func (s *service) createDockerSecret(ctx context.Context, reg *dockerConfigJSON) return &id, nil } -func (s *service) getDockerSecret(ctx context.Context, id uuid.UUID) (*dockerConfigJSON, error) { - bs, err := s.rs.Get(ctx, id) - if err != nil { - return nil, err - } - - var cfg dockerConfigJSON - if err := json.NewDecoder(bytes.NewReader(bs)).Decode(&cfg); err != nil { - return nil, fmt.Errorf("could not decode docker secret: %w", err) - } - return &cfg, nil +func (s *service) deleteDockerSecret(ctx context.Context, id uuid.UUID) error { + return s.rs.Delete(ctx, id) } -func (s *service) updateDockerSecret(ctx context.Context, cfg *dockerConfigJSON, id uuid.UUID) error { - bs, err := json.Marshal(cfg) - if err != nil { - return fmt.Errorf("could not marshal docker config: %w", err) - } - - if err := s.rs.Update(ctx, id, bs); err != nil { - return fmt.Errorf("could not update docker config.json: %w", err) - } - - return nil -} +func createRegistrySecret(reg *project_settings.Update_AddDockerRegistry) (*registry.Secret, error) { + switch v := reg.AddDockerRegistry.Field.(type) { + case *project_settings.AddDockerRegistry_Auth: + raw, err := base64.StdEncoding.DecodeString(v.Auth) + if err != nil { + return nil, errors.InvalidArgumentErrorf("invalid auth format, expected base64 encoded payload") + } -func (s *service) deleteDockerSecret(ctx context.Context, id uuid.UUID) error { - if err := s.rs.Delete(ctx, id); err != nil { - return fmt.Errorf("could not delete docker config.json secret: %w", err) - } - return nil -} + var r struct { + Username string + Password string + Auth string + } + if err := json.Unmarshal(raw, &r); err == nil { + if r.Username != "" && r.Password != "" { + return ®istry.Secret{ + Username: r.Username, + Password: r.Password, + }, nil + } -type dockerConfigJSON struct { - Auths map[string]dockerConfigJSONAuth `json:"auths"` -} + if r.Auth == "" { + errors.InvalidArgumentErrorf("invalid auth format, expected base64 json token with `username/password` or `auth`") + } -func createDockerConfigJSON(reg *project_settings.Update_AddDockerRegistry) *dockerConfigJSON { - cfg := dockerConfigJSON{Auths: map[string]dockerConfigJSONAuth{}} - switch v := reg.AddDockerRegistry.Field.(type) { - case *project_settings.DockerRegistry_Auth: - cfg.Auths[reg.AddDockerRegistry.GetHost()] = dockerConfigJSONAuth{ - Auth: reg.AddDockerRegistry.GetAuth(), + raw, err = base64.StdEncoding.DecodeString(r.Auth) + if err != nil { + return nil, errors.InvalidArgumentErrorf("invalid auth format, expected base64 encoded payload") + } } - case *project_settings.DockerRegistry_Credentials: - up := fmt.Sprintf("%s:%s", v.Credentials.GetUsername(), v.Credentials.GetPassword()) - cfg.Auths[reg.AddDockerRegistry.GetHost()] = dockerConfigJSONAuth{ - Auth: base64.StdEncoding.EncodeToString([]byte(up)), - Username: v.Credentials.GetUsername(), - Password: v.Credentials.GetPassword(), - Email: v.Credentials.GetEmail(), + + if idx := bytes.IndexByte(raw, ':'); idx > 0 && idx < len(raw)-1 { + return ®istry.Secret{ + Username: string(raw[0:idx]), + Password: string(raw[idx+1:]), + }, nil } - } - return &cfg -} -func (cfg *dockerConfigJSON) merge(newCFG *dockerConfigJSON) { - for h, a := range newCFG.Auths { - cfg.Auths[h] = a - } -} + return nil, errors.InvalidArgumentErrorf("invalid auth format, expected json or `username:password` formatted base64 token") -type dockerConfigJSONAuth struct { - Username string `json:"username"` - Password string `json:"password"` - Email string `json:"email"` - Auth string `json:"auth"` + case *project_settings.AddDockerRegistry_Credentials: + return ®istry.Secret{ + Username: v.Credentials.Username, + Password: v.Credentials.Password, + }, nil + + default: + return nil, errors.InvalidArgumentErrorf("invalid registry auth type '%v'", reflect.TypeOf(v)) + } } diff --git a/internal/service/project/service.go b/internal/service/project/service.go index 405fc9900..891fdebdc 100644 --- a/internal/service/project/service.go +++ b/internal/service/project/service.go @@ -10,6 +10,7 @@ import ( storage_settings "github.com/rigdev/rig-go-api/api/v1/storage/settings" user_settings "github.com/rigdev/rig-go-api/api/v1/user/settings" "github.com/rigdev/rig-go-api/model" + "github.com/rigdev/rig/gen/go/registry" "github.com/rigdev/rig/internal/config" "github.com/rigdev/rig/internal/gateway/email" "github.com/rigdev/rig/internal/oauth2" @@ -32,7 +33,7 @@ type Service interface { List(ctx context.Context, query *model.Pagination) (iterator.Iterator[*project.Project], int64, error) DeleteProject(ctx context.Context) error - GetProjectDockerSecret(ctx context.Context) ([]byte, error) + GetProjectDockerSecret(ctx context.Context, host string) (*registry.Secret, error) GetEmailProvider(ctx context.Context) (email.Gateway, error) diff --git a/proto/internal/registry/secret.proto b/proto/internal/registry/secret.proto new file mode 100644 index 000000000..b80476de5 --- /dev/null +++ b/proto/internal/registry/secret.proto @@ -0,0 +1,8 @@ +syntax = "proto3"; + +package rollout; + +message Secret { + string username = 1; + string password = 2; +} diff --git a/proto/rig/api/v1/project/settings/settings.proto b/proto/rig/api/v1/project/settings/settings.proto index 98227915e..0f5900288 100644 --- a/proto/rig/api/v1/project/settings/settings.proto +++ b/proto/rig/api/v1/project/settings/settings.proto @@ -25,7 +25,7 @@ message SmtpInstance { int64 port = 2; } -message EmailInstance{ +message EmailInstance { oneof instance { DefaultInstance default = 1; MailjetInstance mailjet = 2; @@ -33,7 +33,7 @@ message EmailInstance{ } } -message TextInstance{ +message TextInstance { oneof instance { DefaultInstance default = 1; TwilioInstance twilio = 2; @@ -86,34 +86,34 @@ message Settings { EmailProviderEntry email_provider = 1; TextProviderEntry text_provider = 2; Templates templates = 3; - DockerRegistries docker_registries = 4; + repeated DockerRegistry docker_registries = 4; } -message DockerRegistries { - string secret_id = 1; - repeated string hosts = 2; +message DockerRegistry { + string secret_id = 1; + string host = 2; } -message DockerRegistry { - string host = 1; - oneof field { - string auth = 2; - DockerRegistryCredentials credentials = 3; - } +message AddDockerRegistry { + string host = 1; + oneof field { + string auth = 2; + DockerRegistryCredentials credentials = 3; + } } message DockerRegistryCredentials { - string username = 1; - string password = 2; - string email = 3; + string username = 1; + string password = 2; + string email = 3; } message Update { - oneof field { - EmailProvider email_provider = 1; - TextProvider text_provider = 2; - Template template = 3; - DockerRegistry add_docker_registry = 4; - string delete_docker_registry = 5; - } + oneof field { + EmailProvider email_provider = 1; + TextProvider text_provider = 2; + Template template = 3; + AddDockerRegistry add_docker_registry = 4; + string delete_docker_registry = 5; + } }