github.com/argoproj/argo-cd/v2@v2.10.9/server/repocreds/repocreds.go (about)

     1  package repocreds
     2  
     3  import (
     4  	"reflect"
     5  
     6  	"github.com/argoproj/argo-cd/v2/util/argo"
     7  
     8  	"context"
     9  	"google.golang.org/grpc/codes"
    10  	"google.golang.org/grpc/status"
    11  
    12  	repocredspkg "github.com/argoproj/argo-cd/v2/pkg/apiclient/repocreds"
    13  	appsv1 "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
    14  	"github.com/argoproj/argo-cd/v2/reposerver/apiclient"
    15  	"github.com/argoproj/argo-cd/v2/server/rbacpolicy"
    16  	"github.com/argoproj/argo-cd/v2/util/db"
    17  	"github.com/argoproj/argo-cd/v2/util/rbac"
    18  	"github.com/argoproj/argo-cd/v2/util/settings"
    19  )
    20  
    21  // Server provides a Repository service
    22  type Server struct {
    23  	db            db.ArgoDB
    24  	repoClientset apiclient.Clientset
    25  	enf           *rbac.Enforcer
    26  	settings      *settings.SettingsManager
    27  }
    28  
    29  // NewServer returns a new instance of the Repository service
    30  func NewServer(
    31  	repoClientset apiclient.Clientset,
    32  	db db.ArgoDB,
    33  	enf *rbac.Enforcer,
    34  	settings *settings.SettingsManager,
    35  ) *Server {
    36  	return &Server{
    37  		db:            db,
    38  		repoClientset: repoClientset,
    39  		enf:           enf,
    40  		settings:      settings,
    41  	}
    42  }
    43  
    44  // ListRepositoryCredentials returns a list of all configured repository credential sets
    45  func (s *Server) ListRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsQuery) (*appsv1.RepoCredsList, error) {
    46  	urls, err := s.db.ListRepositoryCredentials(ctx)
    47  	if err != nil {
    48  		return nil, err
    49  	}
    50  	items := make([]appsv1.RepoCreds, 0)
    51  	for _, url := range urls {
    52  		if s.enf.Enforce(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionGet, url) {
    53  			repo, err := s.db.GetRepositoryCredentials(ctx, url)
    54  			if err != nil {
    55  				return nil, err
    56  			}
    57  			if repo != nil {
    58  				items = append(items, appsv1.RepoCreds{
    59  					URL:      url,
    60  					Username: repo.Username,
    61  				})
    62  			}
    63  		}
    64  	}
    65  	return &appsv1.RepoCredsList{Items: items}, nil
    66  }
    67  
    68  // CreateRepositoryCredentials creates a new credential set in the configuration
    69  func (s *Server) CreateRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsCreateRequest) (*appsv1.RepoCreds, error) {
    70  	if q.Creds == nil {
    71  		return nil, status.Errorf(codes.InvalidArgument, "missing payload in request")
    72  	}
    73  	if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionCreate, q.Creds.URL); err != nil {
    74  		return nil, err
    75  	}
    76  
    77  	r := q.Creds
    78  
    79  	if r.URL == "" {
    80  		return nil, status.Errorf(codes.InvalidArgument, "must specify URL")
    81  	}
    82  
    83  	_, err := s.db.CreateRepositoryCredentials(ctx, r)
    84  	if status.Convert(err).Code() == codes.AlreadyExists {
    85  		// act idempotent if existing spec matches new spec
    86  		existing, getErr := s.db.GetRepositoryCredentials(ctx, r.URL)
    87  		if getErr != nil {
    88  			return nil, status.Errorf(codes.Internal, "unable to check existing repository credentials details: %v", getErr)
    89  		}
    90  
    91  		if reflect.DeepEqual(existing, r) {
    92  			err = nil
    93  		} else if q.Upsert {
    94  			return s.UpdateRepositoryCredentials(ctx, &repocredspkg.RepoCredsUpdateRequest{Creds: r})
    95  		} else {
    96  			return nil, status.Errorf(codes.InvalidArgument, argo.GenerateSpecIsDifferentErrorMessage("repository credentials", existing, r))
    97  		}
    98  	}
    99  	return &appsv1.RepoCreds{URL: r.URL}, err
   100  }
   101  
   102  // UpdateRepositoryCredentials updates a repository credential set
   103  func (s *Server) UpdateRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsUpdateRequest) (*appsv1.RepoCreds, error) {
   104  	if q.Creds == nil {
   105  		return nil, status.Errorf(codes.InvalidArgument, "missing payload in request")
   106  	}
   107  	if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionUpdate, q.Creds.URL); err != nil {
   108  		return nil, err
   109  	}
   110  	_, err := s.db.UpdateRepositoryCredentials(ctx, q.Creds)
   111  	return &appsv1.RepoCreds{URL: q.Creds.URL}, err
   112  }
   113  
   114  // DeleteRepositoryCredentials removes a credential set from the configuration
   115  func (s *Server) DeleteRepositoryCredentials(ctx context.Context, q *repocredspkg.RepoCredsDeleteRequest) (*repocredspkg.RepoCredsResponse, error) {
   116  	if err := s.enf.EnforceErr(ctx.Value("claims"), rbacpolicy.ResourceRepositories, rbacpolicy.ActionDelete, q.Url); err != nil {
   117  		return nil, err
   118  	}
   119  
   120  	err := s.db.DeleteRepositoryCredentials(ctx, q.Url)
   121  	return &repocredspkg.RepoCredsResponse{}, err
   122  }