Compare commits

...

14 Commits

Author SHA1 Message Date
Alexander Matyushentsev
1b0e3e7b80 Update manifests to v0.9.2 2018-09-28 09:36:21 -07:00
Jesse Suen
2faf45af94 Add version check during release to ensure compiled version is accurate (#646) 2018-09-27 18:57:44 -07:00
Jesse Suen
b8c4436870 Update generated files 2018-09-27 18:09:50 -07:00
Jesse Suen
f8b2576f19 Fix issue where argocd-server logged credentials in plain text during repo add (issue #653) 2018-09-27 18:04:10 -07:00
Jesse Suen
61f4513e52 Switch to go-git for all remote git interactions including auth (issue #651) 2018-09-27 18:03:56 -07:00
Jesse Suen
4d210c887b Do not append .git extension during normalization for Azure hosted git (issue #643) (#645) 2018-09-27 18:03:33 -07:00
Alexander Matyushentsev
ab6b2969ac Issue #650 - Temporary ignore service catalog resources (#661) 2018-09-27 18:00:24 -07:00
Andrew Merenbach
447dd30768 Update generated files (#660) 2018-09-27 13:53:56 -07:00
dthomson25
ab98589e1a Normalize policies by always adding space after comma (#659) 2018-09-27 13:30:49 -07:00
Stephen Haynes
2fd6c11338 update to kustomize 1.0.8 (#644) 2018-09-26 21:28:08 -07:00
Alexander Matyushentsev
b90102bc68 Update argocd VERSION file 2018-09-24 15:28:17 -07:00
Alexander Matyushentsev
1aa7146d3e Update manifests to v0.9.1 2018-09-24 14:26:20 -07:00
Alexander Matyushentsev
b366977265 Issue #639 - Repo server unable to execute ls-remote for private repos (#640) 2018-09-24 14:22:23 -07:00
Alexander Matyushentsev
b6439dc545 Update manifests to v0.9.0 2018-09-24 13:16:09 -07:00
19 changed files with 194 additions and 270 deletions

View File

@@ -61,7 +61,7 @@ RUN wget https://storage.googleapis.com/kubernetes-helm/helm-v${HELM_VERSION}-li
mv /tmp/linux-amd64/helm /usr/local/bin/helm
# Install kustomize
ENV KUSTOMIZE_VERSION=1.0.7
ENV KUSTOMIZE_VERSION=1.0.8
RUN curl -L -o /usr/local/bin/kustomize https://github.com/kubernetes-sigs/kustomize/releases/download/v${KUSTOMIZE_VERSION}/kustomize_${KUSTOMIZE_VERSION}_linux_amd64 && \
chmod +x /usr/local/bin/kustomize

View File

@@ -151,6 +151,7 @@ precheckin: test lint
release-precheck: manifests
@if [ "$(GIT_TREE_STATE)" != "clean" ]; then echo 'git tree state is $(GIT_TREE_STATE)' ; exit 1; fi
@if [ -z "$(GIT_TAG)" ]; then echo 'commit must be tagged to perform release' ; exit 1; fi
@if [ "$(GIT_TAG)" != "v`cat VERSION`" ]; then echo 'VERSION does not match git tag'; exit 1; fi
.PHONY: release
release: release-precheck precheckin cli-darwin cli-linux server-image controller-image repo-server-image cli-image

View File

@@ -1 +1 @@
0.9.0
0.9.2

View File

@@ -87,7 +87,7 @@ func NewRepoAddCommand(clientOpts *argocdclient.ClientOptions) *cobra.Command {
}
command.Flags().StringVar(&repo.Username, "username", "", "username to the repository")
command.Flags().StringVar(&repo.Password, "password", "", "password to the repository")
command.Flags().StringVar(&sshPrivateKeyPath, "sshPrivateKeyPath", "", "path to the private ssh key (e.g. ~/.ssh/id_rsa)")
command.Flags().StringVar(&sshPrivateKeyPath, "ssh-private-key-path", "", "path to the private ssh key (e.g. ~/.ssh/id_rsa)")
command.Flags().BoolVar(&upsert, "upsert", false, "Override an existing repository with the same name even if the spec differs")
return command
}

View File

@@ -3,16 +3,9 @@ package controller
import (
"context"
"encoding/json"
"runtime/debug"
"time"
"runtime/debug"
"github.com/argoproj/argo-cd/common"
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/reposerver"
"github.com/argoproj/argo-cd/reposerver/repository"
"github.com/argoproj/argo-cd/util"
"github.com/argoproj/argo-cd/util/db"
log "github.com/sirupsen/logrus"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -25,6 +18,12 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/tools/cache"
"k8s.io/client-go/util/workqueue"
"github.com/argoproj/argo-cd/common"
"github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/reposerver"
"github.com/argoproj/argo-cd/util/db"
"github.com/argoproj/argo-cd/util/git"
)
type SecretController struct {
@@ -93,22 +92,13 @@ func (ctrl *SecretController) getRepoConnectionState(repo *v1alpha1.Repository)
ModifiedAt: repo.ConnectionState.ModifiedAt,
Status: v1alpha1.ConnectionStatusUnknown,
}
closer, client, err := ctrl.repoClientset.NewRepositoryClient()
if err != nil {
log.Errorf("Unable to create repository client: %v", err)
return state
}
defer util.Close(closer)
_, err = client.ListDir(context.Background(), &repository.ListDirRequest{Repo: repo, Path: ".gitignore"})
err := git.TestRepo(repo.Repo, repo.Username, repo.Password, repo.SSHPrivateKey)
if err == nil {
state.Status = v1alpha1.ConnectionStatusSuccessful
} else {
state.Status = v1alpha1.ConnectionStatusFailed
state.Message = err.Error()
}
return state
}

View File

@@ -24,8 +24,8 @@ resources:
imageTags:
- name: argoproj/argocd-server
newTag: latest
newTag: v0.9.2
- name: argoproj/argocd-repo-server
newTag: latest
newTag: v0.9.2
- name: argoproj/application-controller
newTag: latest
newTag: v0.9.2

View File

@@ -315,7 +315,7 @@ spec:
- /argocd-application-controller
- --repo-server
- argocd-repo-server:8081
image: argoproj/argocd-application-controller:latest
image: argoproj/argocd-application-controller:v0.9.2
name: application-controller
serviceAccountName: application-controller
---
@@ -336,7 +336,7 @@ spec:
containers:
- command:
- /argocd-repo-server
image: argoproj/argocd-repo-server:latest
image: argoproj/argocd-repo-server:v0.9.2
name: argocd-repo-server
ports:
- containerPort: 8081
@@ -366,7 +366,7 @@ spec:
- /shared/app
- --repo-server
- argocd-repo-server:8081
image: argoproj/argocd-server:latest
image: argoproj/argocd-server:v0.9.2
name: argocd-server
readinessProbe:
httpGet:
@@ -383,7 +383,7 @@ spec:
- -r
- /app
- /shared
image: argoproj/argocd-ui:latest
image: argoproj/argocd-ui:v0.9.2
name: ui
volumeMounts:
- mountPath: /shared
@@ -423,7 +423,7 @@ spec:
- cp
- /argocd-util
- /shared
image: argoproj/argocd-server:latest
image: argoproj/argocd-server:v0.9.2
name: copyutil
volumeMounts:
- mountPath: /shared

View File

@@ -261,7 +261,7 @@ spec:
- /argocd-application-controller
- --repo-server
- argocd-repo-server:8081
image: argoproj/argocd-application-controller:latest
image: argoproj/argocd-application-controller:v0.9.2
name: application-controller
serviceAccountName: application-controller
---
@@ -282,7 +282,7 @@ spec:
containers:
- command:
- /argocd-repo-server
image: argoproj/argocd-repo-server:latest
image: argoproj/argocd-repo-server:v0.9.2
name: argocd-repo-server
ports:
- containerPort: 8081
@@ -312,7 +312,7 @@ spec:
- /shared/app
- --repo-server
- argocd-repo-server:8081
image: argoproj/argocd-server:latest
image: argoproj/argocd-server:v0.9.2
name: argocd-server
readinessProbe:
httpGet:
@@ -329,7 +329,7 @@ spec:
- -r
- /app
- /shared
image: argoproj/argocd-ui:latest
image: argoproj/argocd-ui:v0.9.2
name: ui
volumeMounts:
- mountPath: /shared
@@ -369,7 +369,7 @@ spec:
- cp
- /argocd-util
- /shared
image: argoproj/argocd-server:latest
image: argoproj/argocd-server:v0.9.2
name: copyutil
volumeMounts:
- mountPath: /shared

View File

@@ -790,6 +790,11 @@ func (in *SyncOperation) DeepCopyInto(out *SyncOperation) {
(*in).DeepCopyInto(*out)
}
}
if in.ParameterOverrides != nil {
in, out := &in.ParameterOverrides, &out.ParameterOverrides
*out = make(ParameterOverrides, len(*in))
copy(*out, *in)
}
return
}

View File

@@ -76,10 +76,6 @@ func (s *Service) ListDir(ctx context.Context, q *ListDirRequest) (*FileList, er
s.repoLock.Lock(gitClient.Root())
defer s.repoLock.Unlock(gitClient.Root())
err = gitClient.Init()
if err != nil {
return nil, err
}
commitSHA, err = checkoutRevision(gitClient, commitSHA)
if err != nil {
return nil, err
@@ -119,10 +115,6 @@ func (s *Service) GetFile(ctx context.Context, q *GetFileRequest) (*GetFileRespo
s.repoLock.Lock(gitClient.Root())
defer s.repoLock.Unlock(gitClient.Root())
err = gitClient.Init()
if err != nil {
return nil, err
}
commitSHA, err = checkoutRevision(gitClient, commitSHA)
if err != nil {
return nil, err
@@ -165,10 +157,6 @@ func (s *Service) GenerateManifest(c context.Context, q *ManifestRequest) (*Mani
s.repoLock.Lock(gitClient.Root())
defer s.repoLock.Unlock(gitClient.Root())
err = gitClient.Init()
if err != nil {
return nil, err
}
commitSHA, err = checkoutRevision(gitClient, commitSHA)
if err != nil {
return nil, err
@@ -309,13 +297,17 @@ func IdentifyAppSourceTypeByAppPath(appFilePath string) AppSourceType {
// checkoutRevision is a convenience function to initialize a repo, fetch, and checkout a revision
// Returns the 40 character commit SHA after the checkout has been performed
func checkoutRevision(gitClient git.Client, commitSHA string) (string, error) {
err := gitClient.Fetch()
err := gitClient.Init()
if err != nil {
return "", err
return "", status.Errorf(codes.Internal, "Failed to initialize git repo: %v", err)
}
err = gitClient.Fetch()
if err != nil {
return "", status.Errorf(codes.Internal, "Failed to fetch git repo: %v", err)
}
err = gitClient.Checkout(commitSHA)
if err != nil {
return "", err
return "", status.Errorf(codes.Internal, "Failed to checkout %s: %v", commitSHA, err)
}
return gitClient.CommitSHA()
}

View File

@@ -51,7 +51,7 @@ func (m *ApplicationQuery) Reset() { *m = ApplicationQuery{} }
func (m *ApplicationQuery) String() string { return proto.CompactTextString(m) }
func (*ApplicationQuery) ProtoMessage() {}
func (*ApplicationQuery) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{0}
return fileDescriptor_application_7f078bb160e6090a, []int{0}
}
func (m *ApplicationQuery) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -115,7 +115,7 @@ func (m *ApplicationResourceEventsQuery) Reset() { *m = ApplicationResou
func (m *ApplicationResourceEventsQuery) String() string { return proto.CompactTextString(m) }
func (*ApplicationResourceEventsQuery) ProtoMessage() {}
func (*ApplicationResourceEventsQuery) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{1}
return fileDescriptor_application_7f078bb160e6090a, []int{1}
}
func (m *ApplicationResourceEventsQuery) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -178,7 +178,7 @@ func (m *ApplicationManifestQuery) Reset() { *m = ApplicationManifestQue
func (m *ApplicationManifestQuery) String() string { return proto.CompactTextString(m) }
func (*ApplicationManifestQuery) ProtoMessage() {}
func (*ApplicationManifestQuery) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{2}
return fileDescriptor_application_7f078bb160e6090a, []int{2}
}
func (m *ApplicationManifestQuery) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -231,7 +231,7 @@ func (m *ApplicationResponse) Reset() { *m = ApplicationResponse{} }
func (m *ApplicationResponse) String() string { return proto.CompactTextString(m) }
func (*ApplicationResponse) ProtoMessage() {}
func (*ApplicationResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{3}
return fileDescriptor_application_7f078bb160e6090a, []int{3}
}
func (m *ApplicationResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -272,7 +272,7 @@ func (m *ApplicationCreateRequest) Reset() { *m = ApplicationCreateReque
func (m *ApplicationCreateRequest) String() string { return proto.CompactTextString(m) }
func (*ApplicationCreateRequest) ProtoMessage() {}
func (*ApplicationCreateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{4}
return fileDescriptor_application_7f078bb160e6090a, []int{4}
}
func (m *ApplicationCreateRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -326,7 +326,7 @@ func (m *ApplicationUpdateRequest) Reset() { *m = ApplicationUpdateReque
func (m *ApplicationUpdateRequest) String() string { return proto.CompactTextString(m) }
func (*ApplicationUpdateRequest) ProtoMessage() {}
func (*ApplicationUpdateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{5}
return fileDescriptor_application_7f078bb160e6090a, []int{5}
}
func (m *ApplicationUpdateRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -374,7 +374,7 @@ func (m *ApplicationDeleteRequest) Reset() { *m = ApplicationDeleteReque
func (m *ApplicationDeleteRequest) String() string { return proto.CompactTextString(m) }
func (*ApplicationDeleteRequest) ProtoMessage() {}
func (*ApplicationDeleteRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{6}
return fileDescriptor_application_7f078bb160e6090a, []int{6}
}
func (m *ApplicationDeleteRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -434,7 +434,7 @@ func (m *ApplicationSyncRequest) Reset() { *m = ApplicationSyncRequest{}
func (m *ApplicationSyncRequest) String() string { return proto.CompactTextString(m) }
func (*ApplicationSyncRequest) ProtoMessage() {}
func (*ApplicationSyncRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{7}
return fileDescriptor_application_7f078bb160e6090a, []int{7}
}
func (m *ApplicationSyncRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -505,6 +505,8 @@ func (m *ApplicationSyncRequest) GetParameter() *ParameterOverrides {
return nil
}
// ParameterOverrides is a wrapper on a list of parameters. If omitted, the application's overrides
// in the spec will be used. If set, will use the supplied list of overrides
type ParameterOverrides struct {
Overrides []*Parameter `protobuf:"bytes,1,rep,name=overrides" json:"overrides,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
@@ -516,7 +518,7 @@ func (m *ParameterOverrides) Reset() { *m = ParameterOverrides{} }
func (m *ParameterOverrides) String() string { return proto.CompactTextString(m) }
func (*ParameterOverrides) ProtoMessage() {}
func (*ParameterOverrides) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{8}
return fileDescriptor_application_7f078bb160e6090a, []int{8}
}
func (m *ParameterOverrides) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -565,7 +567,7 @@ func (m *Parameter) Reset() { *m = Parameter{} }
func (m *Parameter) String() string { return proto.CompactTextString(m) }
func (*Parameter) ProtoMessage() {}
func (*Parameter) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{9}
return fileDescriptor_application_7f078bb160e6090a, []int{9}
}
func (m *Parameter) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -628,7 +630,7 @@ func (m *ApplicationUpdateSpecRequest) Reset() { *m = ApplicationUpdateS
func (m *ApplicationUpdateSpecRequest) String() string { return proto.CompactTextString(m) }
func (*ApplicationUpdateSpecRequest) ProtoMessage() {}
func (*ApplicationUpdateSpecRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{10}
return fileDescriptor_application_7f078bb160e6090a, []int{10}
}
func (m *ApplicationUpdateSpecRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -685,7 +687,7 @@ func (m *ApplicationRollbackRequest) Reset() { *m = ApplicationRollbackR
func (m *ApplicationRollbackRequest) String() string { return proto.CompactTextString(m) }
func (*ApplicationRollbackRequest) ProtoMessage() {}
func (*ApplicationRollbackRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{11}
return fileDescriptor_application_7f078bb160e6090a, []int{11}
}
func (m *ApplicationRollbackRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -756,7 +758,7 @@ func (m *ApplicationDeleteResourceRequest) Reset() { *m = ApplicationDel
func (m *ApplicationDeleteResourceRequest) String() string { return proto.CompactTextString(m) }
func (*ApplicationDeleteResourceRequest) ProtoMessage() {}
func (*ApplicationDeleteResourceRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{12}
return fileDescriptor_application_7f078bb160e6090a, []int{12}
}
func (m *ApplicationDeleteResourceRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -830,7 +832,7 @@ func (m *ApplicationPodLogsQuery) Reset() { *m = ApplicationPodLogsQuery
func (m *ApplicationPodLogsQuery) String() string { return proto.CompactTextString(m) }
func (*ApplicationPodLogsQuery) ProtoMessage() {}
func (*ApplicationPodLogsQuery) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{13}
return fileDescriptor_application_7f078bb160e6090a, []int{13}
}
func (m *ApplicationPodLogsQuery) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -920,7 +922,7 @@ func (m *LogEntry) Reset() { *m = LogEntry{} }
func (m *LogEntry) String() string { return proto.CompactTextString(m) }
func (*LogEntry) ProtoMessage() {}
func (*LogEntry) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{14}
return fileDescriptor_application_7f078bb160e6090a, []int{14}
}
func (m *LogEntry) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -974,7 +976,7 @@ func (m *OperationTerminateRequest) Reset() { *m = OperationTerminateReq
func (m *OperationTerminateRequest) String() string { return proto.CompactTextString(m) }
func (*OperationTerminateRequest) ProtoMessage() {}
func (*OperationTerminateRequest) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{15}
return fileDescriptor_application_7f078bb160e6090a, []int{15}
}
func (m *OperationTerminateRequest) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -1020,7 +1022,7 @@ func (m *OperationTerminateResponse) Reset() { *m = OperationTerminateRe
func (m *OperationTerminateResponse) String() string { return proto.CompactTextString(m) }
func (*OperationTerminateResponse) ProtoMessage() {}
func (*OperationTerminateResponse) Descriptor() ([]byte, []int) {
return fileDescriptor_application_139f86dca173329e, []int{16}
return fileDescriptor_application_7f078bb160e6090a, []int{16}
}
func (m *OperationTerminateResponse) XXX_Unmarshal(b []byte) error {
return m.Unmarshal(b)
@@ -4875,10 +4877,10 @@ var (
)
func init() {
proto.RegisterFile("server/application/application.proto", fileDescriptor_application_139f86dca173329e)
proto.RegisterFile("server/application/application.proto", fileDescriptor_application_7f078bb160e6090a)
}
var fileDescriptor_application_139f86dca173329e = []byte{
var fileDescriptor_application_7f078bb160e6090a = []byte{
// 1407 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x58, 0xcf, 0x6f, 0xdc, 0x44,
0x14, 0x66, 0x76, 0x37, 0x9b, 0xec, 0x4b, 0x85, 0x60, 0x68, 0x83, 0x31, 0x69, 0xb2, 0x9a, 0xa6,

View File

@@ -313,7 +313,6 @@ func validateProject(p *v1alpha1.AppProject) error {
} else {
return status.Errorf(codes.AlreadyExists, "can't have duplicate roles: role '%s' already exists", role.Name)
}
}
return nil
@@ -367,6 +366,13 @@ func (s *Server) Update(ctx context.Context, q *ProjectUpdateRequest) (*v1alpha1
return nil, status.Errorf(
codes.InvalidArgument, "following source repos are used by one or more application and cannot be removed: %s", strings.Join(removedSrcUsed, ";"))
}
for i, role := range q.Project.Spec.Roles {
var normalizedPolicies []string
for _, policy := range role.Policies {
normalizedPolicies = append(normalizedPolicies, normalizePolicy(policy))
}
q.Project.Spec.Roles[i].Policies = normalizedPolicies
}
res, err := s.appclientset.ArgoprojV1alpha1().AppProjects(s.ns).Update(q.Project)
if err == nil {
@@ -375,6 +381,19 @@ func (s *Server) Update(ctx context.Context, q *ProjectUpdateRequest) (*v1alpha1
return res, err
}
func normalizePolicy(policy string) string {
policyComponents := strings.Split(policy, ",")
normalizedPolicy := ""
for _, component := range policyComponents {
if normalizedPolicy == "" {
normalizedPolicy = component
} else {
normalizedPolicy = fmt.Sprintf("%s, %s", normalizedPolicy, strings.Trim(component, " "))
}
}
return normalizedPolicy
}
// Delete deletes a project
func (s *Server) Delete(ctx context.Context, q *ProjectQuery) (*EmptyResponse, error) {
if q.Name == common.DefaultAppProjectName {

View File

@@ -3,6 +3,7 @@ package project
import (
"context"
"fmt"
"strings"
"testing"
"github.com/stretchr/testify/assert"
@@ -326,4 +327,25 @@ func TestProjectServer(t *testing.T) {
expectedErr := fmt.Sprintf("rpc error: code = InvalidArgument desc = incorrect policy format for '%s' as effect can only have value 'allow' or 'deny'", invalidPolicy)
assert.EqualError(t, err, expectedErr)
})
t.Run("TestNormalizeProjectRolePolicies", func(t *testing.T) {
action := "create"
object := "testApplication"
roleName := "testRole"
effect := "allow"
projWithRole := existingProj.DeepCopy()
role := v1alpha1.ProjectRole{Name: roleName, JWTTokens: []v1alpha1.JWTToken{{IssuedAt: 1}}}
noSpacesPolicyTemplate := strings.Replace(policyTemplate, " ", "", -1)
invalidPolicy := fmt.Sprintf(noSpacesPolicyTemplate, projWithRole.Name, roleName, action, projWithRole.Name, object, effect)
role.Policies = append(role.Policies, invalidPolicy)
projWithRole.Spec.Roles = append(projWithRole.Spec.Roles, role)
projectServer := NewServer("default", fake.NewSimpleClientset(), apps.NewSimpleClientset(projWithRole), enforcer, util.NewKeyLock(), nil)
request := &ProjectUpdateRequest{Project: projWithRole}
updateProj, err := projectServer.Update(context.Background(), request)
assert.Nil(t, err)
expectedPolicy := fmt.Sprintf(policyTemplate, projWithRole.Name, roleName, action, projWithRole.Name, object, effect)
assert.Equal(t, expectedPolicy, updateProj.Spec.Roles[0].Policies[0])
})
}

View File

@@ -367,6 +367,8 @@ func (a *ArgoCDServer) newGRPCServer() *grpc.Server {
sensitiveMethods := map[string]bool{
"/session.SessionService/Create": true,
"/account.AccountService/UpdatePassword": true,
"/repository.RepositoryService/Create": true,
"/repository.RepositoryService/Update": true,
}
// NOTE: notice we do not configure the gRPC server here with TLS (e.g. grpc.Creds(creds))
// This is because TLS handshaking occurs in cmux handling

View File

@@ -1358,6 +1358,7 @@
},
"applicationParameterOverrides": {
"type": "object",
"title": "ParameterOverrides is a wrapper on a list of parameters. If omitted, the application's overrides\nin the spec will be used. If set, will use the supplied list of overrides",
"properties": {
"overrides": {
"type": "array",

View File

@@ -2,11 +2,8 @@ package git
import (
"fmt"
"io/ioutil"
"net/url"
"os"
"os/exec"
"path"
"strings"
log "github.com/sirupsen/logrus"
@@ -29,7 +26,6 @@ type Client interface {
LsRemote(revision string) (string, error)
LsFiles(path string) ([]string, error)
CommitSHA() (string, error)
Reset() error
}
// ClientFactory is a factory of Git Clients
@@ -40,12 +36,9 @@ type ClientFactory interface {
// nativeGitClient implements Client interface using git CLI
type nativeGitClient struct {
repoURL string
root string
username string
password string
sshPrivateKey string
auth transport.AuthMethod
repoURL string
root string
auth transport.AuthMethod
}
type factory struct{}
@@ -56,11 +49,8 @@ func NewFactory() ClientFactory {
func (f *factory) NewClient(repoURL, path, username, password, sshPrivateKey string) (Client, error) {
clnt := nativeGitClient{
repoURL: repoURL,
root: path,
username: username,
password: password,
sshPrivateKey: sshPrivateKey,
repoURL: repoURL,
root: path,
}
if sshPrivateKey != "" {
signer, err := ssh.ParsePrivateKey([]byte(sshPrivateKey))
@@ -83,91 +73,61 @@ func (m *nativeGitClient) Root() string {
// Init initializes a local git repository and sets the remote origin
func (m *nativeGitClient) Init() error {
var needInit bool
if _, err := os.Stat(m.root); os.IsNotExist(err) {
needInit = true
} else {
_, err = m.runCmd("git", "status")
needInit = err != nil
_, err := git.PlainOpen(m.root)
if err == nil {
return nil
}
if needInit {
log.Infof("Initializing %s to %s", m.repoURL, m.root)
_, err := exec.Command("rm", "-rf", m.root).Output()
if err != nil {
return fmt.Errorf("unable to clean repo at %s: %v", m.root, err)
}
err = os.MkdirAll(m.root, 0755)
if err != nil {
return err
}
if _, err := m.runCmd("git", "init"); err != nil {
return err
}
if _, err := m.runCmd("git", "remote", "add", "origin", m.repoURL); err != nil {
return err
}
if err != git.ErrRepositoryNotExists {
return err
}
// always set credentials since it can change
err := m.setCredentials()
log.Infof("Initializing %s to %s", m.repoURL, m.root)
_, err = exec.Command("rm", "-rf", m.root).Output()
if err != nil {
return fmt.Errorf("unable to clean repo at %s: %v", m.root, err)
}
err = os.MkdirAll(m.root, 0755)
if err != nil {
return err
}
return nil
}
// setCredentials sets a local credentials file to connect to a remote git repository
func (m *nativeGitClient) setCredentials() error {
if m.password != "" {
log.Debug("Setting password credentials")
gitCredentialsFile := path.Join(m.root, ".git", "credentials")
urlObj, err := url.ParseRequestURI(m.repoURL)
if err != nil {
return err
}
urlObj.User = url.UserPassword(m.username, m.password)
cmdURL := urlObj.String()
err = ioutil.WriteFile(gitCredentialsFile, []byte(cmdURL), 0600)
if err != nil {
return fmt.Errorf("failed to set git credentials: %v", err)
}
_, err = m.runCmd("git", "config", "--local", "credential.helper", fmt.Sprintf("store --file=%s", gitCredentialsFile))
if err != nil {
return err
}
repo, err := git.PlainInit(m.root, false)
if err != nil {
return err
}
if IsSSHURL(m.repoURL) {
sshCmd := gitSSHCommand
if m.sshPrivateKey != "" {
log.Debug("Setting SSH credentials")
sshPrivateKeyFile := path.Join(m.root, ".git", "ssh-private-key")
err := ioutil.WriteFile(sshPrivateKeyFile, []byte(m.sshPrivateKey), 0600)
if err != nil {
return fmt.Errorf("failed to set git credentials: %v", err)
}
sshCmd += " -i " + sshPrivateKeyFile
}
_, err := m.runCmd("git", "config", "--local", "core.sshCommand", sshCmd)
if err != nil {
return err
}
}
return nil
_, err = repo.CreateRemote(&config.RemoteConfig{
Name: git.DefaultRemoteName,
URLs: []string{m.repoURL},
})
return err
}
// Fetch fetches latest updates from origin
func (m *nativeGitClient) Fetch() error {
var err error
log.Debugf("Fetching repo %s at %s", m.repoURL, m.root)
if _, err = m.runCmd("git", "fetch", "origin", "--tags", "--force"); err != nil {
repo, err := git.PlainOpen(m.root)
if err != nil {
return err
}
log.Debug("git fetch origin --tags --force")
err = repo.Fetch(&git.FetchOptions{
RemoteName: git.DefaultRemoteName,
Auth: m.auth,
Tags: git.AllTags,
Force: true,
})
if err == git.NoErrAlreadyUpToDate {
return nil
}
return err
// git fetch does not update the HEAD reference. The following command will update the local
// knowledge of what remote considers the “default branch”
// See: https://stackoverflow.com/questions/8839958/how-does-origin-head-get-set
if _, err := m.runCmd("git", "remote", "set-head", "origin", "-a"); err != nil {
return err
}
return nil
// NOTE(jessesuen): disabling the following code because:
// 1. we no longer perform a `git checkout HEAD`, instead relying on `ls-remote` and checking
// out a specific SHA1.
// 2. This command is the only other command that we use (excluding fetch/ls-remote) which
// requires remote access, and there appears to be no go-git equivalent to this command.
// _, err = m.runCmd("git", "remote", "set-head", "origin", "-a")
// return err
}
// LsFiles lists the local working tree, including only files that are under source control
@@ -181,34 +141,6 @@ func (m *nativeGitClient) LsFiles(path string) ([]string, error) {
return ss[:len(ss)-1], nil
}
// Reset resets local changes in a repository
func (m *nativeGitClient) Reset() error {
if _, err := m.runCmd("git", "reset", "--hard", "origin/HEAD"); err != nil {
return err
}
// Delete all local branches (we must first detach so we are not checked out a branch we are about to delete)
if _, err := m.runCmd("git", "checkout", "--detach", "origin/HEAD"); err != nil {
return err
}
branchesOut, err := m.runCmd("git", "for-each-ref", "--format=%(refname:short)", "refs/heads/")
if err != nil {
return err
}
branchesOut = strings.TrimSpace(branchesOut)
if branchesOut != "" {
branches := strings.Split(branchesOut, "\n")
args := []string{"branch", "-D"}
args = append(args, branches...)
if _, err = m.runCmd("git", args...); err != nil {
return err
}
}
if _, err := m.runCmd("git", "clean", "-fd"); err != nil {
return err
}
return nil
}
// Checkout checkout specified git sha
func (m *nativeGitClient) Checkout(revision string) error {
if revision == "" || revision == "HEAD" {
@@ -243,7 +175,7 @@ func (m *nativeGitClient) LsRemote(revision string) (string, error) {
if err != nil {
return "", err
}
refs, err := remote.List(&git.ListOptions{})
refs, err := remote.List(&git.ListOptions{Auth: m.auth})
if err != nil {
return "", err
}
@@ -310,6 +242,8 @@ func (m *nativeGitClient) runCmd(command string, args ...string) (string, error)
log.Debug(strings.Join(cmd.Args, " "))
cmd.Dir = m.root
env := os.Environ()
env = append(env, "HOME=/dev/null")
env = append(env, "GIT_CONFIG_NOSYSTEM=true")
env = append(env, "GIT_ASKPASS=")
cmd.Env = env
out, err := cmd.Output()

View File

@@ -1,12 +1,7 @@
package git
import (
"errors"
"fmt"
"io/ioutil"
"net/url"
"os"
"os/exec"
"regexp"
"strings"
)
@@ -43,93 +38,45 @@ func IsTruncatedCommitSHA(sha string) bool {
// NormalizeGitURL normalizes a git URL for lookup and storage
func NormalizeGitURL(repo string) string {
// preprocess
repo = strings.TrimSpace(repo)
repo = ensureSuffix(repo, ".git")
if IsSSHURL(repo) {
repo = ensurePrefix(repo, "ssh://")
}
// process
if !isAzureGitURL(repo) {
// NOTE: not all git services support `.git` appended to their URLs (e.g. azure) so this
// normalization is not entirely safe.
repo = ensureSuffix(repo, ".git")
}
repoURL, err := url.Parse(repo)
if err != nil {
return ""
}
// postprocess
repoURL.Host = strings.ToLower(repoURL.Host)
normalized := repoURL.String()
return strings.TrimPrefix(normalized, "ssh://")
}
// isAzureGitURL returns true if supplied URL is from an Azure domain
func isAzureGitURL(repo string) bool {
repoURL, err := url.Parse(repo)
if err != nil {
return false
}
hostname := repoURL.Hostname()
return strings.HasSuffix(hostname, "dev.azure.com") || strings.HasSuffix(hostname, "visualstudio.com")
}
// IsSSHURL returns true if supplied URL is SSH URL
func IsSSHURL(url string) bool {
return strings.HasPrefix(url, "git@") || strings.HasPrefix(url, "ssh://")
}
const gitSSHCommand = "ssh -q -F /dev/null -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=20"
//TODO: Make sure every public method works with '*' repo
// GetGitCommandEnvAndURL returns URL and env options for git operation
func GetGitCommandEnvAndURL(repo, username, password string, sshPrivateKey string) (string, []string, error) {
cmdURL := repo
env := os.Environ()
if IsSSHURL(repo) {
sshCmd := gitSSHCommand
if sshPrivateKey != "" {
sshFile, err := ioutil.TempFile("", "")
if err != nil {
return "", nil, err
}
_, err = sshFile.WriteString(sshPrivateKey)
if err != nil {
return "", nil, err
}
err = sshFile.Close()
if err != nil {
return "", nil, err
}
sshCmd += " -i " + sshFile.Name()
}
env = append(env, fmt.Sprintf("GIT_SSH_COMMAND=%s", sshCmd))
} else {
env = append(env, "GIT_ASKPASS=")
repoURL, err := url.ParseRequestURI(repo)
if err != nil {
return "", nil, err
}
repoURL.User = url.UserPassword(username, password)
cmdURL = repoURL.String()
}
return cmdURL, env, nil
}
// TestRepo tests if a repo exists and is accessible with the given credentials
func TestRepo(repo, username, password string, sshPrivateKey string) error {
repo, env, err := GetGitCommandEnvAndURL(repo, username, password, sshPrivateKey)
clnt, err := NewFactory().NewClient(repo, "", username, password, sshPrivateKey)
if err != nil {
return err
}
cmd := exec.Command("git", "ls-remote", repo, "HEAD")
cmd.Env = env
_, err = cmd.Output()
if err != nil {
if exErr, ok := err.(*exec.ExitError); ok {
errOutput := strings.Split(string(exErr.Stderr), "\n")[0]
errOutput = fmt.Sprintf("%s: %s", repo, errOutput)
return errors.New(redactPassword(errOutput, password))
}
return err
}
return nil
}
func redactPassword(msg string, password string) string {
if password != "" {
passwordRegexp := regexp.MustCompile("\\b" + regexp.QuoteMeta(password) + "\\b")
msg = passwordRegexp.ReplaceAllString(msg, "*****")
}
return msg
_, err = clnt.LsRemote("HEAD")
return err
}

View File

@@ -72,20 +72,22 @@ func TestIsSSHURL(t *testing.T) {
func TestNormalizeUrl(t *testing.T) {
data := map[string]string{
"git@GITHUB.com:argoproj/test": "git@github.com:argoproj/test.git",
"git@GITHUB.com:argoproj/test.git": "git@github.com:argoproj/test.git",
"git@GITHUB.com:test": "git@github.com:test.git",
"git@GITHUB.com:test.git": "git@github.com:test.git",
"https://GITHUB.com/argoproj/test": "https://github.com/argoproj/test.git",
"https://GITHUB.com/argoproj/test.git": "https://github.com/argoproj/test.git",
"https://github.com/TEST": "https://github.com/TEST.git",
"https://github.com/TEST.git": "https://github.com/TEST.git",
"ssh://git@GITHUB.com:argoproj/test": "git@github.com:argoproj/test.git",
"ssh://git@GITHUB.com:argoproj/test.git": "git@github.com:argoproj/test.git",
"ssh://git@GITHUB.com:test.git": "git@github.com:test.git",
"ssh://git@github.com:test": "git@github.com:test.git",
" https://github.com/argoproj/test ": "https://github.com/argoproj/test.git",
"\thttps://github.com/argoproj/test\n": "https://github.com/argoproj/test.git",
"git@GITHUB.com:argoproj/test": "git@github.com:argoproj/test.git",
"git@GITHUB.com:argoproj/test.git": "git@github.com:argoproj/test.git",
"git@GITHUB.com:test": "git@github.com:test.git",
"git@GITHUB.com:test.git": "git@github.com:test.git",
"https://GITHUB.com/argoproj/test": "https://github.com/argoproj/test.git",
"https://GITHUB.com/argoproj/test.git": "https://github.com/argoproj/test.git",
"https://github.com/TEST": "https://github.com/TEST.git",
"https://github.com/TEST.git": "https://github.com/TEST.git",
"ssh://git@GITHUB.com:argoproj/test": "git@github.com:argoproj/test.git",
"ssh://git@GITHUB.com:argoproj/test.git": "git@github.com:argoproj/test.git",
"ssh://git@GITHUB.com:test.git": "git@github.com:test.git",
"ssh://git@github.com:test": "git@github.com:test.git",
" https://github.com/argoproj/test ": "https://github.com/argoproj/test.git",
"\thttps://github.com/argoproj/test\n": "https://github.com/argoproj/test.git",
"https://1234.visualstudio.com/myproj/_git/myrepo": "https://1234.visualstudio.com/myproj/_git/myrepo",
"https://dev.azure.com/1234/myproj/_git/myrepo": "https://dev.azure.com/1234/myproj/_git/myrepo",
}
for k, v := range data {
assert.Equal(t, v, NormalizeGitURL(k))

View File

@@ -226,6 +226,11 @@ func IsCRD(obj *unstructured.Unstructured) bool {
return IsCRDGroupVersionKind(obj.GroupVersionKind())
}
// temporal solution for https://github.com/argoproj/argo-cd/issues/650.
func isExcludedResourceGroup(resource metav1.APIResource) bool {
return resource.Group == "servicecatalog.k8s.io"
}
func WatchResourcesWithLabel(ctx context.Context, config *rest.Config, namespace string, labelName string) (chan watch.Event, error) {
log.Infof("Start watching for resources changes with label %s in cluster %s", labelName, config.Host)
dynClientPool := dynamic.NewDynamicClientPool(config)
@@ -249,7 +254,7 @@ func WatchResourcesWithLabel(ctx context.Context, config *rest.Config, namespace
break
}
}
if watchSupported {
if watchSupported && !isExcludedResourceGroup(apiResource) {
dclient, err := dynClientPool.ClientForGroupVersionKind(schema.FromAPIVersionAndKind(apiResourcesList.GroupVersion, apiResource.Kind))
if err != nil {
return nil, err
@@ -323,7 +328,7 @@ func GetResourcesWithLabel(config *rest.Config, namespace string, labelName stri
break
}
}
if listSupported {
if listSupported && !isExcludedResourceGroup(apiResource) {
dclient, err := dynClientPool.ClientForGroupVersionKind(schema.FromAPIVersionAndKind(apiResourcesList.GroupVersion, apiResource.Kind))
if err != nil {
return nil, err
@@ -403,7 +408,9 @@ func DeleteResourceWithLabel(config *rest.Config, namespace string, labelName st
return err
}
if deleteCollectionSupported || deleteSupported && !IsCRDGroupVersionKind(schema.FromAPIVersionAndKind(apiResourcesList.GroupVersion, apiResource.Kind)) {
if (deleteCollectionSupported || deleteSupported) &&
!IsCRDGroupVersionKind(schema.FromAPIVersionAndKind(apiResourcesList.GroupVersion, apiResource.Kind)) &&
!isExcludedResourceGroup(apiResource) {
resourceInterfaces = append(resourceInterfaces, resClient{
dclient.Resource(&apiResource, namespace),
deleteCollectionSupported,