mirror of
https://github.com/portainer/portainer.git
synced 2025-07-24 15:59:41 +02:00
fix(git) EE-2026 git default branch (#6876)
fix(git) EE-2026 git default branch
This commit is contained in:
parent
0ffb84aaa6
commit
df05914fac
19 changed files with 167 additions and 127 deletions
|
@ -177,9 +177,6 @@ func (payload *composeStackFromGitRepositoryPayload) Validate(r *http.Request) e
|
|||
if govalidator.IsNull(payload.RepositoryURL) || !govalidator.IsURL(payload.RepositoryURL) {
|
||||
return errors.New("Invalid repository URL. Must correspond to a valid URL format")
|
||||
}
|
||||
if govalidator.IsNull(payload.RepositoryReferenceName) {
|
||||
payload.RepositoryReferenceName = defaultGitReferenceName
|
||||
}
|
||||
if payload.RepositoryAuthentication && govalidator.IsNull(payload.RepositoryPassword) {
|
||||
return errors.New("Invalid repository credentials. Password must be specified when authentication is enabled")
|
||||
}
|
||||
|
|
|
@ -70,9 +70,6 @@ func (payload *kubernetesGitDeploymentPayload) Validate(r *http.Request) error {
|
|||
if govalidator.IsNull(payload.ManifestFile) {
|
||||
return errors.New("Invalid manifest file in repository")
|
||||
}
|
||||
if govalidator.IsNull(payload.RepositoryReferenceName) {
|
||||
payload.RepositoryReferenceName = defaultGitReferenceName
|
||||
}
|
||||
if err := validateStackAutoUpdate(payload.AutoUpdate); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -144,9 +144,6 @@ func (payload *swarmStackFromGitRepositoryPayload) Validate(r *http.Request) err
|
|||
if govalidator.IsNull(payload.RepositoryURL) || !govalidator.IsURL(payload.RepositoryURL) {
|
||||
return errors.New("Invalid repository URL. Must correspond to a valid URL format")
|
||||
}
|
||||
if govalidator.IsNull(payload.RepositoryReferenceName) {
|
||||
payload.RepositoryReferenceName = defaultGitReferenceName
|
||||
}
|
||||
if payload.RepositoryAuthentication && govalidator.IsNull(payload.RepositoryPassword) {
|
||||
return errors.New("Invalid repository credentials. Password must be specified when authentication is enabled")
|
||||
}
|
||||
|
|
|
@ -21,8 +21,6 @@ import (
|
|||
"github.com/portainer/portainer/api/stacks"
|
||||
)
|
||||
|
||||
const defaultGitReferenceName = "refs/heads/master"
|
||||
|
||||
var (
|
||||
errStackAlreadyExists = errors.New("A stack already exists with this name")
|
||||
errWebhookIDAlreadyExists = errors.New("A webhook ID already exists")
|
||||
|
|
|
@ -4,7 +4,6 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/pkg/errors"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
|
@ -26,10 +25,6 @@ type stackGitUpdatePayload struct {
|
|||
}
|
||||
|
||||
func (payload *stackGitUpdatePayload) Validate(r *http.Request) error {
|
||||
if govalidator.IsNull(payload.RepositoryReferenceName) {
|
||||
payload.RepositoryReferenceName = defaultGitReferenceName
|
||||
}
|
||||
|
||||
if err := validateStackAutoUpdate(payload.AutoUpdate); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -6,7 +6,6 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/pkg/errors"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
|
@ -28,9 +27,6 @@ type stackGitRedployPayload struct {
|
|||
}
|
||||
|
||||
func (payload *stackGitRedployPayload) Validate(r *http.Request) error {
|
||||
if govalidator.IsNull(payload.RepositoryReferenceName) {
|
||||
payload.RepositoryReferenceName = defaultGitReferenceName
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -38,9 +38,6 @@ func (payload *kubernetesFileStackUpdatePayload) Validate(r *http.Request) error
|
|||
}
|
||||
|
||||
func (payload *kubernetesGitStackUpdatePayload) Validate(r *http.Request) error {
|
||||
if govalidator.IsNull(payload.RepositoryReferenceName) {
|
||||
payload.RepositoryReferenceName = defaultGitReferenceName
|
||||
}
|
||||
if err := validateStackAutoUpdate(payload.AutoUpdate); err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
@ -64,7 +64,7 @@ func (factory *ProxyFactory) newDockerHTTPProxy(endpoint *portainer.Endpoint) (h
|
|||
DockerClientFactory: factory.dockerClientFactory,
|
||||
}
|
||||
|
||||
dockerTransport, err := docker.NewTransport(transportParameters, httpTransport)
|
||||
dockerTransport, err := docker.NewTransport(transportParameters, httpTransport, factory.gitService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ type (
|
|||
signatureService portainer.DigitalSignatureService
|
||||
reverseTunnelService portainer.ReverseTunnelService
|
||||
dockerClientFactory *docker.ClientFactory
|
||||
gitService portainer.GitService
|
||||
}
|
||||
|
||||
// TransportParameters is used to create a new Transport
|
||||
|
@ -62,7 +63,7 @@ type (
|
|||
)
|
||||
|
||||
// NewTransport returns a pointer to a new Transport instance.
|
||||
func NewTransport(parameters *TransportParameters, httpTransport *http.Transport) (*Transport, error) {
|
||||
func NewTransport(parameters *TransportParameters, httpTransport *http.Transport, gitService portainer.GitService) (*Transport, error) {
|
||||
transport := &Transport{
|
||||
endpoint: parameters.Endpoint,
|
||||
dataStore: parameters.DataStore,
|
||||
|
@ -70,6 +71,7 @@ func NewTransport(parameters *TransportParameters, httpTransport *http.Transport
|
|||
reverseTunnelService: parameters.ReverseTunnelService,
|
||||
dockerClientFactory: parameters.DockerClientFactory,
|
||||
HTTPTransport: httpTransport,
|
||||
gitService: gitService,
|
||||
}
|
||||
|
||||
return transport, nil
|
||||
|
@ -381,9 +383,31 @@ func (transport *Transport) proxyTaskRequest(request *http.Request) (*http.Respo
|
|||
}
|
||||
|
||||
func (transport *Transport) proxyBuildRequest(request *http.Request) (*http.Response, error) {
|
||||
err := transport.updateDefaultGitBranch(request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return transport.interceptAndRewriteRequest(request, buildOperation)
|
||||
}
|
||||
|
||||
func (transport *Transport) updateDefaultGitBranch(request *http.Request) error {
|
||||
remote := request.URL.Query().Get("remote")
|
||||
if strings.HasSuffix(remote, ".git") {
|
||||
repositoryURL := remote[:len(remote)-4]
|
||||
latestCommitID, err := transport.gitService.LatestCommitID(repositoryURL, "", "", "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newRemote := fmt.Sprintf("%s#%s", remote, latestCommitID)
|
||||
|
||||
q := request.URL.Query()
|
||||
q.Set("remote", newRemote)
|
||||
request.URL.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (transport *Transport) proxyImageRequest(request *http.Request) (*http.Response, error) {
|
||||
switch requestPath := request.URL.Path; requestPath {
|
||||
case "/images/create":
|
||||
|
|
73
api/http/proxy/factory/docker/transport_test.go
Normal file
73
api/http/proxy/factory/docker/transport_test.go
Normal file
|
@ -0,0 +1,73 @@
|
|||
package docker
|
||||
|
||||
import (
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type noopGitService struct{}
|
||||
|
||||
func (s *noopGitService) CloneRepository(destination string, repositoryURL, referenceName, username, password string) error {
|
||||
return nil
|
||||
}
|
||||
func (s *noopGitService) LatestCommitID(repositoryURL, referenceName, username, password string) (string, error) {
|
||||
return "my-latest-commit-id", nil
|
||||
}
|
||||
|
||||
func TestTransport_updateDefaultGitBranch(t *testing.T) {
|
||||
type fields struct {
|
||||
gitService portainer.GitService
|
||||
}
|
||||
|
||||
type args struct {
|
||||
request *http.Request
|
||||
}
|
||||
|
||||
defaultFields := fields{
|
||||
gitService: &noopGitService{},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
fields fields
|
||||
args args
|
||||
wantErr bool
|
||||
expectedQuery string
|
||||
}{
|
||||
{
|
||||
name: "append commit ID",
|
||||
fields: defaultFields,
|
||||
args: args{
|
||||
request: httptest.NewRequest(http.MethodPost, "http://unixsocket/build?dockerfile=Dockerfile&remote=https://my-host.com/my-user/my-repo.git&t=my-image", nil),
|
||||
},
|
||||
wantErr: false,
|
||||
expectedQuery: "dockerfile=Dockerfile&remote=https%3A%2F%2Fmy-host.com%2Fmy-user%2Fmy-repo.git%23my-latest-commit-id&t=my-image",
|
||||
},
|
||||
{
|
||||
name: "not append commit ID",
|
||||
fields: defaultFields,
|
||||
args: args{
|
||||
request: httptest.NewRequest(http.MethodPost, "http://unixsocket/build?dockerfile=Dockerfile&remote=https://my-host.com/my-user/my-repo/my-file&t=my-image", nil),
|
||||
},
|
||||
wantErr: false,
|
||||
expectedQuery: "dockerfile=Dockerfile&remote=https://my-host.com/my-user/my-repo/my-file&t=my-image",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
transport := &Transport{
|
||||
gitService: tt.fields.gitService,
|
||||
}
|
||||
err := transport.updateDefaultGitBranch(tt.args.request)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("updateDefaultGitBranch() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
|
||||
assert.Equal(t, tt.expectedQuery, tt.args.request.URL.RawQuery)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ func (factory ProxyFactory) newOSBasedLocalProxy(path string, endpoint *portaine
|
|||
|
||||
proxy := &dockerLocalProxy{}
|
||||
|
||||
dockerTransport, err := docker.NewTransport(transportParameters, newSocketTransport(path))
|
||||
dockerTransport, err := docker.NewTransport(transportParameters, newSocketTransport(path), factory.gitService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ func (factory ProxyFactory) newOSBasedLocalProxy(path string, endpoint *portaine
|
|||
|
||||
proxy := &dockerLocalProxy{}
|
||||
|
||||
dockerTransport, err := docker.NewTransport(transportParameters, newNamedPipeTransport(path))
|
||||
dockerTransport, err := docker.NewTransport(transportParameters, newNamedPipeTransport(path), factory.gitService)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -23,11 +23,12 @@ type (
|
|||
dockerClientFactory *docker.ClientFactory
|
||||
kubernetesClientFactory *cli.ClientFactory
|
||||
kubernetesTokenCacheManager *kubernetes.TokenCacheManager
|
||||
gitService portainer.GitService
|
||||
}
|
||||
)
|
||||
|
||||
// NewProxyFactory returns a pointer to a new instance of a ProxyFactory
|
||||
func NewProxyFactory(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, tunnelService portainer.ReverseTunnelService, clientFactory *docker.ClientFactory, kubernetesClientFactory *cli.ClientFactory, kubernetesTokenCacheManager *kubernetes.TokenCacheManager) *ProxyFactory {
|
||||
func NewProxyFactory(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, tunnelService portainer.ReverseTunnelService, clientFactory *docker.ClientFactory, kubernetesClientFactory *cli.ClientFactory, kubernetesTokenCacheManager *kubernetes.TokenCacheManager, gitService portainer.GitService) *ProxyFactory {
|
||||
return &ProxyFactory{
|
||||
dataStore: dataStore,
|
||||
signatureService: signatureService,
|
||||
|
@ -35,6 +36,7 @@ func NewProxyFactory(dataStore dataservices.DataStore, signatureService portaine
|
|||
dockerClientFactory: clientFactory,
|
||||
kubernetesClientFactory: kubernetesClientFactory,
|
||||
kubernetesTokenCacheManager: kubernetesTokenCacheManager,
|
||||
gitService: gitService,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -25,11 +25,11 @@ type (
|
|||
)
|
||||
|
||||
// NewManager initializes a new proxy Service
|
||||
func NewManager(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, tunnelService portainer.ReverseTunnelService, clientFactory *docker.ClientFactory, kubernetesClientFactory *cli.ClientFactory, kubernetesTokenCacheManager *kubernetes.TokenCacheManager) *Manager {
|
||||
func NewManager(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, tunnelService portainer.ReverseTunnelService, clientFactory *docker.ClientFactory, kubernetesClientFactory *cli.ClientFactory, kubernetesTokenCacheManager *kubernetes.TokenCacheManager, gitService portainer.GitService) *Manager {
|
||||
return &Manager{
|
||||
endpointProxies: cmap.New(),
|
||||
k8sClientFactory: kubernetesClientFactory,
|
||||
proxyFactory: factory.NewProxyFactory(dataStore, signatureService, tunnelService, clientFactory, kubernetesClientFactory, kubernetesTokenCacheManager),
|
||||
proxyFactory: factory.NewProxyFactory(dataStore, signatureService, tunnelService, clientFactory, kubernetesClientFactory, kubernetesTokenCacheManager, gitService),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue