github.com/argoproj/argo-cd@v1.8.7/server/repocreds/repocreds.go (about)

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