diff --git a/api/cli/cli.go b/api/cli/cli.go index c04f41121..5f7062c21 100644 --- a/api/cli/cli.go +++ b/api/cli/cli.go @@ -72,6 +72,7 @@ func (*Service) ParseFlags(version string) (*portainer.CLIFlags, error) { if err != nil { panic(err) } + *flags.Assets = filepath.Join(filepath.Dir(ex), *flags.Assets) } @@ -80,7 +81,6 @@ func (*Service) ParseFlags(version string) (*portainer.CLIFlags, error) { // ValidateFlags validates the values of the flags. func (*Service) ValidateFlags(flags *portainer.CLIFlags) error { - displayDeprecationWarnings(flags) err := validateEndpointURL(*flags.EndpointURL) @@ -111,31 +111,38 @@ func displayDeprecationWarnings(flags *portainer.CLIFlags) { } func validateEndpointURL(endpointURL string) error { - if endpointURL != "" { - if !strings.HasPrefix(endpointURL, "unix://") && !strings.HasPrefix(endpointURL, "tcp://") && !strings.HasPrefix(endpointURL, "npipe://") { - return errInvalidEndpointProtocol - } + if endpointURL == "" { + return nil + } - if strings.HasPrefix(endpointURL, "unix://") || strings.HasPrefix(endpointURL, "npipe://") { - socketPath := strings.TrimPrefix(endpointURL, "unix://") - socketPath = strings.TrimPrefix(socketPath, "npipe://") - if _, err := os.Stat(socketPath); err != nil { - if os.IsNotExist(err) { - return errSocketOrNamedPipeNotFound - } - return err + if !strings.HasPrefix(endpointURL, "unix://") && !strings.HasPrefix(endpointURL, "tcp://") && !strings.HasPrefix(endpointURL, "npipe://") { + return errInvalidEndpointProtocol + } + + if strings.HasPrefix(endpointURL, "unix://") || strings.HasPrefix(endpointURL, "npipe://") { + socketPath := strings.TrimPrefix(endpointURL, "unix://") + socketPath = strings.TrimPrefix(socketPath, "npipe://") + if _, err := os.Stat(socketPath); err != nil { + if os.IsNotExist(err) { + return errSocketOrNamedPipeNotFound } + + return err } } + return nil } func validateSnapshotInterval(snapshotInterval string) error { - if snapshotInterval != "" { - _, err := time.ParseDuration(snapshotInterval) - if err != nil { - return errInvalidSnapshotInterval - } + if snapshotInterval == "" { + return nil } + + _, err := time.ParseDuration(snapshotInterval) + if err != nil { + return errInvalidSnapshotInterval + } + return nil } diff --git a/api/cli/confirm.go b/api/cli/confirm.go index ac468e97e..ec1076057 100644 --- a/api/cli/confirm.go +++ b/api/cli/confirm.go @@ -12,13 +12,14 @@ func Confirm(message string) (bool, error) { fmt.Printf("%s [y/N]", message) reader := bufio.NewReader(os.Stdin) + answer, err := reader.ReadString('\n') if err != nil { return false, err } - answer = strings.Replace(answer, "\n", "", -1) + + answer = strings.ReplaceAll(answer, "\n", "") answer = strings.ToLower(answer) return answer == "y" || answer == "yes", nil - } diff --git a/api/crypto/ecdsa.go b/api/crypto/ecdsa.go index 1cd119fce..bbf839324 100644 --- a/api/crypto/ecdsa.go +++ b/api/crypto/ecdsa.go @@ -7,7 +7,6 @@ import ( "crypto/x509" "encoding/base64" "encoding/hex" - "math/big" "github.com/portainer/libcrypto" ) @@ -115,9 +114,6 @@ func (service *ECDSAService) CreateSignature(message string) (string, error) { hash := libcrypto.HashFromBytes([]byte(message)) - r := big.NewInt(0) - s := big.NewInt(0) - r, s, err := ecdsa.Sign(rand.Reader, service.privateKey, hash) if err != nil { return "", err diff --git a/api/database/boltdb/json_test.go b/api/database/boltdb/json_test.go index 2d22bfafc..3d6d83ce1 100644 --- a/api/database/boltdb/json_test.go +++ b/api/database/boltdb/json_test.go @@ -129,7 +129,7 @@ func Test_UnMarshalObjectUnencrypted(t *testing.T) { var object string err := conn.UnmarshalObject(test.object, &object) is.NoError(err) - is.Equal(test.expected, string(object)) + is.Equal(test.expected, object) }) } } diff --git a/api/database/boltdb/tx.go b/api/database/boltdb/tx.go index e62e7b2d9..c4503fde8 100644 --- a/api/database/boltdb/tx.go +++ b/api/database/boltdb/tx.go @@ -92,7 +92,7 @@ func (tx *DbTransaction) CreateObject(bucketName string, fn func(uint64) (int, i return err } - return bucket.Put(tx.conn.ConvertToKey(int(id)), data) + return bucket.Put(tx.conn.ConvertToKey(id), data) } func (tx *DbTransaction) CreateObjectWithId(bucketName string, id int, obj interface{}) error { diff --git a/api/database/database.go b/api/database/database.go index f4705cc94..492d56bcf 100644 --- a/api/database/database.go +++ b/api/database/database.go @@ -9,8 +9,7 @@ import ( // NewDatabase should use config options to return a connection to the requested database func NewDatabase(storeType, storePath string, encryptionKey []byte) (connection portainer.Connection, err error) { - switch storeType { - case "boltdb": + if storeType == "boltdb" { return &boltdb.DbConnection{ Path: storePath, EncryptionKey: encryptionKey, diff --git a/api/datastore/migrate_post_init.go b/api/datastore/migrate_post_init.go index dab0139b6..2f943c193 100644 --- a/api/datastore/migrate_post_init.go +++ b/api/datastore/migrate_post_init.go @@ -8,6 +8,7 @@ import ( "github.com/portainer/portainer/api/dataservices" "github.com/portainer/portainer/api/docker" "github.com/portainer/portainer/api/kubernetes/cli" + "github.com/rs/zerolog/log" ) @@ -17,11 +18,7 @@ type PostInitMigrator struct { dataStore dataservices.DataStore } -func NewPostInitMigrator( - kubeFactory *cli.ClientFactory, - dockerFactory *docker.ClientFactory, - dataStore dataservices.DataStore, -) *PostInitMigrator { +func NewPostInitMigrator(kubeFactory *cli.ClientFactory, dockerFactory *docker.ClientFactory, dataStore dataservices.DataStore) *PostInitMigrator { return &PostInitMigrator{ kubeFactory: kubeFactory, dockerFactory: dockerFactory, @@ -44,9 +41,10 @@ func (migrator *PostInitMigrator) PostInitMigrateIngresses() error { if err != nil { return err } + for i := range endpoints { // Early exit if we do not need to migrate! - if endpoints[i].PostInitMigrations.MigrateIngresses == false { + if !endpoints[i].PostInitMigrations.MigrateIngresses { return nil } @@ -67,10 +65,11 @@ func (migrator *PostInitMigrator) PostInitMigrateGPUs() { log.Err(err).Msg("failure getting endpoints") return } + for i := range environments { if environments[i].Type == portainer.DockerEnvironment { // // Early exit if we do not need to migrate! - if environments[i].PostInitMigrations.MigrateGPUs == false { + if !environments[i].PostInitMigrations.MigrateGPUs { return } @@ -102,11 +101,13 @@ func (migrator *PostInitMigrator) PostInitMigrateGPUs() { log.Err(err).Msg("failed to inspect container") return } + deviceRequests := containerDetails.HostConfig.Resources.DeviceRequests for _, deviceRequest := range deviceRequests { if deviceRequest.Driver == "nvidia" { environments[i].EnableGPUManagement = true migrator.dataStore.Endpoint().UpdateEndpoint(environments[i].ID, &environments[i]) + break containersLoop } } diff --git a/api/docker/client.go b/api/docker/client.go index 909fbe708..af9161b17 100644 --- a/api/docker/client.go +++ b/api/docker/client.go @@ -38,17 +38,19 @@ func NewClientFactory(signatureService portainer.DigitalSignatureService, revers // with an agent enabled environment(endpoint) to target a specific node in an agent cluster. // The underlying http client timeout may be specified, a default value is used otherwise. func (factory *ClientFactory) CreateClient(endpoint *portainer.Endpoint, nodeName string, timeout *time.Duration) (*client.Client, error) { - if endpoint.Type == portainer.AzureEnvironment { + switch endpoint.Type { + case portainer.AzureEnvironment: return nil, errUnsupportedEnvironmentType - } else if endpoint.Type == portainer.AgentOnDockerEnvironment { + case portainer.AgentOnDockerEnvironment: return createAgentClient(endpoint, factory.signatureService, nodeName, timeout) - } else if endpoint.Type == portainer.EdgeAgentOnDockerEnvironment { + case portainer.EdgeAgentOnDockerEnvironment: return createEdgeClient(endpoint, factory.signatureService, factory.reverseTunnelService, nodeName, timeout) } if strings.HasPrefix(endpoint.URL, "unix://") || strings.HasPrefix(endpoint.URL, "npipe://") { return createLocalClient(endpoint) } + return createTCPClient(endpoint, timeout) } diff --git a/api/exec/swarm_stack.go b/api/exec/swarm_stack.go index 114ac3fd4..b16cfe11a 100644 --- a/api/exec/swarm_stack.go +++ b/api/exec/swarm_stack.go @@ -59,6 +59,7 @@ func (manager *SwarmStackManager) Login(registries []portainer.Registry, endpoin if err != nil { return err } + for _, registry := range registries { if registry.Authentication { err = registryutils.EnsureRegTokenValid(manager.dataStore, ®istry) @@ -75,6 +76,7 @@ func (manager *SwarmStackManager) Login(registries []portainer.Registry, endpoin runCommandAndCaptureStdErr(command, registryArgs, nil, "") } } + return nil } @@ -84,7 +86,9 @@ func (manager *SwarmStackManager) Logout(endpoint *portainer.Endpoint) error { if err != nil { return err } + args = append(args, "logout") + return runCommandAndCaptureStdErr(command, args, nil, "") } @@ -101,6 +105,7 @@ func (manager *SwarmStackManager) Deploy(stack *portainer.Stack, prune bool, pul } else { args = append(args, "stack", "deploy", "--with-registry-auth") } + if !pullImage { args = append(args, "--resolve-image=never") } @@ -112,6 +117,7 @@ func (manager *SwarmStackManager) Deploy(stack *portainer.Stack, prune bool, pul for _, envvar := range stack.Env { env = append(env, envvar.Name+"="+envvar.Value) } + return runCommandAndCaptureStdErr(command, args, env, stack.ProjectPath) } @@ -121,7 +127,9 @@ func (manager *SwarmStackManager) Remove(stack *portainer.Stack, endpoint *porta if err != nil { return err } + args = append(args, "stack", "rm", stack.Name) + return runCommandAndCaptureStdErr(command, args, nil, "") } @@ -198,6 +206,7 @@ func (manager *SwarmStackManager) updateDockerCLIConfiguration(configPath string if config["HttpHeaders"] == nil { config["HttpHeaders"] = make(map[string]interface{}) } + headersObject := config["HttpHeaders"].(map[string]interface{}) headersObject["X-PortainerAgent-ManagerOperation"] = "1" headersObject["X-PortainerAgent-Signature"] = signature @@ -230,5 +239,6 @@ func configureFilePaths(args []string, filePaths []string) []string { for _, path := range filePaths { args = append(args, "--compose-file", path) } + return args } diff --git a/api/git/azure.go b/api/git/azure.go index 7bbe65c64..72d35802c 100644 --- a/api/git/azure.go +++ b/api/git/azure.go @@ -75,6 +75,7 @@ func newHttpClientForAzure() *http.Client { } client.InstallProtocol("https", githttp.NewClient(httpsCli)) + return httpsCli } @@ -98,10 +99,12 @@ func (a *azureClient) downloadZipFromAzureDevOps(ctx context.Context, opt cloneO if err != nil { return "", errors.WithMessage(err, "failed to parse url") } + downloadUrl, err := a.buildDownloadUrl(config, opt.referenceName) if err != nil { return "", errors.WithMessage(err, "failed to build download url") } + zipFile, err := os.CreateTemp("", "azure-git-repo-*.zip") if err != nil { return "", errors.WithMessage(err, "failed to create temp file") @@ -133,6 +136,7 @@ func (a *azureClient) downloadZipFromAzureDevOps(ctx context.Context, opt cloneO if err != nil { return "", errors.WithMessage(err, "failed to save HTTP response to a file") } + return zipFile.Name(), nil } @@ -141,6 +145,7 @@ func (a *azureClient) latestCommitID(ctx context.Context, opt fetchOption) (stri if err != nil { return "", err } + return rootItem.CommitId, nil } @@ -187,6 +192,7 @@ func (a *azureClient) getRootItem(ctx context.Context, opt fetchOption) (*azureI if len(items.Value) == 0 || items.Value[0].CommitId == "" { return nil, errors.Errorf("failed to get latest commitID in the repository") } + return &items.Value[0], nil } @@ -205,7 +211,7 @@ func parseUrl(rawUrl string) (*azureOptions, error) { return nil, errors.Errorf("supported url schemes are https and ssh; recevied URL %s rawUrl", rawUrl) } -var expectedSshUrl = "git@ssh.dev.azure.com:v3/Organisation/Project/Repository" +const expectedSshUrl = "git@ssh.dev.azure.com:v3/Organisation/Project/Repository" func parseSshUrl(rawUrl string) (*azureOptions, error) { path := strings.Split(rawUrl, "/") @@ -343,6 +349,7 @@ func (a *azureClient) buildTreeUrl(config *azureOptions, rootObjectHash string) if err != nil { return "", errors.Wrapf(err, "failed to parse list tree url path %s", rawUrl) } + q := u.Query() // projectId={projectId}&recursive=true&fileName={fileName}&$format={$format}&api-version=6.0 q.Set("recursive", "true") @@ -361,9 +368,11 @@ func formatReferenceName(name string) string { if strings.HasPrefix(name, branchPrefix) { return strings.TrimPrefix(name, branchPrefix) } + if strings.HasPrefix(name, tagPrefix) { return strings.TrimPrefix(name, tagPrefix) } + return name } @@ -371,9 +380,11 @@ func getVersionType(name string) string { if strings.HasPrefix(name, branchPrefix) { return "branch" } + if strings.HasPrefix(name, tagPrefix) { return "tag" } + return "commit" } @@ -490,5 +501,6 @@ func checkAzureStatusCode(err error, code int) error { } else if code == http.StatusUnauthorized || code == http.StatusNonAuthoritativeInfo { return gittypes.ErrAuthenticationFailure } + return err } diff --git a/api/git/azure_integration_test.go b/api/git/azure_integration_test.go index 8c22a3e91..f5aba3218 100644 --- a/api/git/azure_integration_test.go +++ b/api/git/azure_integration_test.go @@ -8,14 +8,13 @@ import ( "testing" "time" - _ "github.com/joho/godotenv/autoload" gittypes "github.com/portainer/portainer/api/git/types" + + _ "github.com/joho/godotenv/autoload" "github.com/stretchr/testify/assert" ) -var ( - privateAzureRepoURL = "https://portainer.visualstudio.com/gitops-test/_git/gitops-test" -) +const privateAzureRepoURL = "https://portainer.visualstudio.com/gitops-test/_git/gitops-test" func TestService_ClonePublicRepository_Azure(t *testing.T) { ensureIntegrationTest(t) @@ -107,7 +106,7 @@ func TestService_ListRefs_Azure_Concurrently(t *testing.T) { accessToken := getRequiredValue(t, "AZURE_DEVOPS_PAT") username := getRequiredValue(t, "AZURE_DEVOPS_USERNAME") - service := newService(context.TODO(), REPOSITORY_CACHE_SIZE, 200*time.Millisecond) + service := newService(context.TODO(), repositoryCacheSize, 200*time.Millisecond) go service.ListRefs(privateAzureRepoURL, username, accessToken, false) service.ListRefs(privateAzureRepoURL, username, accessToken, false) @@ -269,7 +268,7 @@ func TestService_ListFiles_Azure_Concurrently(t *testing.T) { accessToken := getRequiredValue(t, "AZURE_DEVOPS_PAT") username := getRequiredValue(t, "AZURE_DEVOPS_USERNAME") - service := newService(context.TODO(), REPOSITORY_CACHE_SIZE, 200*time.Millisecond) + service := newService(context.TODO(), repositoryCacheSize, 200*time.Millisecond) go service.ListFiles(privateAzureRepoURL, "refs/heads/main", username, accessToken, false, []string{}) service.ListFiles(privateAzureRepoURL, "refs/heads/main", username, accessToken, false, []string{}) diff --git a/api/git/git_integration_test.go b/api/git/git_integration_test.go index 886003c8d..6c72532dc 100644 --- a/api/git/git_integration_test.go +++ b/api/git/git_integration_test.go @@ -60,7 +60,7 @@ func TestService_ListRefs_Github_Concurrently(t *testing.T) { accessToken := getRequiredValue(t, "GITHUB_PAT") username := getRequiredValue(t, "GITHUB_USERNAME") - service := newService(context.TODO(), REPOSITORY_CACHE_SIZE, 200*time.Millisecond) + service := newService(context.TODO(), repositoryCacheSize, 200*time.Millisecond) repositoryUrl := privateGitRepoURL go service.ListRefs(repositoryUrl, username, accessToken, false) @@ -224,7 +224,7 @@ func TestService_ListFiles_Github_Concurrently(t *testing.T) { repositoryUrl := privateGitRepoURL accessToken := getRequiredValue(t, "GITHUB_PAT") username := getRequiredValue(t, "GITHUB_USERNAME") - service := newService(context.TODO(), REPOSITORY_CACHE_SIZE, 200*time.Millisecond) + service := newService(context.TODO(), repositoryCacheSize, 200*time.Millisecond) go service.ListFiles(repositoryUrl, "refs/heads/main", username, accessToken, false, []string{}) service.ListFiles(repositoryUrl, "refs/heads/main", username, accessToken, false, []string{}) diff --git a/api/git/git_test.go b/api/git/git_test.go index 5f129d4f5..0e2d6caeb 100644 --- a/api/git/git_test.go +++ b/api/git/git_test.go @@ -95,10 +95,12 @@ func getCommitHistoryLength(t *testing.T, err error, dir string) int { if err != nil { t.Fatalf("can't open a git repo at %s with error %v", dir, err) } + iter, err := repo.Log(&git.LogOptions{All: true}) if err != nil { t.Fatalf("can't get a commit history iterator with error %v", err) } + count := 0 err = iter.ForEach(func(_ *object.Commit) error { count++ @@ -107,6 +109,7 @@ func getCommitHistoryLength(t *testing.T, err error, dir string) int { if err != nil { t.Fatalf("can't iterate over the commit history with error %v", err) } + return count } diff --git a/api/git/service.go b/api/git/service.go index baf3a841d..7f062cd7a 100644 --- a/api/git/service.go +++ b/api/git/service.go @@ -10,9 +10,9 @@ import ( "github.com/rs/zerolog/log" ) -var ( - REPOSITORY_CACHE_SIZE = 4 - REPOSITORY_CACHE_TTL = 5 * time.Minute +const ( + repositoryCacheSize = 4 + repositoryCacheTTL = 5 * time.Minute ) // baseOption provides a minimum group of information to operate a git repository, like git-remote @@ -58,7 +58,7 @@ type Service struct { // NewService initializes a new service. func NewService(ctx context.Context) *Service { - return newService(ctx, REPOSITORY_CACHE_SIZE, REPOSITORY_CACHE_TTL) + return newService(ctx, repositoryCacheSize, repositoryCacheTTL) } func newService(ctx context.Context, cacheSize int, cacheTTL time.Duration) *Service { diff --git a/api/git/update/update.go b/api/git/update/update.go index d43ef2102..e0c23eefd 100644 --- a/api/git/update/update.go +++ b/api/git/update/update.go @@ -34,7 +34,7 @@ func UpdateGitObject(gitService portainer.GitService, dataStore dataservices.Dat return false, "", errors.WithMessagef(err, "failed to fetch latest commit id of %v", objId) } - hashChanged := !strings.EqualFold(newHash, string(gitConfig.ConfigHash)) + hashChanged := !strings.EqualFold(newHash, gitConfig.ConfigHash) forceUpdate := autoUpdateConfig != nil && autoUpdateConfig.ForceUpdate if !hashChanged && !forceUpdate { log.Debug(). diff --git a/api/http/handler/hostmanagement/fdo/profile_create.go b/api/http/handler/hostmanagement/fdo/profile_create.go index f4837618d..d83ad9b50 100644 --- a/api/http/handler/hostmanagement/fdo/profile_create.go +++ b/api/http/handler/hostmanagement/fdo/profile_create.go @@ -48,15 +48,16 @@ func (handler *Handler) createProfile(w http.ResponseWriter, r *http.Request) *h return httperror.BadRequest("Invalid query parameter: method", err) } - switch method { - case "editor": + if method == "editor" { return handler.createFDOProfileFromFileContent(w, r) } + return httperror.BadRequest("Invalid method. Value must be one of: editor", errors.New("invalid method")) } func (handler *Handler) createFDOProfileFromFileContent(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { var payload createProfileFromFileContentPayload + err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { return httperror.BadRequest("Invalid request payload", err) @@ -66,6 +67,7 @@ func (handler *Handler) createFDOProfileFromFileContent(w http.ResponseWriter, r if err != nil { return httperror.InternalServerError(err.Error(), err) } + if !isUnique { return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A profile with the name '%s' already exists", payload.Name), Err: errors.New("a profile already exists with this name")} } @@ -80,6 +82,7 @@ func (handler *Handler) createFDOProfileFromFileContent(w http.ResponseWriter, r if err != nil { return httperror.InternalServerError("Unable to persist profile file on disk", err) } + profile.FilePath = filePath profile.DateCreated = time.Now().Unix() diff --git a/api/http/handler/templates/template_file.go b/api/http/handler/templates/template_file.go index 3299f25cd..e7e5a23a0 100644 --- a/api/http/handler/templates/template_file.go +++ b/api/http/handler/templates/template_file.go @@ -63,6 +63,7 @@ func (handler *Handler) ifRequestedTemplateExists(payload *filePayload) *httperr return nil } } + return httperror.InternalServerError("Invalid template", errors.New("requested template does not exist")) } @@ -82,6 +83,7 @@ func (handler *Handler) ifRequestedTemplateExists(payload *filePayload) *httperr // @router /templates/file [post] func (handler *Handler) templateFile(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { var payload filePayload + err := request.DecodeAndValidateJSONPayload(r, &payload) if err != nil { return httperror.BadRequest("Invalid request payload", err) @@ -112,11 +114,9 @@ func (handler *Handler) templateFile(w http.ResponseWriter, r *http.Request) *ht } -func (handler *Handler) cleanUp(projectPath string) error { +func (handler *Handler) cleanUp(projectPath string) { err := handler.FileService.RemoveDirectory(projectPath) if err != nil { log.Debug().Err(err).Msg("HTTP error: unable to cleanup stack creation") } - - return nil } diff --git a/api/http/handler/websocket/stream.go b/api/http/handler/websocket/stream.go index 131951803..c3e8a5835 100644 --- a/api/http/handler/websocket/stream.go +++ b/api/http/handler/websocket/stream.go @@ -14,30 +14,35 @@ func streamFromWebsocketToWriter(websocketConn *websocket.Conn, writer io.Writer _, in, err := websocketConn.ReadMessage() if err != nil { errorChan <- err + break } _, err = writer.Write(in) if err != nil { errorChan <- err + break } } } func streamFromReaderToWebsocket(websocketConn *websocket.Conn, reader io.Reader, errorChan chan error) { + out := make([]byte, readerBufferSize) + for { - out := make([]byte, readerBufferSize) _, err := reader.Read(out) if err != nil { errorChan <- err + break } - processedOutput := validString(string(out[:])) + processedOutput := validString(string(out)) err = websocketConn.WriteMessage(websocket.TextMessage, []byte(processedOutput)) if err != nil { errorChan <- err + break } } @@ -46,6 +51,7 @@ func streamFromReaderToWebsocket(websocketConn *websocket.Conn, reader io.Reader func validString(s string) string { if !utf8.ValidString(s) { v := make([]rune, 0, len(s)) + for i, r := range s { if r == utf8.RuneError { _, size := utf8.DecodeRuneInString(s[i:]) @@ -53,9 +59,12 @@ func validString(s string) string { continue } } + v = append(v, r) } + s = string(v) } + return s } diff --git a/api/http/proxy/factory/docker/portainer.go b/api/http/proxy/factory/docker/portainer.go index 437d0427f..be046db0d 100644 --- a/api/http/proxy/factory/docker/portainer.go +++ b/api/http/proxy/factory/docker/portainer.go @@ -26,6 +26,7 @@ func (transport *Transport) applyPortainerContainers(resources []interface{}) ([ responseObject, _ = transport.applyPortainerContainer(responseObject) decoratedResourceData = append(decoratedResourceData, responseObject) } + return decoratedResourceData, nil } @@ -34,8 +35,10 @@ func (transport *Transport) applyPortainerContainer(resourceObject map[string]in if !ok { return resourceObject, nil } + if len(resourceId) >= 12 && resourceId[0:12] == portainerContainerId { resourceObject["IsPortainer"] = true } + return resourceObject, nil } diff --git a/api/http/proxy/factory/kubernetes/transport.go b/api/http/proxy/factory/kubernetes/transport.go index 1f05092f8..aeab4d876 100644 --- a/api/http/proxy/factory/kubernetes/transport.go +++ b/api/http/proxy/factory/kubernetes/transport.go @@ -150,8 +150,7 @@ func (transport *baseTransport) getRoundTripToken(request *http.Request, tokenMa func decorateAgentRequest(r *http.Request, dataStore dataservices.DataStore) error { requestPath := strings.TrimPrefix(r.URL.Path, "/v2") - switch { - case strings.HasPrefix(requestPath, "/dockerhub"): + if strings.HasPrefix(requestPath, "/dockerhub") { return decorateAgentDockerHubRequest(r, dataStore) } diff --git a/api/internal/upgrade/upgrade_docker.go b/api/internal/upgrade/upgrade_docker.go index 8d569fcef..c4865433f 100644 --- a/api/internal/upgrade/upgrade_docker.go +++ b/api/internal/upgrade/upgrade_docker.go @@ -8,13 +8,14 @@ import ( "strings" "time" - "github.com/cbroglie/mustache" "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" "github.com/docker/docker/client" - "github.com/pkg/errors" libstack "github.com/portainer/docker-compose-wrapper" "github.com/portainer/portainer/api/filesystem" + + "github.com/cbroglie/mustache" + "github.com/pkg/errors" "github.com/rs/zerolog/log" ) @@ -65,7 +66,7 @@ func (service *service) upgradeDocker(licenseKey, version, envType string) error projectName := fmt.Sprintf( "portainer-upgrade-%d-%s", timeId, - strings.Replace(version, ".", "-", -1)) + strings.ReplaceAll(version, ".", "-")) err = service.composeDeployer.Deploy( ctx, diff --git a/api/kubernetes/kubeclusteraccess_service.go b/api/kubernetes/kubeclusteraccess_service.go index 4a97885d4..a5145d585 100644 --- a/api/kubernetes/kubeclusteraccess_service.go +++ b/api/kubernetes/kubeclusteraccess_service.go @@ -98,7 +98,7 @@ func (service *kubeClusterAccessService) GetData(hostURL string, endpointID port // When the api call is internal, the baseURL should not be used. if hostURL == "localhost" { - hostURL = hostURL + service.httpsBindAddr + hostURL += service.httpsBindAddr baseURL = "/" } diff --git a/api/stacks/stackutils/util.go b/api/stacks/stackutils/util.go index bb3d82d23..b1c8f17ba 100644 --- a/api/stacks/stackutils/util.go +++ b/api/stacks/stackutils/util.go @@ -24,6 +24,7 @@ func GetStackFilePaths(stack *portainer.Stack, absolute bool) []string { for _, file := range append([]string{stack.EntryPoint}, stack.AdditionalFiles...) { filePaths = append(filePaths, filesystem.JoinPaths(stack.ProjectPath, file)) } + return filePaths }