1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-19 13:29:41 +02:00

chore(code): clean up the code EE-5719 (#9183)

This commit is contained in:
andres-portainer 2023-07-10 23:26:54 -03:00 committed by GitHub
parent 979af5301e
commit 64b227b2e1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 93 additions and 87 deletions

View file

@ -18,6 +18,7 @@ func (service *Service) AddEdgeJob(endpoint *portainer.Endpoint, edgeJob *portai
for idx, existingJob := range tunnel.Jobs { for idx, existingJob := range tunnel.Jobs {
if existingJob.ID == edgeJob.ID { if existingJob.ID == edgeJob.ID {
existingJobIndex = idx existingJobIndex = idx
break break
} }
} }

View file

@ -152,7 +152,7 @@ func initDataStore(flags *portainer.CLIFlags, secretKey []byte, fileService port
return store return store
} }
func initComposeStackManager(composeDeployer libstack.Deployer, reverseTunnelService portainer.ReverseTunnelService, proxyManager *proxy.Manager) portainer.ComposeStackManager { func initComposeStackManager(composeDeployer libstack.Deployer, proxyManager *proxy.Manager) portainer.ComposeStackManager {
composeWrapper, err := exec.NewComposeStackManager(composeDeployer, proxyManager) composeWrapper, err := exec.NewComposeStackManager(composeDeployer, proxyManager)
if err != nil { if err != nil {
log.Fatal().Err(err).Msg("failed creating compose manager") log.Fatal().Err(err).Msg("failed creating compose manager")
@ -458,7 +458,7 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
log.Fatal().Err(err).Msg("failed initializing compose deployer") log.Fatal().Err(err).Msg("failed initializing compose deployer")
} }
composeStackManager := initComposeStackManager(composeDeployer, reverseTunnelService, proxyManager) composeStackManager := initComposeStackManager(composeDeployer, proxyManager)
swarmStackManager, err := initSwarmStackManager(*flags.Assets, dockerConfigPath, digitalSignatureService, fileService, reverseTunnelService, dataStore) swarmStackManager, err := initSwarmStackManager(*flags.Assets, dockerConfigPath, digitalSignatureService, fileService, reverseTunnelService, dataStore)
if err != nil { if err != nil {

View file

@ -66,6 +66,7 @@ func (service ServiceTx) DeleteEndpoint(ID portainer.EndpointID) error {
for edgeID, endpointID := range service.service.idxEdgeID { for edgeID, endpointID := range service.service.idxEdgeID {
if endpointID == ID { if endpointID == ID {
delete(service.service.idxEdgeID, edgeID) delete(service.service.idxEdgeID, edgeID)
break break
} }
} }

View file

@ -20,10 +20,6 @@ func (m *Migrator) migrateDockerDesktopExtentionSetting() error {
} }
settings.IsDockerDesktopExtension = isDDExtension settings.IsDockerDesktopExtension = isDDExtension
err = m.settingsService.UpdateSettings(settings)
if err != nil {
return err
}
return nil return m.settingsService.UpdateSettings(settings)
} }

View file

@ -3,15 +3,11 @@ package migrator
import ( import (
"errors" "errors"
"github.com/portainer/portainer/api/dataservices/edgejob"
"github.com/portainer/portainer/api/dataservices/edgestack"
"github.com/Masterminds/semver"
"github.com/rs/zerolog/log"
portainer "github.com/portainer/portainer/api" portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/database/models" "github.com/portainer/portainer/api/database/models"
"github.com/portainer/portainer/api/dataservices/dockerhub" "github.com/portainer/portainer/api/dataservices/dockerhub"
"github.com/portainer/portainer/api/dataservices/edgejob"
"github.com/portainer/portainer/api/dataservices/edgestack"
"github.com/portainer/portainer/api/dataservices/endpoint" "github.com/portainer/portainer/api/dataservices/endpoint"
"github.com/portainer/portainer/api/dataservices/endpointgroup" "github.com/portainer/portainer/api/dataservices/endpointgroup"
"github.com/portainer/portainer/api/dataservices/endpointrelation" "github.com/portainer/portainer/api/dataservices/endpointrelation"
@ -29,6 +25,9 @@ import (
"github.com/portainer/portainer/api/dataservices/user" "github.com/portainer/portainer/api/dataservices/user"
"github.com/portainer/portainer/api/dataservices/version" "github.com/portainer/portainer/api/dataservices/version"
"github.com/portainer/portainer/api/internal/authorization" "github.com/portainer/portainer/api/internal/authorization"
"github.com/Masterminds/semver"
"github.com/rs/zerolog/log"
) )
type ( type (

View file

@ -4,22 +4,19 @@ import (
"strings" "strings"
"time" "time"
"github.com/patrickmn/go-cache"
"github.com/pkg/errors"
portainer "github.com/portainer/portainer/api" portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/dataservices" "github.com/portainer/portainer/api/dataservices"
"github.com/portainer/portainer/api/internal/registryutils" "github.com/portainer/portainer/api/internal/registryutils"
"github.com/patrickmn/go-cache"
"github.com/pkg/errors"
) )
var ( var registriesCache = cache.New(5*time.Minute, 5*time.Minute)
_registriesCache = cache.New(5*time.Minute, 5*time.Minute)
)
type ( type RegistryClient struct {
RegistryClient struct { dataStore dataservices.DataStore
dataStore dataservices.DataStore }
}
)
func NewRegistryClient(dataStore dataservices.DataStore) *RegistryClient { func NewRegistryClient(dataStore dataservices.DataStore) *RegistryClient {
return &RegistryClient{dataStore: dataStore} return &RegistryClient{dataStore: dataStore}
@ -130,12 +127,14 @@ func findBestMatchRegistry(repository string, registries []portainer.Registry) (
if match == nil { if match == nil {
return nil, errors.New("no registries matched") return nil, errors.New("no registries matched")
} }
_registriesCache.Set(repository, match, 0)
registriesCache.Set(repository, match, 0)
return match, nil return match, nil
} }
func cachedRegistry(cacheKey string) (*portainer.Registry, error) { func cachedRegistry(cacheKey string) (*portainer.Registry, error) {
r, ok := _registriesCache.Get(cacheKey) r, ok := registriesCache.Get(cacheKey)
if ok { if ok {
registry, ok := r.(portainer.Registry) registry, ok := r.(portainer.Registry)
if ok { if ok {

View file

@ -7,12 +7,12 @@ import (
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters" "github.com/docker/docker/api/types/filters"
"github.com/opencontainers/go-digest"
"github.com/patrickmn/go-cache"
portainer "github.com/portainer/portainer/api" portainer "github.com/portainer/portainer/api"
consts "github.com/portainer/portainer/api/docker/consts" consts "github.com/portainer/portainer/api/docker/consts"
"github.com/portainer/portainer/api/internal/slices" "github.com/portainer/portainer/api/internal/slices"
"github.com/opencontainers/go-digest"
"github.com/patrickmn/go-cache"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
@ -40,6 +40,7 @@ func (c *DigestClient) ContainersImageStatus(ctx context.Context, containers []t
cli, err := c.clientFactory.CreateClient(endpoint, "", nil) cli, err := c.clientFactory.CreateClient(endpoint, "", nil)
if err != nil { if err != nil {
log.Error().Err(err).Msg("cannot create docker client") log.Error().Err(err).Msg("cannot create docker client")
return Error return Error
} }

View file

@ -6,15 +6,15 @@ import (
"encoding/pem" "encoding/pem"
"errors" "errors"
"fmt" "fmt"
"io"
"os"
"path/filepath" "path/filepath"
"strings" "strings"
"github.com/gofrs/uuid"
portainer "github.com/portainer/portainer/api" portainer "github.com/portainer/portainer/api"
"github.com/rs/zerolog/log"
"io" "github.com/gofrs/uuid"
"os" "github.com/rs/zerolog/log"
) )
const ( const (
@ -327,7 +327,7 @@ func (service *Service) GetEdgeStackProjectPathByVersion(edgeStackIdentifier str
} }
if commitHash != "" { if commitHash != "" {
versionStr = fmt.Sprintf("%s", commitHash) versionStr = commitHash
} }
return JoinPaths(service.wrapFileStore(EdgeStackStorePath), edgeStackIdentifier, versionStr) return JoinPaths(service.wrapFileStore(EdgeStackStorePath), edgeStackIdentifier, versionStr)
@ -367,7 +367,7 @@ func (service *Service) FormProjectPathByVersion(path string, version int, commi
} }
if commitHash != "" { if commitHash != "" {
versionStr = fmt.Sprintf("%s", commitHash) versionStr = commitHash
} }
return JoinPaths(path, versionStr) return JoinPaths(path, versionStr)

View file

@ -8,6 +8,8 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
var content = []byte("content")
func Test_movePath_shouldFailIfSourceDirDoesNotExist(t *testing.T) { func Test_movePath_shouldFailIfSourceDirDoesNotExist(t *testing.T) {
sourceDir := "missing" sourceDir := "missing"
destinationDir := t.TempDir() destinationDir := t.TempDir()
@ -52,8 +54,6 @@ func Test_movePath_successWhenSourceExistsAndDestinationIsMissing(t *testing.T)
assertFileContent(t, path.Join(destinationDir, "dir", "file")) assertFileContent(t, path.Join(destinationDir, "dir", "file"))
} }
var content []byte = []byte("content")
func addFile(fileParts ...string) (filepath string) { func addFile(fileParts ...string) (filepath string) {
if len(fileParts) > 2 { if len(fileParts) > 2 {
dir := path.Join(fileParts[:len(fileParts)-1]...) dir := path.Join(fileParts[:len(fileParts)-1]...)
@ -62,6 +62,7 @@ func addFile(fileParts ...string) (filepath string) {
p := path.Join(fileParts...) p := path.Join(fileParts...)
os.WriteFile(p, content, 0766) os.WriteFile(p, content, 0766)
return p return p
} }

View file

@ -6,11 +6,12 @@ import (
"path/filepath" "path/filepath"
"testing" "testing"
"github.com/portainer/portainer/api/archive"
gittypes "github.com/portainer/portainer/api/git/types"
"github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/object"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/portainer/portainer/api/archive"
gittypes "github.com/portainer/portainer/api/git/types"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )

View file

@ -11,6 +11,7 @@ import (
"github.com/portainer/libhttp/response" "github.com/portainer/libhttp/response"
portainer "github.com/portainer/portainer/api" portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/stacks/stackutils" "github.com/portainer/portainer/api/stacks/stackutils"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
@ -68,10 +69,12 @@ func (handler *Handler) customTemplateGitFetch(w http.ResponseWriter, r *http.Re
}) })
if err != nil { if err != nil {
log.Warn().Err(err).Msg("failed to download git repository") log.Warn().Err(err).Msg("failed to download git repository")
rbErr := rollbackCustomTemplate(backupPath, customTemplate.ProjectPath)
if err != nil { if err != nil {
rbErr := rollbackCustomTemplate(backupPath, customTemplate.ProjectPath)
return httperror.InternalServerError("Failed to rollback the custom template folder", rbErr) return httperror.InternalServerError("Failed to rollback the custom template folder", rbErr)
} }
return httperror.InternalServerError("Failed to download git repository", err) return httperror.InternalServerError("Failed to download git repository", err)
} }
@ -104,11 +107,7 @@ func backupCustomTemplate(projectPath string) (string, error) {
return "", err return "", err
} }
err = os.Mkdir(projectPath, stat.Mode()) return backupPath, os.Mkdir(projectPath, stat.Mode())
if err != nil {
return backupPath, err
}
return backupPath, nil
} }
func rollbackCustomTemplate(backupPath, projectPath string) error { func rollbackCustomTemplate(backupPath, projectPath string) error {
@ -116,6 +115,7 @@ func rollbackCustomTemplate(backupPath, projectPath string) error {
if err != nil { if err != nil {
return err return err
} }
return os.Rename(backupPath, projectPath) return os.Rename(backupPath, projectPath)
} }

View file

@ -23,7 +23,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
var testFileContent string = "abcdefg" var testFileContent = "abcdefg"
type TestGitService struct { type TestGitService struct {
portainer.GitService portainer.GitService
@ -32,6 +32,7 @@ type TestGitService struct {
func (g *TestGitService) CloneRepository(destination string, repositoryURL, referenceName string, username, password string, tlsSkipVerify bool) error { func (g *TestGitService) CloneRepository(destination string, repositoryURL, referenceName string, username, password string, tlsSkipVerify bool) error {
time.Sleep(100 * time.Millisecond) time.Sleep(100 * time.Millisecond)
return createTestFile(g.targetFilePath) return createTestFile(g.targetFilePath)
} }
@ -53,7 +54,9 @@ func createTestFile(targetPath string) error {
return err return err
} }
defer f.Close() defer f.Close()
_, err = f.WriteString(testFileContent) _, err = f.WriteString(testFileContent)
return err return err
} }
@ -152,7 +155,7 @@ func Test_customTemplateGitFetch(t *testing.T) {
wg.Add(10) wg.Add(10)
for i := 0; i < 10; i++ { for i := 0; i < 10; i++ {
go func(j int) { go func(j int) {
if j%1 == 0 { if j%2 == 0 {
singleAPIRequest(h, jwt1, is, "abcdefg") singleAPIRequest(h, jwt1, is, "abcdefg")
} else { } else {
singleAPIRequest(h, jwt2, is, "abcdefg") singleAPIRequest(h, jwt2, is, "abcdefg")

View file

@ -38,6 +38,7 @@ func (handler *Handler) getKubernetesConfig(w http.ResponseWriter, r *http.Reque
if err != nil { if err != nil {
return httperror.Forbidden("Permission denied to access environment", err) return httperror.Forbidden("Permission denied to access environment", err)
} }
bearerToken, err := handler.JwtService.GenerateTokenForKubeconfig(tokenData) bearerToken, err := handler.JwtService.GenerateTokenForKubeconfig(tokenData)
if err != nil { if err != nil {
return httperror.InternalServerError("Unable to generate JWT token", err) return httperror.InternalServerError("Unable to generate JWT token", err)
@ -47,14 +48,12 @@ func (handler *Handler) getKubernetesConfig(w http.ResponseWriter, r *http.Reque
if handlerErr != nil { if handlerErr != nil {
return handlerErr return handlerErr
} }
if len(endpoints) == 0 { if len(endpoints) == 0 {
return httperror.BadRequest("empty endpoints list", errors.New("empty endpoints list")) return httperror.BadRequest("empty endpoints list", errors.New("empty endpoints list"))
} }
config, handlerErr := handler.buildConfig(r, tokenData, bearerToken, endpoints, false) config := handler.buildConfig(r, tokenData, bearerToken, endpoints, false)
if handlerErr != nil {
return handlerErr
}
return writeFileContent(w, r, endpoints, tokenData, config) return writeFileContent(w, r, endpoints, tokenData, config)
} }
@ -92,7 +91,9 @@ func (handler *Handler) filterUserKubeEndpoints(r *http.Request) ([]portainer.En
} }
endpoints = append(endpoints, *endpoint) endpoints = append(endpoints, *endpoint)
} }
filteredEndpoints := security.FilterEndpoints(endpoints, endpointGroups, securityContext) filteredEndpoints := security.FilterEndpoints(endpoints, endpointGroups, securityContext)
return filteredEndpoints, nil return filteredEndpoints, nil
} }
@ -101,10 +102,12 @@ func (handler *Handler) filterUserKubeEndpoints(r *http.Request) ([]portainer.En
if err != nil { if err != nil {
return nil, httperror.InternalServerError("Unable to retrieve environments from the database", err) return nil, httperror.InternalServerError("Unable to retrieve environments from the database", err)
} }
for _, endpoint := range endpoints { for _, endpoint := range endpoints {
if !endpointutils.IsKubernetesEndpoint(&endpoint) { if !endpointutils.IsKubernetesEndpoint(&endpoint) {
continue continue
} }
kubeEndpoints = append(kubeEndpoints, endpoint) kubeEndpoints = append(kubeEndpoints, endpoint)
} }
@ -112,13 +115,15 @@ func (handler *Handler) filterUserKubeEndpoints(r *http.Request) ([]portainer.En
if len(excludeEndpointIDs) > 0 { if len(excludeEndpointIDs) > 0 {
filteredEndpoints = endpointutils.FilterByExcludeIDs(filteredEndpoints, excludeEndpointIDs) filteredEndpoints = endpointutils.FilterByExcludeIDs(filteredEndpoints, excludeEndpointIDs)
} }
return filteredEndpoints, nil return filteredEndpoints, nil
} }
func (handler *Handler) buildConfig(r *http.Request, tokenData *portainer.TokenData, bearerToken string, endpoints []portainer.Endpoint, isInternal bool) (*clientV1.Config, *httperror.HandlerError) { func (handler *Handler) buildConfig(r *http.Request, tokenData *portainer.TokenData, bearerToken string, endpoints []portainer.Endpoint, isInternal bool) *clientV1.Config {
var configAuthInfos []clientV1.NamedAuthInfo
configClusters := make([]clientV1.NamedCluster, len(endpoints)) configClusters := make([]clientV1.NamedCluster, len(endpoints))
configContexts := make([]clientV1.NamedContext, len(endpoints)) configContexts := make([]clientV1.NamedContext, len(endpoints))
var configAuthInfos []clientV1.NamedAuthInfo
authInfosSet := make(map[string]bool) authInfosSet := make(map[string]bool)
for idx, endpoint := range endpoints { for idx, endpoint := range endpoints {
@ -127,6 +132,7 @@ func (handler *Handler) buildConfig(r *http.Request, tokenData *portainer.TokenD
configClusters[idx] = handler.buildCluster(r, endpoint, isInternal) configClusters[idx] = handler.buildCluster(r, endpoint, isInternal)
configContexts[idx] = buildContext(serviceAccountName, endpoint) configContexts[idx] = buildContext(serviceAccountName, endpoint)
if !authInfosSet[serviceAccountName] { if !authInfosSet[serviceAccountName] {
configAuthInfos = append(configAuthInfos, buildAuthInfo(serviceAccountName, bearerToken)) configAuthInfos = append(configAuthInfos, buildAuthInfo(serviceAccountName, bearerToken))
authInfosSet[serviceAccountName] = true authInfosSet[serviceAccountName] = true
@ -140,7 +146,7 @@ func (handler *Handler) buildConfig(r *http.Request, tokenData *portainer.TokenD
Contexts: configContexts, Contexts: configContexts,
CurrentContext: configContexts[0].Name, CurrentContext: configContexts[0].Name,
AuthInfos: configAuthInfos, AuthInfos: configAuthInfos,
}, nil }
} }
// buildCluster builds a Kubernetes cluster configuration based on the endpoint and if it's used internally or externally. // buildCluster builds a Kubernetes cluster configuration based on the endpoint and if it's used internally or externally.

View file

@ -166,22 +166,13 @@ func (handler *Handler) kubeClient(next http.Handler) http.Handler {
singleEndpointList := []portainer.Endpoint{ singleEndpointList := []portainer.Endpoint{
*endpoint, *endpoint,
} }
config, handlerErr := handler.buildConfig( config := handler.buildConfig(
r, r,
tokenData, tokenData,
bearerToken, bearerToken,
singleEndpointList, singleEndpointList,
true, true,
) )
if err != nil {
httperror.WriteError(
w,
http.StatusInternalServerError,
"Unable to build endpoint kubeconfig",
handlerErr.Err,
)
return
}
if len(config.Clusters) == 0 { if len(config.Clusters) == 0 {
httperror.WriteError( httperror.WriteError(

View file

@ -59,9 +59,11 @@ func (r K8sIngressInfo) Validate(request *http.Request) error {
if r.Name == "" { if r.Name == "" {
return errors.New("missing ingress name from the request payload") return errors.New("missing ingress name from the request payload")
} }
if r.Namespace == "" { if r.Namespace == "" {
return errors.New("missing ingress Namespace from the request payload") return errors.New("missing ingress Namespace from the request payload")
} }
return nil return nil
} }
@ -69,10 +71,12 @@ func (r K8sIngressDeleteRequests) Validate(request *http.Request) error {
if len(r) == 0 { if len(r) == 0 {
return errors.New("missing deletion request list in payload") return errors.New("missing deletion request list in payload")
} }
for ns := range r { for ns := range r {
if len(ns) == 0 { if len(ns) == 0 {
return errors.New("deletion given with empty namespace") return errors.New("deletion given with empty namespace")
} }
} }
return nil return nil
} }

View file

@ -48,12 +48,15 @@ func (s *K8sServiceInfo) Validate(request *http.Request) error {
if s.Name == "" { if s.Name == "" {
return errors.New("missing service name from the request payload") return errors.New("missing service name from the request payload")
} }
if s.Namespace == "" { if s.Namespace == "" {
return errors.New("missing service namespace from the request payload") return errors.New("missing service namespace from the request payload")
} }
if s.Ports == nil { if s.Ports == nil {
return errors.New("missing service ports from the request payload") return errors.New("missing service ports from the request payload")
} }
return nil return nil
} }
@ -61,10 +64,12 @@ func (r K8sServiceDeleteRequests) Validate(request *http.Request) error {
if len(r) == 0 { if len(r) == 0 {
return errors.New("missing deletion request list in payload") return errors.New("missing deletion request list in payload")
} }
for ns := range r { for ns := range r {
if len(ns) == 0 { if len(ns) == 0 {
return errors.New("deletion given with empty namespace") return errors.New("deletion given with empty namespace")
} }
} }
return nil return nil
} }

View file

@ -8,8 +8,7 @@ func (transport *baseTransport) proxyDeploymentsRequest(request *http.Request, n
switch request.Method { switch request.Method {
case http.MethodPost, http.MethodPatch: case http.MethodPost, http.MethodPatch:
transport.refreshRegistry(request, namespace) transport.refreshRegistry(request, namespace)
return transport.executeKubernetesRequest(request)
default:
return transport.executeKubernetesRequest(request)
} }
return transport.executeKubernetesRequest(request)
} }

View file

@ -5,11 +5,9 @@ import (
) )
func (transport *baseTransport) proxyPodsRequest(request *http.Request, namespace, requestPath string) (*http.Response, error) { func (transport *baseTransport) proxyPodsRequest(request *http.Request, namespace, requestPath string) (*http.Response, error) {
switch request.Method { if request.Method == http.MethodDelete {
case "DELETE":
transport.refreshRegistry(request, namespace) transport.refreshRegistry(request, namespace)
return transport.executeKubernetesRequest(request)
default:
return transport.executeKubernetesRequest(request)
} }
return transport.executeKubernetesRequest(request)
} }

View file

@ -508,18 +508,21 @@ func getUserEndpointAuthorizations(user *portainer.User, endpoints []portainer.E
authorizations := getAuthorizationsFromUserEndpointPolicy(user, &endpoint, roles) authorizations := getAuthorizationsFromUserEndpointPolicy(user, &endpoint, roles)
if len(authorizations) > 0 { if len(authorizations) > 0 {
endpointAuthorizations[endpoint.ID] = authorizations endpointAuthorizations[endpoint.ID] = authorizations
continue continue
} }
authorizations = getAuthorizationsFromUserEndpointGroupPolicy(user, &endpoint, roles, groupUserAccessPolicies) authorizations = getAuthorizationsFromUserEndpointGroupPolicy(user, &endpoint, roles, groupUserAccessPolicies)
if len(authorizations) > 0 { if len(authorizations) > 0 {
endpointAuthorizations[endpoint.ID] = authorizations endpointAuthorizations[endpoint.ID] = authorizations
continue continue
} }
authorizations = getAuthorizationsFromTeamEndpointPolicies(userMemberships, &endpoint, roles) authorizations = getAuthorizationsFromTeamEndpointPolicies(userMemberships, &endpoint, roles)
if len(authorizations) > 0 { if len(authorizations) > 0 {
endpointAuthorizations[endpoint.ID] = authorizations endpointAuthorizations[endpoint.ID] = authorizations
continue continue
} }
@ -587,6 +590,7 @@ func getAuthorizationsFromRoles(roleIdentifiers []portainer.RoleID, roles []port
for _, role := range roles { for _, role := range roles {
if role.ID == id { if role.ID == id {
associatedRoles = append(associatedRoles, role) associatedRoles = append(associatedRoles, role)
break break
} }
} }
@ -609,6 +613,7 @@ func (service *Service) UserIsAdminOrAuthorized(userID portainer.UserID, endpoin
if err != nil { if err != nil {
return false, err return false, err
} }
if user.Role == portainer.AdministratorRole { if user.Role == portainer.AdministratorRole {
return true, nil return true, nil
} }
@ -619,5 +624,6 @@ func (service *Service) UserIsAdminOrAuthorized(userID portainer.UserID, endpoin
return true, nil return true, nil
} }
} }
return false, nil return false, nil
} }

View file

@ -74,20 +74,11 @@ func (service *Service) getUserEndpointAccessWithPolicies(
} }
} }
if userAccess(tx, userID, endpoint.UserAccessPolicies, endpoint.TeamAccessPolicies, memberships) { return userAccess(userID, endpoint.UserAccessPolicies, endpoint.TeamAccessPolicies, memberships) ||
return true, nil userAccess(userID, endpointGroup.UserAccessPolicies, endpointGroup.TeamAccessPolicies, memberships), nil
}
if userAccess(tx, userID, endpointGroup.UserAccessPolicies, endpointGroup.TeamAccessPolicies, memberships) {
return true, nil
}
return false, nil
} }
func userAccess( func userAccess(
tx dataservices.DataStoreTx,
userID portainer.UserID, userID portainer.UserID,
userAccessPolicies portainer.UserAccessPolicies, userAccessPolicies portainer.UserAccessPolicies,
teamAccessPolicies portainer.TeamAccessPolicies, teamAccessPolicies portainer.TeamAccessPolicies,

View file

@ -7,10 +7,11 @@ import (
"sync" "sync"
"time" "time"
"github.com/patrickmn/go-cache"
"github.com/pkg/errors"
portainer "github.com/portainer/portainer/api" portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/dataservices" "github.com/portainer/portainer/api/dataservices"
"github.com/patrickmn/go-cache"
"github.com/pkg/errors"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest" "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd" "k8s.io/client-go/tools/clientcmd"
@ -116,7 +117,7 @@ func (factory *ClientFactory) SetProxyKubeClient(endpointID, token string, cli *
// CreateKubeClientFromKubeConfig creates a KubeClient from a clusterID, and // CreateKubeClientFromKubeConfig creates a KubeClient from a clusterID, and
// Kubernetes config. // Kubernetes config.
func (factory *ClientFactory) CreateKubeClientFromKubeConfig(clusterID string, kubeConfig []byte) (*KubeClient, error) { func (factory *ClientFactory) CreateKubeClientFromKubeConfig(clusterID string, kubeConfig []byte) (*KubeClient, error) {
config, err := clientcmd.NewClientConfigFromBytes([]byte(kubeConfig)) config, err := clientcmd.NewClientConfigFromBytes(kubeConfig)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View file

@ -5,6 +5,7 @@ import (
"testing" "testing"
portainer "github.com/portainer/portainer/api" portainer "github.com/portainer/portainer/api"
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -76,8 +77,8 @@ func newPods() *v1.PodList {
Name: "test-container-1", Name: "test-container-1",
Resources: v1.ResourceRequirements{ Resources: v1.ResourceRequirements{
Requests: v1.ResourceList{ Requests: v1.ResourceList{
v1.ResourceName(v1.ResourceCPU): resource.MustParse("2"), v1.ResourceCPU: resource.MustParse("2"),
v1.ResourceName(v1.ResourceMemory): resource.MustParse("3M"), v1.ResourceMemory: resource.MustParse("3M"),
}, },
}, },
}, },

View file

@ -85,7 +85,7 @@ func Test_GenerateYAML(t *testing.T) {
t.Errorf("generateYamlConfig failed; err=%s", err) t.Errorf("generateYamlConfig failed; err=%s", err)
} }
if compareYAMLStrings(string(yaml), ryt.wantYAML) != 0 { if compareYAMLStrings(yaml, ryt.wantYAML) != 0 {
t.Errorf("generateYamlConfig failed;\ngot=\n%s\nwant=\n%s", yaml, ryt.wantYAML) t.Errorf("generateYamlConfig failed;\ngot=\n%s\nwant=\n%s", yaml, ryt.wantYAML)
} }
}) })

View file

@ -5,6 +5,7 @@ import (
portainer "github.com/portainer/portainer/api" portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/dataservices" "github.com/portainer/portainer/api/dataservices"
"github.com/portainer/portainer/api/stacks/deployments" "github.com/portainer/portainer/api/stacks/deployments"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
) )
@ -41,6 +42,7 @@ func (b *StackBuilder) SaveStack() (*portainer.Stack, *httperror.HandlerError) {
} }
b.doCleanUp = false b.doCleanUp = false
return b.stack, b.err return b.stack, b.err
} }