Skip to content

Commit

Permalink
feat(hydrator): write credentials handling + UI
Browse files Browse the repository at this point in the history
Signed-off-by: Michael Crenshaw <[email protected]>
  • Loading branch information
crenshaw-dev committed Oct 11, 2024
1 parent 8dd122a commit f20b541
Show file tree
Hide file tree
Showing 23 changed files with 1,115 additions and 169 deletions.
42 changes: 42 additions & 0 deletions assets/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

300 changes: 219 additions & 81 deletions pkg/apiclient/repository/repository.pb.go

Large diffs are not rendered by default.

36 changes: 36 additions & 0 deletions pkg/apiclient/repository/repository.pb.gw.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

96 changes: 80 additions & 16 deletions server/repository/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"strings"

"github.com/argoproj/gitops-engine/pkg/utils/kube"
"github.com/argoproj/gitops-engine/pkg/utils/text"
log "github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
Expand Down Expand Up @@ -78,6 +77,14 @@ func (s *Server) getRepo(ctx context.Context, url, project string) (*appsv1.Repo
return repo, nil
}

func (s *Server) getWriteRepo(ctx context.Context, url, project string) (*appsv1.Repository, error) {
repo, err := s.db.GetWriteRepository(ctx, url, project)
if err != nil {
return nil, errPermissionDenied
}
return repo, nil
}

func createRBACObject(project string, repo string) string {
if project != "" {
return project + "/" + repo
Expand Down Expand Up @@ -138,12 +145,27 @@ func (s *Server) Get(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.R
}

// getRepo does not return an error for unconfigured repositories, so we are checking here
exists, err := s.db.RepositoryExists(ctx, q.Repo, repo.Project)
if err != nil {
return nil, err
if q.Type != "" && q.Type != "write" && q.Type != "read" && q.Type != "both" {
return nil, status.Errorf(codes.InvalidArgument, "invalid repository type '%s'; must be '', 'read', 'write', or 'both'", q.Type)
}
if !exists {
return nil, status.Errorf(codes.NotFound, "repo '%s' not found", q.Repo)
var exists bool
if q.Type == "write" || q.Type == "both" {
exists, err = s.db.WriteRepositoryExists(ctx, q.Repo, repo.Project)
if err != nil {
return nil, err
}
if !exists {
return nil, status.Errorf(codes.NotFound, "repo '%s' not found", q.Repo)
}
}
if q.Type == "" || q.Type == "read" || q.Type == "both" {
exists, err = s.db.RepositoryExists(ctx, q.Repo, repo.Project)
if err != nil {
return nil, err
}
if !exists {
return nil, status.Errorf(codes.NotFound, "repo '%s' not found", q.Repo)
}
}

// For backwards compatibility, if we have no repo type set assume a default
Expand Down Expand Up @@ -174,9 +196,24 @@ func (s *Server) Get(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.R

// ListRepositories returns a list of all configured repositories and the state of their connections
func (s *Server) ListRepositories(ctx context.Context, q *repositorypkg.RepoQuery) (*appsv1.RepositoryList, error) {
repos, err := s.db.ListRepositories(ctx)
if err != nil {
return nil, err
if q.Type != "" && q.Type != "write" && q.Type != "read" && q.Type != "both" {
return nil, status.Errorf(codes.InvalidArgument, "invalid repository type '%s'; must be '', 'read', 'write', or 'both'", q.Type)
}
var repos []*appsv1.Repository
var err error
if q.Type == "write" || q.Type == "both" {
wRepos, err := s.db.ListWriteRepositories(ctx)
if err != nil {
return nil, err
}
repos = append(repos, wRepos...)
}
if q.Type == "" || q.Type == "read" || q.Type == "both" {
rRepos, err := s.db.ListRepositories(ctx)
if err != nil {
return nil, err
}
repos = append(repos, rRepos...)
}
items := appsv1.Repositories{}
for _, repo := range repos {
Expand Down Expand Up @@ -426,22 +463,35 @@ func (s *Server) CreateRepository(ctx context.Context, q *repositorypkg.RepoCrea

r := q.Repo
r.ConnectionState = appsv1.ConnectionState{Status: appsv1.ConnectionStatusSuccessful}
repo, err = s.db.CreateRepository(ctx, r)
if q.Write {
repo, err = s.db.CreateWriteRepository(ctx, r)
} else {
repo, err = s.db.CreateRepository(ctx, r)
}
if status.Convert(err).Code() == codes.AlreadyExists {
// act idempotent if existing spec matches new spec
existing, getErr := s.db.GetRepository(ctx, r.Repo, q.Repo.Project)
var existing *appsv1.Repository
var getErr error
if q.Write {
existing, getErr = s.db.GetWriteRepository(ctx, r.Repo, q.Repo.Project)
} else {
existing, getErr = s.db.GetRepository(ctx, r.Repo, q.Repo.Project)
}
if getErr != nil {
return nil, status.Errorf(codes.Internal, "unable to check existing repository details: %v", getErr)
}

existing.Type = text.FirstNonEmpty(existing.Type, "git")
// repository ConnectionState may differ, so make consistent before testing
existing.ConnectionState = r.ConnectionState
if reflect.DeepEqual(existing, r) {
repo, err = existing, nil
} else if q.Upsert {
r.Project = q.Repo.Project
return s.UpdateRepository(ctx, &repositorypkg.RepoUpdateRequest{Repo: r})
if q.Write {
return s.db.UpdateWriteRepository(ctx, r)
} else {
return s.db.UpdateRepository(ctx, r)
}
} else {
return nil, status.Error(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("repository", existing, r))
}
Expand All @@ -464,7 +514,13 @@ func (s *Server) UpdateRepository(ctx context.Context, q *repositorypkg.RepoUpda
return nil, status.Errorf(codes.InvalidArgument, "missing payload in request")
}

repo, err := s.getRepo(ctx, q.Repo.Repo, q.Repo.Project)
var repo *appsv1.Repository
var err error
if q.Write {
repo, err = s.getWriteRepo(ctx, q.Repo.Repo, q.Repo.Project)
} else {
repo, err = s.getRepo(ctx, q.Repo.Repo, q.Repo.Project)
}
if err != nil {
return nil, err
}
Expand All @@ -477,7 +533,11 @@ func (s *Server) UpdateRepository(ctx context.Context, q *repositorypkg.RepoUpda
if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionUpdate, createRBACObject(q.Repo.Project, q.Repo.Repo)); err != nil {
return nil, err
}
_, err = s.db.UpdateRepository(ctx, q.Repo)
if q.Write {
_, err = s.db.UpdateWriteRepository(ctx, q.Repo)
} else {
_, err = s.db.UpdateRepository(ctx, q.Repo)
}
return &appsv1.Repository{Repo: q.Repo.Repo, Type: q.Repo.Type, Name: q.Repo.Name}, err
}

Expand All @@ -503,7 +563,11 @@ func (s *Server) DeleteRepository(ctx context.Context, q *repositorypkg.RepoQuer
log.Errorf("error invalidating cache: %v", err)
}

err = s.db.DeleteRepository(ctx, repo.Repo, repo.Project)
if q.Type == "write" {
err = s.db.DeleteWriteRepository(ctx, repo.Repo, repo.Project)
} else {
err = s.db.DeleteRepository(ctx, repo.Repo, repo.Project)
}
return &repositorypkg.RepoResponse{}, err
}

Expand Down
7 changes: 7 additions & 0 deletions server/repository/repository.proto
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ message RepoQuery {
bool forceRefresh = 2;
// App project for query
string appProject = 3;
// Type determines what kind of credential we're interacting with. It can be "read", "write", or "both". Default is
// "read".
string type = 4;
}

// RepoAccessQuery is a query for checking access to a repo
Expand Down Expand Up @@ -101,10 +104,14 @@ message RepoCreateRequest {
bool upsert = 2;
// Whether to operate on credential set instead of repository
bool credsOnly = 3;
// Write determines whether the credential will be stored as a read credential or a write credential.
bool write = 4;
}

message RepoUpdateRequest {
github.com.argoproj.argo_cd.v2.pkg.apis.application.v1alpha1.Repository repo = 1;
// Write determines whether the credential to be updated is a read credential or a write credential.
bool write = 2;
}

// RepositoryService
Expand Down
1 change: 1 addition & 0 deletions server/repository/repository_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,6 +415,7 @@ func TestRepositoryServer(t *testing.T) {
})

require.NoError(t, err)
require.NotNil(t, repo)
assert.Equal(t, "test", repo.Repo)
})

Expand Down
Loading

0 comments on commit f20b541

Please sign in to comment.