mirror of https://github.com/portainer/portainer
chore(code): reduce divergence with EE EE-4344 (#7748)
parent
e9384a6987
commit
cb79dc18f8
|
@ -25,7 +25,7 @@ type Monitor struct {
|
|||
adminInitDisabled bool
|
||||
}
|
||||
|
||||
// New creates a monitor that when started will wait for the timeout duration and then sends the timeout signal to disable the application
|
||||
// New creates a monitor that when started will wait for the timeout duration and then shutdown the application unless it has been initialized.
|
||||
func New(timeout time.Duration, datastore dataservices.DataStore, shutdownCtx context.Context) *Monitor {
|
||||
return &Monitor{
|
||||
timeout: timeout,
|
||||
|
@ -105,12 +105,10 @@ func (m *Monitor) WasInstanceDisabled() bool {
|
|||
// Otherwise, it will pass through the request to next
|
||||
func (m *Monitor) WithRedirect(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if m.WasInstanceDisabled() {
|
||||
if strings.HasPrefix(r.RequestURI, "/api") && r.RequestURI != "/api/status" && r.RequestURI != "/api/settings/public" {
|
||||
w.Header().Set("redirect-reason", RedirectReasonAdminInitTimeout)
|
||||
httperror.WriteError(w, http.StatusSeeOther, "Administrator initialization timeout", nil)
|
||||
return
|
||||
}
|
||||
if m.WasInstanceDisabled() && strings.HasPrefix(r.RequestURI, "/api") && r.RequestURI != "/api/status" && r.RequestURI != "/api/settings/public" {
|
||||
w.Header().Set("redirect-reason", RedirectReasonAdminInitTimeout)
|
||||
httperror.WriteError(w, http.StatusSeeOther, "Administrator initialization timeout", nil)
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
|
|
|
@ -6,10 +6,10 @@ import (
|
|||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/dataservices"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const portainerAPIKeyPrefix = "ptr_"
|
||||
|
|
|
@ -2,6 +2,7 @@ package apikey
|
|||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
@ -170,11 +171,9 @@ func Test_UpdateAPIKey(t *testing.T) {
|
|||
_, apiKeyGot, err := service.GetDigestUserAndKey(apiKey.Digest)
|
||||
is.NoError(err)
|
||||
|
||||
log.Debug().Msgf("%+v", apiKey)
|
||||
log.Debug().Msgf("%+v", apiKeyGot)
|
||||
log.Debug().Str("wanted", fmt.Sprintf("%+v", apiKey)).Str("got", fmt.Sprintf("%+v", apiKeyGot)).Msg("")
|
||||
|
||||
is.Equal(apiKey.LastUsed, apiKeyGot.LastUsed)
|
||||
|
||||
})
|
||||
|
||||
t.Run("Successfully updates api-key in cache upon api-key update", func(t *testing.T) {
|
||||
|
|
|
@ -246,9 +246,8 @@ func (service *Service) checkTunnels() {
|
|||
err := service.snapshotEnvironment(endpointID, tunnel.Port)
|
||||
if err != nil {
|
||||
log.Error().
|
||||
Int("endpoint_id", int(endpointID)).Err(
|
||||
|
||||
err).
|
||||
Int("endpoint_id", int(endpointID)).
|
||||
Err(err).
|
||||
Msg("unable to snapshot Edge environment")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package cli
|
||||
|
||||
import (
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
|
||||
"strings"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
||||
|
|
|
@ -186,6 +186,10 @@ func initAPIKeyService(datastore dataservices.DataStore) apikey.APIKeyService {
|
|||
}
|
||||
|
||||
func initJWTService(userSessionTimeout string, dataStore dataservices.DataStore) (dataservices.JWTService, error) {
|
||||
if userSessionTimeout == "" {
|
||||
userSessionTimeout = portainer.DefaultUserSessionTimeout
|
||||
}
|
||||
|
||||
jwtService, err := jwt.NewService(userSessionTimeout, dataStore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -239,7 +243,13 @@ func initKubernetesClientFactory(signatureService portainer.DigitalSignatureServ
|
|||
return kubecli.NewClientFactory(signatureService, reverseTunnelService, instanceID, dataStore)
|
||||
}
|
||||
|
||||
func initSnapshotService(snapshotIntervalFromFlag string, dataStore dataservices.DataStore, dockerClientFactory *docker.ClientFactory, kubernetesClientFactory *kubecli.ClientFactory, shutdownCtx context.Context) (portainer.SnapshotService, error) {
|
||||
func initSnapshotService(
|
||||
snapshotIntervalFromFlag string,
|
||||
dataStore dataservices.DataStore,
|
||||
dockerClientFactory *docker.ClientFactory,
|
||||
kubernetesClientFactory *kubecli.ClientFactory,
|
||||
shutdownCtx context.Context,
|
||||
) (portainer.SnapshotService, error) {
|
||||
dockerSnapshotter := docker.NewSnapshotter(dockerClientFactory)
|
||||
kubernetesSnapshotter := kubernetes.NewSnapshotter(kubernetesClientFactory)
|
||||
|
||||
|
@ -580,6 +590,7 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
|
|||
ldapService := initLDAPService()
|
||||
|
||||
oauthService := initOAuthService()
|
||||
|
||||
gitService := initGitService(shutdownCtx)
|
||||
|
||||
openAMTService := openamt.NewService()
|
||||
|
@ -704,15 +715,15 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
|
|||
log.Fatal().Err(err).Msg("failed starting tunnel server")
|
||||
}
|
||||
|
||||
scheduler := scheduler.NewScheduler(shutdownCtx)
|
||||
stackDeployer := stacks.NewStackDeployer(swarmStackManager, composeStackManager, kubernetesDeployer)
|
||||
stacks.StartStackSchedules(scheduler, stackDeployer, dataStore, gitService)
|
||||
|
||||
sslDBSettings, err := dataStore.SSLSettings().Settings()
|
||||
if err != nil {
|
||||
log.Fatal().Msg("failed to fetch SSL settings from DB")
|
||||
}
|
||||
|
||||
scheduler := scheduler.NewScheduler(shutdownCtx)
|
||||
stackDeployer := stacks.NewStackDeployer(swarmStackManager, composeStackManager, kubernetesDeployer)
|
||||
stacks.StartStackSchedules(scheduler, stackDeployer, dataStore, gitService)
|
||||
|
||||
return &http.Server{
|
||||
AuthorizationService: authorizationService,
|
||||
ReverseTunnelService: reverseTunnelService,
|
||||
|
@ -726,8 +737,8 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
|
|||
ComposeStackManager: composeStackManager,
|
||||
KubernetesDeployer: kubernetesDeployer,
|
||||
HelmPackageManager: helmPackageManager,
|
||||
CryptoService: cryptoService,
|
||||
APIKeyService: apiKeyService,
|
||||
CryptoService: cryptoService,
|
||||
JWTService: jwtService,
|
||||
FileService: fileService,
|
||||
LDAPService: ldapService,
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"github.com/portainer/portainer/api/cli"
|
||||
"github.com/portainer/portainer/api/dataservices"
|
||||
"github.com/portainer/portainer/api/datastore"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/alecthomas/kingpin.v2"
|
||||
)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package boltdb
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
@ -162,7 +163,7 @@ func (connection *DbConnection) ExportRaw(filename string) error {
|
|||
return fmt.Errorf("stat on %s failed: %s", databasePath, err)
|
||||
}
|
||||
|
||||
b, err := connection.ExportJson(databasePath, true)
|
||||
b, err := connection.ExportJSON(databasePath, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -369,6 +370,27 @@ func (connection *DbConnection) GetAllWithJsoniter(bucketName string, obj interf
|
|||
return err
|
||||
}
|
||||
|
||||
func (connection *DbConnection) GetAllWithKeyPrefix(bucketName string, keyPrefix []byte, obj interface{}, append func(o interface{}) (interface{}, error)) error {
|
||||
return connection.View(func(tx *bolt.Tx) error {
|
||||
cursor := tx.Bucket([]byte(bucketName)).Cursor()
|
||||
|
||||
for k, v := cursor.Seek(keyPrefix); k != nil && bytes.HasPrefix(k, keyPrefix); k, v = cursor.Next() {
|
||||
err := connection.UnmarshalObjectWithJsoniter(v, obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
obj, err = append(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// BackupMetadata will return a copy of the boltdb sequence numbers for all buckets.
|
||||
func (connection *DbConnection) BackupMetadata() (map[string]interface{}, error) {
|
||||
buckets := map[string]interface{}{}
|
||||
|
||||
|
@ -387,6 +409,7 @@ func (connection *DbConnection) BackupMetadata() (map[string]interface{}, error)
|
|||
return buckets, err
|
||||
}
|
||||
|
||||
// RestoreMetadata will restore the boltdb sequence numbers for all buckets.
|
||||
func (connection *DbConnection) RestoreMetadata(s map[string]interface{}) error {
|
||||
var err error
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ func backupMetadata(connection *bolt.DB) (map[string]interface{}, error) {
|
|||
// using this function.
|
||||
// inspired by github.com/konoui/boltdb-exporter (which has no license)
|
||||
// but very much simplified, based on how we use boltdb
|
||||
func (c *DbConnection) ExportJson(databasePath string, metadata bool) ([]byte, error) {
|
||||
func (c *DbConnection) ExportJSON(databasePath string, metadata bool) ([]byte, error) {
|
||||
log.Debug().Str("databasePath", databasePath).Msg("exportJson")
|
||||
|
||||
connection, err := bolt.Open(databasePath, 0600, &bolt.Options{Timeout: 1 * time.Second, ReadOnly: true})
|
||||
|
|
|
@ -16,5 +16,6 @@ func NewDatabase(storeType, storePath string, encryptionKey []byte) (connection
|
|||
EncryptionKey: encryptionKey,
|
||||
}, nil
|
||||
}
|
||||
return nil, fmt.Errorf("unknown storage database: %s", storeType)
|
||||
|
||||
return nil, fmt.Errorf("Unknown storage database: %s", storeType)
|
||||
}
|
||||
|
|
|
@ -85,7 +85,7 @@ func (service *Service) List() ([]edgetypes.UpdateSchedule, error) {
|
|||
item, ok := obj.(*edgetypes.UpdateSchedule)
|
||||
if !ok {
|
||||
logrus.WithField("obj", obj).Errorf("Failed to convert to EdgeUpdateSchedule object")
|
||||
return nil, fmt.Errorf("failed to convert to EdgeUpdateSchedule object: %s", obj)
|
||||
return nil, fmt.Errorf("Failed to convert to EdgeUpdateSchedule object: %s", obj)
|
||||
}
|
||||
list = append(list, *item)
|
||||
return &edgetypes.UpdateSchedule{}, nil
|
||||
|
|
|
@ -24,7 +24,6 @@ type (
|
|||
BackupTo(w io.Writer) error
|
||||
Export(filename string) (err error)
|
||||
IsErrObjectNotFound(err error) bool
|
||||
|
||||
CustomTemplate() CustomTemplateService
|
||||
EdgeGroup() EdgeGroupService
|
||||
EdgeJob() EdgeJobService
|
||||
|
|
|
@ -156,6 +156,7 @@ func (store *Store) encryptDB() error {
|
|||
if err != nil {
|
||||
// Remove the new encrypted file that we failed to import
|
||||
os.Remove(store.connection.GetDatabaseFilePath())
|
||||
|
||||
log.Fatal().Err(portainerErrors.ErrDBImportFailed).Msg("")
|
||||
}
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@ func (store *Store) checkOrCreateInstanceID() error {
|
|||
instanceID := uid.String()
|
||||
return store.VersionService.StoreInstanceID(instanceID)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -88,7 +89,6 @@ func (store *Store) checkOrCreateDefaultSettings() error {
|
|||
|
||||
func (store *Store) checkOrCreateDefaultSSLSettings() error {
|
||||
_, err := store.SSLSettings().Settings()
|
||||
|
||||
if store.IsErrObjectNotFound(err) {
|
||||
defaultSSLSettings := &portainer.SSLSettings{
|
||||
HTTPEnabled: true,
|
||||
|
@ -96,6 +96,7 @@ func (store *Store) checkOrCreateDefaultSSLSettings() error {
|
|||
|
||||
return store.SSLSettings().UpdateSettings(defaultSSLSettings)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
@ -259,7 +259,7 @@ func migrateDBTestHelper(t *testing.T, srcPath, wantPath string) error {
|
|||
return fmt.Errorf("stat on %s failed: %s", databasePath, err)
|
||||
}
|
||||
|
||||
gotJSON, err := con.ExportJson(databasePath, false)
|
||||
gotJSON, err := con.ExportJSON(databasePath, false)
|
||||
if err != nil {
|
||||
t.Logf(
|
||||
"failed re-exporting database %s to JSON: %v",
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package migrator
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"runtime"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
|
||||
werrors "github.com/pkg/errors"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
|
@ -17,7 +16,7 @@ type migration struct {
|
|||
}
|
||||
|
||||
func migrationError(err error, context string) error {
|
||||
return werrors.Wrap(err, "failed in "+context)
|
||||
return errors.Wrap(err, "failed in "+context)
|
||||
}
|
||||
|
||||
func newMigration(dbversion int, migrate func() error) migration {
|
||||
|
|
|
@ -15,6 +15,7 @@ func (m *Migrator) updateUsersToDBVersion20() error {
|
|||
}
|
||||
|
||||
func (m *Migrator) updateSettingsToDBVersion20() error {
|
||||
log.Info().Msg("updating settings")
|
||||
legacySettings, err := m.settingsService.Settings()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -22,6 +22,7 @@ func (m *Migrator) updateTagsToDBVersion23() error {
|
|||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -19,5 +19,6 @@ func (m *Migrator) MigrateSettingsToDB30() error {
|
|||
|
||||
legacySettings.OAuthSettings.SSO = false
|
||||
legacySettings.OAuthSettings.LogoutURI = ""
|
||||
|
||||
return m.settingsService.UpdateSettings(legacySettings)
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ func (m *Migrator) migrateDBVersionToDB33() error {
|
|||
}
|
||||
|
||||
func (m *Migrator) migrateSettingsToDB33() error {
|
||||
log.Info().Msg("setting default kubctl shell")
|
||||
settings, err := m.settingsService.Settings()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -14,6 +14,8 @@ func (m *Migrator) migrateDBVersionToDB36() error {
|
|||
}
|
||||
|
||||
func (m *Migrator) migrateUsersToDB36() error {
|
||||
log.Info().Msg("updating user authorizations")
|
||||
|
||||
users, err := m.userService.Users()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -2,6 +2,7 @@ package migrator
|
|||
|
||||
import (
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
|
|
|
@ -518,7 +518,7 @@ func (store *Store) Export(filename string) (err error) {
|
|||
|
||||
if snapshot, err := store.Snapshot().Snapshots(); err != nil {
|
||||
if !store.IsErrObjectNotFound(err) {
|
||||
log.Err(err).Msg("Exporting Snapshots")
|
||||
log.Error().Err(err).Msg("exporting Snapshots")
|
||||
}
|
||||
} else {
|
||||
backup.Snapshot = snapshot
|
||||
|
@ -707,7 +707,7 @@ func (store *Store) Import(filename string) (err error) {
|
|||
|
||||
for _, user := range backup.User {
|
||||
if err := store.User().UpdateUser(user.ID, &user); err != nil {
|
||||
log.Debug().Str("user", fmt.Sprintf("%+v", user)).Err(err).Msg("user: failed to Update Database")
|
||||
log.Debug().Str("user", fmt.Sprintf("%+v", user)).Err(err).Msg("failed to update the user in the database")
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
package docker
|
||||
|
||||
const (
|
||||
ComposeStackNameLabel = "com.docker.compose.project"
|
||||
SwarmStackNameLabel = "com.docker.stack.namespace"
|
||||
)
|
|
@ -194,7 +194,7 @@ func snapshotContainers(snapshot *portainer.DockerSnapshot, cli *client.Client)
|
|||
}
|
||||
|
||||
for k, v := range container.Labels {
|
||||
if k == "com.docker.compose.project" {
|
||||
if k == ComposeStackNameLabel {
|
||||
stacks[v] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,15 +8,14 @@ import (
|
|||
"path"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
libstack "github.com/portainer/docker-compose-wrapper"
|
||||
"github.com/portainer/docker-compose-wrapper/compose"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/http/proxy"
|
||||
"github.com/portainer/portainer/api/http/proxy/factory"
|
||||
"github.com/portainer/portainer/api/internal/stackutils"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// ComposeStackManager is a wrapper for docker-compose binary
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
type kubernetesMockDeployer struct{}
|
||||
|
||||
// NewKubernetesDeployer creates a mock kubernetes deployer
|
||||
func NewKubernetesDeployer() portainer.KubernetesDeployer {
|
||||
return &kubernetesMockDeployer{}
|
||||
}
|
||||
|
|
|
@ -9,14 +9,14 @@ import (
|
|||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/dataservices"
|
||||
"github.com/portainer/portainer/api/http/proxy"
|
||||
"github.com/portainer/portainer/api/http/proxy/factory"
|
||||
"github.com/portainer/portainer/api/http/proxy/factory/kubernetes"
|
||||
"github.com/portainer/portainer/api/kubernetes/cli"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// KubernetesDeployer represents a service to deploy resources inside a Kubernetes environment(endpoint).
|
||||
|
@ -73,6 +73,7 @@ func (deployer *KubernetesDeployer) getToken(userID portainer.UserID, endpoint *
|
|||
if token == "" {
|
||||
return "", fmt.Errorf("can not get a valid user service account token")
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
|
@ -13,6 +12,7 @@ import (
|
|||
"github.com/portainer/portainer/api/internal/authorization"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
|
|
|
@ -22,6 +22,7 @@ func (payload *oauthPayload) Validate(r *http.Request) error {
|
|||
if govalidator.IsNull(payload.Code) {
|
||||
return errors.New("Invalid OAuth authorization code")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -3,13 +3,14 @@ package auth
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/dataservices"
|
||||
"github.com/portainer/portainer/api/http/proxy"
|
||||
"github.com/portainer/portainer/api/http/proxy/factory/kubernetes"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// Handler is the HTTP handler used to handle authentication operations.
|
||||
|
|
|
@ -56,6 +56,7 @@ func Test_backupHandlerWithoutPassword_shouldCreateATarballArchive(t *testing.T)
|
|||
body, _ := io.ReadAll(response.Body)
|
||||
|
||||
tmpdir := t.TempDir()
|
||||
|
||||
archivePath := filepath.Join(tmpdir, "archive.tar.gz")
|
||||
err := ioutil.WriteFile(archivePath, body, 0600)
|
||||
if err != nil {
|
||||
|
@ -91,6 +92,7 @@ func Test_backupHandlerWithPassword_shouldCreateEncryptedATarballArchive(t *test
|
|||
body, _ := io.ReadAll(response.Body)
|
||||
|
||||
tmpdir := t.TempDir()
|
||||
|
||||
dr, err := crypto.AesDecrypt(bytes.NewReader(body), []byte("secret"))
|
||||
if err != nil {
|
||||
t.Fatal("Failed to decrypt archive")
|
||||
|
|
|
@ -3,6 +3,7 @@ package customtemplates
|
|||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
|
@ -13,6 +14,7 @@ import (
|
|||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/filesystem"
|
||||
"github.com/portainer/portainer/api/git"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
"github.com/portainer/portainer/api/internal/authorization"
|
||||
|
||||
|
@ -290,6 +292,9 @@ func (handler *Handler) createCustomTemplateFromGitRepository(r *http.Request) (
|
|||
|
||||
err = handler.GitService.CloneRepository(projectPath, payload.RepositoryURL, payload.RepositoryReferenceName, repositoryUsername, repositoryPassword)
|
||||
if err != nil {
|
||||
if err == git.ErrAuthenticationFailure {
|
||||
return nil, fmt.Errorf("invalid git credential")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
|
@ -4,11 +4,13 @@ import (
|
|||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
)
|
||||
|
||||
type edgeGroupCreatePayload struct {
|
||||
|
@ -81,7 +83,7 @@ func (handler *Handler) edgeGroupCreate(w http.ResponseWriter, r *http.Request)
|
|||
return httperror.InternalServerError("Unable to retrieve environment from the database", err)
|
||||
}
|
||||
|
||||
if endpoint.Type == portainer.EdgeAgentOnDockerEnvironment || endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment {
|
||||
if endpointutils.IsEdgeEndpoint(endpoint) {
|
||||
endpointIDs = append(endpointIDs, endpoint.ID)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -53,5 +53,4 @@ func (handler *Handler) edgeGroupDelete(w http.ResponseWriter, r *http.Request)
|
|||
}
|
||||
|
||||
return response.Empty(w)
|
||||
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ func getEndpointTypes(endpointService dataservices.EndpointService, endpointIds
|
|||
for _, endpointID := range endpointIds {
|
||||
endpoint, err := endpointService.Endpoint(endpointID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed fetching endpoint: %w", err)
|
||||
return nil, fmt.Errorf("failed fetching environment: %w", err)
|
||||
}
|
||||
|
||||
typeSet[endpoint.Type] = true
|
||||
|
|
|
@ -4,12 +4,14 @@ import (
|
|||
"errors"
|
||||
"net/http"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/internal/edge"
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
)
|
||||
|
||||
type edgeGroupUpdatePayload struct {
|
||||
|
@ -102,7 +104,7 @@ func (handler *Handler) edgeGroupUpdate(w http.ResponseWriter, r *http.Request)
|
|||
return httperror.InternalServerError("Unable to retrieve environment from the database", err)
|
||||
}
|
||||
|
||||
if endpoint.Type == portainer.EdgeAgentOnDockerEnvironment || endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment {
|
||||
if endpointutils.IsEdgeEndpoint(endpoint) {
|
||||
endpointIDs = append(endpointIDs, endpoint.ID)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
)
|
||||
|
||||
// @id EdgeJobCreate
|
||||
|
@ -200,7 +201,7 @@ func (handler *Handler) addAndPersistEdgeJob(edgeJob *portainer.EdgeJob, file []
|
|||
return err
|
||||
}
|
||||
|
||||
if endpoint.Type != portainer.EdgeAgentOnDockerEnvironment && endpoint.Type != portainer.EdgeAgentOnKubernetesEnvironment {
|
||||
if !endpointutils.IsEdgeEndpoint(endpoint) {
|
||||
delete(edgeJob.Endpoints, ID)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,11 +5,12 @@ import (
|
|||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
)
|
||||
|
||||
type edgeJobUpdatePayload struct {
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
package edgestacks
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
|
@ -16,6 +14,9 @@ import (
|
|||
"github.com/portainer/portainer/api/dataservices"
|
||||
"github.com/portainer/portainer/api/filesystem"
|
||||
"github.com/portainer/portainer/api/internal/edge"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// @id EdgeStackCreate
|
||||
|
@ -271,7 +272,7 @@ func (handler *Handler) createSwarmStackFromGitRepository(r *http.Request) (*por
|
|||
|
||||
err = updateEndpointRelations(handler.DataStore.EndpointRelation(), stack.ID, relatedEndpointIds)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to update endpoint relations: %w", err)
|
||||
return nil, fmt.Errorf("Unable to update environment relations: %w", err)
|
||||
}
|
||||
|
||||
err = handler.DataStore.EdgeStack().Create(stack.ID, stack)
|
||||
|
@ -378,7 +379,7 @@ func (handler *Handler) createSwarmStackFromFileUpload(r *http.Request) (*portai
|
|||
|
||||
err = updateEndpointRelations(handler.DataStore.EndpointRelation(), stack.ID, relatedEndpointIds)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Unable to update endpoint relations: %w", err)
|
||||
return nil, fmt.Errorf("Unable to update environment relations: %w", err)
|
||||
}
|
||||
|
||||
err = handler.DataStore.EdgeStack().Create(stack.ID, stack)
|
||||
|
@ -408,14 +409,14 @@ func updateEndpointRelations(endpointRelationService dataservices.EndpointRelati
|
|||
for _, endpointID := range relatedEndpointIds {
|
||||
relation, err := endpointRelationService.EndpointRelation(endpointID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to find endpoint relation in database: %w", err)
|
||||
return fmt.Errorf("unable to find environment relation in database: %w", err)
|
||||
}
|
||||
|
||||
relation.EdgeStacks[edgeStackID] = true
|
||||
|
||||
err = endpointRelationService.UpdateEndpointRelation(endpointID, relation)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to persist endpoint relation in database: %w", err)
|
||||
return fmt.Errorf("unable to persist environment relation in database: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/internal/testhelpers"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ func (handler *Handler) edgeStackDelete(w http.ResponseWriter, r *http.Request)
|
|||
|
||||
relationConfig, err := fetchEndpointRelationsConfig(handler.DataStore)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to retrieve environments relations config from database", err)
|
||||
return httperror.InternalServerError("Unable to find environment relations in database", err)
|
||||
}
|
||||
|
||||
relatedEndpointIds, err := edge.EdgeStackRelatedEndpoints(edgeStack.EdgeGroups, relationConfig.endpoints, relationConfig.endpointGroups, relationConfig.edgeGroups)
|
||||
|
|
|
@ -46,7 +46,7 @@ func (handler *Handler) edgeStackFile(w http.ResponseWriter, r *http.Request) *h
|
|||
|
||||
stackFileContent, err := handler.FileService.GetFileContent(stack.ProjectPath, fileName)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to retrieve Compose file from disk", err)
|
||||
return httperror.InternalServerError("Unable to retrieve stack file from disk", err)
|
||||
}
|
||||
|
||||
return response.JSON(w, &stackFileResponse{StackFileContent: string(stackFileContent)})
|
||||
|
|
|
@ -3,7 +3,6 @@ package edgestacks
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
|
@ -19,6 +18,8 @@ import (
|
|||
"github.com/portainer/portainer/api/filesystem"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
"github.com/portainer/portainer/api/jwt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type gitService struct {
|
||||
|
|
|
@ -2,7 +2,6 @@ package edgestacks
|
|||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
|
@ -12,6 +11,7 @@ import (
|
|||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/filesystem"
|
||||
"github.com/portainer/portainer/api/internal/edge"
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
)
|
||||
|
||||
type updateEdgeStackPayload struct {
|
||||
|
|
|
@ -31,14 +31,14 @@ func (payload *createPayload) Validate(r *http.Request) error {
|
|||
return errors.New("Required to choose at least one group")
|
||||
}
|
||||
|
||||
if payload.Type != edgetypes.UpdateScheduleRollback && payload.Type != edgetypes.UpdateScheduleUpdate {
|
||||
return errors.New("Invalid schedule type")
|
||||
}
|
||||
|
||||
if len(payload.Environments) == 0 {
|
||||
return errors.New("No Environment is scheduled for update")
|
||||
}
|
||||
|
||||
if payload.Type != edgetypes.UpdateScheduleRollback && payload.Type != edgetypes.UpdateScheduleUpdate {
|
||||
return errors.New("Invalid schedule type")
|
||||
}
|
||||
|
||||
if payload.Time < time.Now().Unix() {
|
||||
return errors.New("Invalid time")
|
||||
}
|
||||
|
|
|
@ -3,14 +3,13 @@ package endpointedge
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/portainer/portainer/api/http/middlewares"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/dataservices"
|
||||
"github.com/portainer/portainer/api/http/middlewares"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// Handler is the HTTP handler used to handle edge environment(endpoint) operations.
|
||||
|
|
|
@ -2,13 +2,13 @@ package endpointproxy
|
|||
|
||||
import (
|
||||
"errors"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"net/http"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
)
|
||||
|
||||
func (handler *Handler) proxyRequestsToDockerAPI(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
|
|
|
@ -3,12 +3,12 @@ package endpointproxy
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"strings"
|
||||
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (handler *Handler) proxyRequestsToKubernetesAPI(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
|
|
|
@ -102,7 +102,6 @@ func Test_EndpointList_AgentVersion(t *testing.T) {
|
|||
is.ElementsMatch(test.expected, respIds)
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func Test_endpointList_edgeDeviceFilter(t *testing.T) {
|
||||
|
|
|
@ -32,6 +32,10 @@ func (handler *Handler) endpointSnapshots(w http.ResponseWriter, r *http.Request
|
|||
continue
|
||||
}
|
||||
|
||||
if endpoint.URL == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
snapshotError := handler.SnapshotService.SnapshotEndpoint(&endpoint)
|
||||
|
||||
latestEndpointReference, err := handler.DataStore.Endpoint().Endpoint(endpoint.ID)
|
||||
|
|
|
@ -38,8 +38,6 @@ func (handler *Handler) helmList(w http.ResponseWriter, r *http.Request) *httper
|
|||
KubernetesClusterAccess: clusterAccess,
|
||||
}
|
||||
|
||||
params := r.URL.Query()
|
||||
|
||||
// optional namespace. The library defaults to "default"
|
||||
namespace, _ := request.RetrieveQueryParameter(r, "namespace", true)
|
||||
if namespace != "" {
|
||||
|
@ -47,12 +45,12 @@ func (handler *Handler) helmList(w http.ResponseWriter, r *http.Request) *httper
|
|||
}
|
||||
|
||||
// optional filter
|
||||
if filter := params.Get("filter"); filter != "" {
|
||||
if filter, _ := request.RetrieveQueryParameter(r, "filter", true); filter != "" {
|
||||
listOpts.Filter = filter
|
||||
}
|
||||
|
||||
// optional selector
|
||||
if selector := params.Get("selector"); selector != "" {
|
||||
if selector, _ := request.RetrieveQueryParameter(r, "selector", true); selector != "" {
|
||||
listOpts.Selector = selector
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,6 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/portainer/libhelm/binary/test"
|
||||
|
||||
helper "github.com/portainer/portainer/api/internal/testhelpers"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
@ -32,6 +31,7 @@ func Test_helmRepoSearch(t *testing.T) {
|
|||
h.ServeHTTP(rr, req)
|
||||
|
||||
is.Equal(http.StatusOK, rr.Code, "Status should be 200 OK")
|
||||
|
||||
body, err := io.ReadAll(rr.Body)
|
||||
is.NoError(err, "ReadAll should not return error")
|
||||
is.NotEmpty(body, "Body should not be empty")
|
||||
|
|
|
@ -5,11 +5,11 @@ import (
|
|||
"net/http"
|
||||
"net/url"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/portainer/libhelm/options"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ func (handler *Handler) userCreateHelmRepo(w http.ResponseWriter, r *http.Reques
|
|||
if err != nil {
|
||||
return httperror.BadRequest("Invalid Helm repository URL", err)
|
||||
}
|
||||
|
||||
// lowercase, remove trailing slash
|
||||
p.URL = strings.TrimSuffix(strings.ToLower(p.URL), "/")
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@ func (handler *Handler) fdoConfigure(w http.ResponseWriter, r *http.Request) *ht
|
|||
|
||||
err := request.DecodeAndValidateJSONPayload(r, &payload)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("Invalid request payload")
|
||||
log.Error().Err(err).Msg("invalid request payload")
|
||||
|
||||
return httperror.BadRequest("Invalid request payload", err)
|
||||
}
|
||||
|
|
|
@ -3,13 +3,14 @@ package fdo
|
|||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
// @id duplicate
|
||||
|
|
|
@ -38,7 +38,7 @@ func (handler *Handler) getKubernetesConfig(w http.ResponseWriter, r *http.Reque
|
|||
if err != nil {
|
||||
return httperror.Forbidden("Permission denied to access environment", err)
|
||||
}
|
||||
bearerToken, err := handler.jwtService.GenerateTokenForKubeconfig(tokenData)
|
||||
bearerToken, err := handler.JwtService.GenerateTokenForKubeconfig(tokenData)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to generate JWT token", err)
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ func (handler *Handler) filterUserKubeEndpoints(r *http.Request) ([]portainer.En
|
|||
return nil, httperror.InternalServerError("Unable to retrieve info from request context", err)
|
||||
}
|
||||
|
||||
endpointGroups, err := handler.dataStore.EndpointGroup().EndpointGroups()
|
||||
endpointGroups, err := handler.DataStore.EndpointGroup().EndpointGroups()
|
||||
if err != nil {
|
||||
return nil, httperror.InternalServerError("Unable to retrieve environment groups from the database", err)
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ func (handler *Handler) filterUserKubeEndpoints(r *http.Request) ([]portainer.En
|
|||
if len(endpointIDs) > 0 {
|
||||
var endpoints []portainer.Endpoint
|
||||
for _, endpointID := range endpointIDs {
|
||||
endpoint, err := handler.dataStore.Endpoint().Endpoint(endpointID)
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(endpointID)
|
||||
if err != nil {
|
||||
return nil, httperror.InternalServerError("Unable to retrieve environment from the database", err)
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ func (handler *Handler) filterUserKubeEndpoints(r *http.Request) ([]portainer.En
|
|||
}
|
||||
|
||||
var kubeEndpoints []portainer.Endpoint
|
||||
endpoints, err := handler.dataStore.Endpoint().Endpoints()
|
||||
endpoints, err := handler.DataStore.Endpoint().Endpoints()
|
||||
if err != nil {
|
||||
return nil, httperror.InternalServerError("Unable to retrieve environments from the database", err)
|
||||
}
|
||||
|
@ -122,7 +122,7 @@ func (handler *Handler) buildConfig(r *http.Request, tokenData *portainer.TokenD
|
|||
authInfosSet := make(map[string]bool)
|
||||
|
||||
for idx, endpoint := range endpoints {
|
||||
instanceID := handler.kubernetesClientFactory.GetInstanceID()
|
||||
instanceID := handler.KubernetesClientFactory.GetInstanceID()
|
||||
serviceAccountName := kcli.UserServiceAccountName(int(tokenData.ID), instanceID)
|
||||
|
||||
configClusters[idx] = handler.buildCluster(r, endpoint)
|
||||
|
@ -145,6 +145,7 @@ func (handler *Handler) buildConfig(r *http.Request, tokenData *portainer.TokenD
|
|||
|
||||
func (handler *Handler) buildCluster(r *http.Request, endpoint portainer.Endpoint) clientV1.NamedCluster {
|
||||
kubeConfigInternal := handler.kubeClusterAccessService.GetData(r.Host, endpoint.ID)
|
||||
|
||||
return clientV1.NamedCluster{
|
||||
Name: buildClusterName(endpoint.Name),
|
||||
Cluster: clientV1.Cluster{
|
||||
|
|
|
@ -23,10 +23,10 @@ import (
|
|||
type Handler struct {
|
||||
*mux.Router
|
||||
authorizationService *authorization.Service
|
||||
dataStore dataservices.DataStore
|
||||
DataStore dataservices.DataStore
|
||||
KubernetesClient portainer.KubeClient
|
||||
kubernetesClientFactory *cli.ClientFactory
|
||||
jwtService dataservices.JWTService
|
||||
KubernetesClientFactory *cli.ClientFactory
|
||||
JwtService dataservices.JWTService
|
||||
kubeClusterAccessService kubernetes.KubeClusterAccessService
|
||||
}
|
||||
|
||||
|
@ -35,10 +35,10 @@ func NewHandler(bouncer *security.RequestBouncer, authorizationService *authoriz
|
|||
h := &Handler{
|
||||
Router: mux.NewRouter(),
|
||||
authorizationService: authorizationService,
|
||||
dataStore: dataStore,
|
||||
jwtService: jwtService,
|
||||
DataStore: dataStore,
|
||||
JwtService: jwtService,
|
||||
kubeClusterAccessService: kubeClusterAccessService,
|
||||
kubernetesClientFactory: kubernetesClientFactory,
|
||||
KubernetesClientFactory: kubernetesClientFactory,
|
||||
KubernetesClient: kubernetesClient,
|
||||
}
|
||||
|
||||
|
@ -90,7 +90,7 @@ func kubeOnlyMiddleware(next http.Handler) http.Handler {
|
|||
}
|
||||
|
||||
if !endpointutils.IsKubernetesEndpoint(endpoint) {
|
||||
errMessage := "Environment is not a kubernetes environment"
|
||||
errMessage := "environment is not a Kubernetes environment"
|
||||
httperror.WriteError(rw, http.StatusBadRequest, errMessage, errors.New(errMessage))
|
||||
return
|
||||
}
|
||||
|
@ -111,7 +111,7 @@ func (handler *Handler) kubeClient(next http.Handler) http.Handler {
|
|||
)
|
||||
}
|
||||
|
||||
endpoint, err := handler.dataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if err == portainerDsErrors.ErrObjectNotFound {
|
||||
httperror.WriteError(
|
||||
w,
|
||||
|
@ -128,11 +128,11 @@ func (handler *Handler) kubeClient(next http.Handler) http.Handler {
|
|||
)
|
||||
}
|
||||
|
||||
if handler.kubernetesClientFactory == nil {
|
||||
if handler.KubernetesClientFactory == nil {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
kubeCli, err := handler.kubernetesClientFactory.GetKubeClient(endpoint)
|
||||
kubeCli, err := handler.KubernetesClientFactory.GetKubeClient(endpoint)
|
||||
if err != nil {
|
||||
httperror.WriteError(
|
||||
w,
|
||||
|
|
|
@ -20,7 +20,7 @@ func (handler *Handler) getKubernetesIngressControllers(w http.ResponseWriter, r
|
|||
)
|
||||
}
|
||||
|
||||
endpoint, err := handler.dataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if err == portainerDsErrors.ErrObjectNotFound {
|
||||
return httperror.NotFound(
|
||||
"Unable to find an environment with the specified identifier inside the database",
|
||||
|
@ -41,7 +41,7 @@ func (handler *Handler) getKubernetesIngressControllers(w http.ResponseWriter, r
|
|||
)
|
||||
}
|
||||
|
||||
cli, err := handler.kubernetesClientFactory.GetKubeClient(endpoint)
|
||||
cli, err := handler.KubernetesClientFactory.GetKubeClient(endpoint)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError(
|
||||
"Unable to create Kubernetes client",
|
||||
|
@ -86,7 +86,7 @@ func (handler *Handler) getKubernetesIngressControllers(w http.ResponseWriter, r
|
|||
newClasses = append(newClasses, class)
|
||||
}
|
||||
endpoint.Kubernetes.Configuration.IngressClasses = newClasses
|
||||
err = handler.dataStore.Endpoint().UpdateEndpoint(
|
||||
err = handler.DataStore.Endpoint().UpdateEndpoint(
|
||||
portainer.EndpointID(endpointID),
|
||||
endpoint,
|
||||
)
|
||||
|
@ -120,8 +120,8 @@ func (handler *Handler) getKubernetesIngressControllersByNamespace(w http.Respon
|
|||
)
|
||||
}
|
||||
|
||||
endpoint, err := handler.dataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if err == portainerDsErrors.ErrObjectNotFound {
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if handler.DataStore.IsErrObjectNotFound(err) {
|
||||
return httperror.NotFound(
|
||||
"Unable to find an environment with the specified identifier inside the database",
|
||||
err,
|
||||
|
@ -183,7 +183,7 @@ func (handler *Handler) getKubernetesIngressControllersByNamespace(w http.Respon
|
|||
// Update the database to match the list of found controllers.
|
||||
// This includes pruning out controllers which no longer exist.
|
||||
endpoint.Kubernetes.Configuration.IngressClasses = updatedClasses
|
||||
err = handler.dataStore.Endpoint().UpdateEndpoint(
|
||||
err = handler.DataStore.Endpoint().UpdateEndpoint(
|
||||
portainer.EndpointID(endpointID),
|
||||
endpoint,
|
||||
)
|
||||
|
@ -205,8 +205,8 @@ func (handler *Handler) updateKubernetesIngressControllers(w http.ResponseWriter
|
|||
)
|
||||
}
|
||||
|
||||
endpoint, err := handler.dataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if err == portainerDsErrors.ErrObjectNotFound {
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if handler.DataStore.IsErrObjectNotFound(err) {
|
||||
return httperror.NotFound(
|
||||
"Unable to find an environment with the specified identifier inside the database",
|
||||
err,
|
||||
|
@ -227,7 +227,7 @@ func (handler *Handler) updateKubernetesIngressControllers(w http.ResponseWriter
|
|||
)
|
||||
}
|
||||
|
||||
cli, err := handler.kubernetesClientFactory.GetKubeClient(endpoint)
|
||||
cli, err := handler.KubernetesClientFactory.GetKubeClient(endpoint)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError(
|
||||
"Unable to create Kubernetes client",
|
||||
|
@ -269,7 +269,7 @@ func (handler *Handler) updateKubernetesIngressControllers(w http.ResponseWriter
|
|||
}
|
||||
|
||||
endpoint.Kubernetes.Configuration.IngressClasses = newClasses
|
||||
err = handler.dataStore.Endpoint().UpdateEndpoint(
|
||||
err = handler.DataStore.Endpoint().UpdateEndpoint(
|
||||
portainer.EndpointID(endpointID),
|
||||
endpoint,
|
||||
)
|
||||
|
@ -291,8 +291,8 @@ func (handler *Handler) updateKubernetesIngressControllersByNamespace(w http.Res
|
|||
)
|
||||
}
|
||||
|
||||
endpoint, err := handler.dataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if err == portainerDsErrors.ErrObjectNotFound {
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if handler.DataStore.IsErrObjectNotFound(err) {
|
||||
return httperror.NotFound(
|
||||
"Unable to find an environment with the specified identifier inside the database",
|
||||
err,
|
||||
|
@ -369,7 +369,7 @@ PayloadLoop:
|
|||
}
|
||||
|
||||
endpoint.Kubernetes.Configuration.IngressClasses = updatedClasses
|
||||
err = handler.dataStore.Endpoint().UpdateEndpoint(
|
||||
err = handler.DataStore.Endpoint().UpdateEndpoint(
|
||||
portainer.EndpointID(endpointID),
|
||||
endpoint,
|
||||
)
|
||||
|
|
|
@ -73,20 +73,12 @@ func (handler *Handler) updateKubernetesNamespace(w http.ResponseWriter, r *http
|
|||
var payload models.K8sNamespaceDetails
|
||||
err := request.DecodeAndValidateJSONPayload(r, &payload)
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{
|
||||
StatusCode: http.StatusBadRequest,
|
||||
Message: "Invalid request payload",
|
||||
Err: err,
|
||||
}
|
||||
return httperror.BadRequest("Invalid request payload", err)
|
||||
}
|
||||
|
||||
err = cli.UpdateNamespace(payload)
|
||||
if err != nil {
|
||||
return &httperror.HandlerError{
|
||||
StatusCode: http.StatusInternalServerError,
|
||||
Message: "Unable to retrieve nodes limits",
|
||||
Err: err,
|
||||
}
|
||||
return httperror.InternalServerError("Unable to retrieve nodes limits", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -32,14 +32,14 @@ func (handler *Handler) getKubernetesNodesLimits(w http.ResponseWriter, r *http.
|
|||
return httperror.BadRequest("Invalid environment identifier route variable", err)
|
||||
}
|
||||
|
||||
endpoint, err := handler.dataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if handler.dataStore.IsErrObjectNotFound(err) {
|
||||
endpoint, err := handler.DataStore.Endpoint().Endpoint(portainer.EndpointID(endpointID))
|
||||
if handler.DataStore.IsErrObjectNotFound(err) {
|
||||
return httperror.NotFound("Unable to find an environment with the specified identifier inside the database", err)
|
||||
} else if err != nil {
|
||||
return httperror.InternalServerError("Unable to find an environment with the specified identifier inside the database", err)
|
||||
}
|
||||
|
||||
cli, err := handler.kubernetesClientFactory.GetKubeClient(endpoint)
|
||||
cli, err := handler.KubernetesClientFactory.GetKubeClient(endpoint)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to create Kubernetes client", err)
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@ func (handler *Handler) namespacesToggleSystem(rw http.ResponseWriter, r *http.R
|
|||
return httperror.BadRequest("Invalid request payload", err)
|
||||
}
|
||||
|
||||
kubeClient, err := handler.kubernetesClientFactory.GetKubeClient(endpoint)
|
||||
kubeClient, err := handler.KubernetesClientFactory.GetKubeClient(endpoint)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to create kubernetes client", err)
|
||||
}
|
||||
|
|
|
@ -119,9 +119,7 @@ func (handler *Handler) registryCreate(w http.ResponseWriter, r *http.Request) *
|
|||
Ecr: payload.Ecr,
|
||||
}
|
||||
|
||||
rs := handler.DataStore.Registry()
|
||||
|
||||
registries, err := rs.Registries()
|
||||
registries, err := handler.DataStore.Registry().Registries()
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to retrieve registries from the database", err)
|
||||
}
|
||||
|
@ -134,7 +132,7 @@ func (handler *Handler) registryCreate(w http.ResponseWriter, r *http.Request) *
|
|||
}
|
||||
}
|
||||
|
||||
err = rs.Create(registry)
|
||||
err = handler.DataStore.Registry().Create(registry)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to persist the registry inside the database", err)
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ func delete_TestHandler_registryUpdate(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
handler.Router.ServeHTTP(w, r)
|
||||
handler.ServeHTTP(w, r)
|
||||
assert.Equal(t, http.StatusOK, w.Code)
|
||||
// Registry type should remain intact
|
||||
assert.Equal(t, registry.Type, updatedRegistry.Type)
|
||||
|
@ -85,5 +85,4 @@ func delete_TestHandler_registryUpdate(t *testing.T) {
|
|||
assert.Equal(t, *payload.Authentication, updatedRegistry.Authentication)
|
||||
assert.Equal(t, *payload.Username, updatedRegistry.Username)
|
||||
assert.Equal(t, *payload.Password, updatedRegistry.Password)
|
||||
|
||||
}
|
||||
|
|
|
@ -141,7 +141,6 @@ func (handler *Handler) settingsUpdate(w http.ResponseWriter, r *http.Request) *
|
|||
if err != nil {
|
||||
return httperror.BadRequest("Invalid Helm repository URL. Must correspond to a valid URL format", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
settings.HelmRepositoryURL = newHelmRepo
|
||||
|
@ -161,12 +160,15 @@ func (handler *Handler) settingsUpdate(w http.ResponseWriter, r *http.Request) *
|
|||
if payload.LDAPSettings != nil {
|
||||
ldapReaderDN := settings.LDAPSettings.ReaderDN
|
||||
ldapPassword := settings.LDAPSettings.Password
|
||||
|
||||
if payload.LDAPSettings.ReaderDN != "" {
|
||||
ldapReaderDN = payload.LDAPSettings.ReaderDN
|
||||
}
|
||||
|
||||
if payload.LDAPSettings.Password != "" {
|
||||
ldapPassword = payload.LDAPSettings.Password
|
||||
}
|
||||
|
||||
settings.LDAPSettings = *payload.LDAPSettings
|
||||
settings.LDAPSettings.ReaderDN = ldapReaderDN
|
||||
settings.LDAPSettings.Password = ldapPassword
|
||||
|
|
|
@ -6,8 +6,6 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/pkg/errors"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
|
@ -16,6 +14,8 @@ import (
|
|||
"github.com/portainer/portainer/api/http/security"
|
||||
"github.com/portainer/portainer/api/internal/stackutils"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
|
@ -438,6 +438,7 @@ func (handler *Handler) createComposeDeployConfig(r *http.Request, stack *portai
|
|||
if err != nil {
|
||||
return nil, httperror.InternalServerError("Unable to retrieve registries from the database", err)
|
||||
}
|
||||
|
||||
filteredRegistries := security.FilterRegistries(registries, user, securityContext.UserMemberships, endpoint.ID)
|
||||
|
||||
config := &composeStackDeploymentConfig{
|
||||
|
|
|
@ -8,9 +8,8 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
|
@ -133,6 +132,7 @@ func (handler *Handler) createKubernetesStackFromFileContent(w http.ResponseWrit
|
|||
}
|
||||
|
||||
stackFolder := strconv.Itoa(int(stack.ID))
|
||||
|
||||
projectPath, err := handler.FileService.StoreStackFileFromBytes(stackFolder, stack.EntryPoint, []byte(payload.StackFileContent))
|
||||
if err != nil {
|
||||
fileType := "Manifest"
|
||||
|
@ -274,7 +274,7 @@ func (handler *Handler) createKubernetesStackFromGitRepository(w http.ResponseWr
|
|||
|
||||
err = handler.DataStore.Stack().Create(stack)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to persist the stack inside the database", err)
|
||||
return httperror.InternalServerError("Unable to persist the Kubernetes stack inside the database", err)
|
||||
}
|
||||
|
||||
resp := &createKubernetesStackResponse{
|
||||
|
|
|
@ -6,9 +6,9 @@ import (
|
|||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
|
@ -378,6 +378,7 @@ func (handler *Handler) createSwarmDeployConfig(r *http.Request, stack *portaine
|
|||
if err != nil {
|
||||
return nil, httperror.InternalServerError("Unable to retrieve registries from the database", err)
|
||||
}
|
||||
|
||||
filteredRegistries := security.FilterRegistries(registries, user, securityContext.UserMemberships, endpoint.ID)
|
||||
|
||||
config := &swarmStackDeploymentConfig{
|
||||
|
|
|
@ -199,7 +199,7 @@ func (handler *Handler) deleteStack(userID portainer.UserID, stack *portainer.St
|
|||
//then process the remove operation
|
||||
if stack.IsComposeFormat {
|
||||
fileNames := append([]string{stack.EntryPoint}, stack.AdditionalFiles...)
|
||||
tmpDir, err := ioutil.TempDir("", "kub_delete")
|
||||
tmpDir, err := ioutil.TempDir("", "kube_delete")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to create temp directory for deleting kub stack")
|
||||
}
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
package teammemberships
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/portainer/api/dataservices"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
|
|
|
@ -5,13 +5,14 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
httperrors "github.com/portainer/portainer/api/http/errors"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
)
|
||||
|
||||
type userUpdatePayload struct {
|
||||
|
@ -122,5 +123,6 @@ func (handler *Handler) userUpdate(w http.ResponseWriter, r *http.Request) *http
|
|||
|
||||
// remove all of the users persisted API keys
|
||||
handler.apiKeyService.InvalidateUserKeyCache(user.ID)
|
||||
|
||||
return response.JSON(w, user)
|
||||
}
|
||||
|
|
|
@ -5,13 +5,14 @@ import (
|
|||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
httperrors "github.com/portainer/portainer/api/http/errors"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
)
|
||||
|
||||
type userUpdatePasswordPayload struct {
|
||||
|
|
|
@ -5,11 +5,12 @@ import (
|
|||
"github.com/portainer/portainer/api/internal/authorization"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/docker"
|
||||
"github.com/portainer/portainer/api/http/security"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
// Handler is the HTTP handler used to handle webhook operations.
|
||||
|
|
|
@ -7,12 +7,13 @@ import (
|
|||
"github.com/portainer/portainer/api/http/security"
|
||||
"github.com/portainer/portainer/api/internal/registryutils/access"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/gofrs/uuid"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
"github.com/portainer/libhttp/response"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/gofrs/uuid"
|
||||
)
|
||||
|
||||
type webhookCreatePayload struct {
|
||||
|
|
|
@ -6,11 +6,12 @@ import (
|
|||
"net/http/httputil"
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/gorilla/websocket"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
// @summary Attach a websocket
|
||||
|
|
|
@ -8,11 +8,12 @@ import (
|
|||
"net/http/httputil"
|
||||
"time"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/gorilla/websocket"
|
||||
httperror "github.com/portainer/libhttp/error"
|
||||
"github.com/portainer/libhttp/request"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
|
||||
"github.com/asaskevich/govalidator"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
type execStartOperationPayload struct {
|
||||
|
|
|
@ -2,10 +2,11 @@ package websocket
|
|||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/crypto"
|
||||
"net"
|
||||
"net/url"
|
||||
|
||||
"github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/crypto"
|
||||
)
|
||||
|
||||
func initDial(endpoint *portainer.Endpoint) (net.Conn, error) {
|
||||
|
|
|
@ -91,12 +91,14 @@ func (handler *Handler) websocketPodExec(w http.ResponseWriter, r *http.Request)
|
|||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to proxy websocket request to agent", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
} else if endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment {
|
||||
err := handler.proxyEdgeAgentWebsocketRequest(w, r, params)
|
||||
if err != nil {
|
||||
return httperror.InternalServerError("Unable to proxy websocket request to Edge agent", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package websocket
|
||||
|
||||
import (
|
||||
"github.com/portainer/portainer/api"
|
||||
)
|
||||
import "github.com/portainer/portainer/api"
|
||||
|
||||
type webSocketRequestParams struct {
|
||||
ID string
|
||||
|
|
|
@ -23,7 +23,7 @@ func (transport *Transport) proxyContainerGroupRequest(request *http.Request) (*
|
|||
}
|
||||
|
||||
func (transport *Transport) proxyContainerGroupPutRequest(request *http.Request) (*http.Response, error) {
|
||||
//add a lock before processing existense check
|
||||
//add a lock before processing existence check
|
||||
transport.mutex.Lock()
|
||||
defer transport.mutex.Unlock()
|
||||
|
||||
|
|
|
@ -24,7 +24,6 @@ func (transport *Transport) applyPortainerContainers(resources []interface{}) ([
|
|||
continue
|
||||
}
|
||||
responseObject, _ = transport.applyPortainerContainer(responseObject)
|
||||
|
||||
decoratedResourceData = append(decoratedResourceData, responseObject)
|
||||
}
|
||||
return decoratedResourceData, nil
|
||||
|
|
|
@ -18,6 +18,8 @@ type edgeTransport struct {
|
|||
// NewAgentTransport returns a new transport that can be used to send signed requests to a Portainer Edge agent
|
||||
func NewEdgeTransport(dataStore dataservices.DataStore, signatureService portainer.DigitalSignatureService, reverseTunnelService portainer.ReverseTunnelService, endpoint *portainer.Endpoint, tokenManager *tokenManager, k8sClientFactory *cli.ClientFactory) *edgeTransport {
|
||||
transport := &edgeTransport{
|
||||
reverseTunnelService: reverseTunnelService,
|
||||
signatureService: signatureService,
|
||||
baseTransport: newBaseTransport(
|
||||
&http.Transport{},
|
||||
tokenManager,
|
||||
|
@ -25,8 +27,6 @@ func NewEdgeTransport(dataStore dataservices.DataStore, signatureService portain
|
|||
k8sClientFactory,
|
||||
dataStore,
|
||||
),
|
||||
reverseTunnelService: reverseTunnelService,
|
||||
signatureService: signatureService,
|
||||
}
|
||||
|
||||
return transport
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package kubernetes
|
||||
|
||||
import (
|
||||
"github.com/portainer/portainer/api/internal/registryutils"
|
||||
"net/http"
|
||||
|
||||
"github.com/portainer/portainer/api/internal/registryutils"
|
||||
)
|
||||
|
||||
func (transport *baseTransport) refreshRegistry(request *http.Request, namespace string) (err error) {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"strconv"
|
||||
"sync"
|
||||
|
||||
"github.com/orcaman/concurrent-map"
|
||||
cmap "github.com/orcaman/concurrent-map"
|
||||
)
|
||||
|
||||
type (
|
||||
|
|
|
@ -3,7 +3,6 @@ package kubernetes
|
|||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
@ -17,6 +16,7 @@ import (
|
|||
"github.com/portainer/portainer/api/http/security"
|
||||
"github.com/portainer/portainer/api/kubernetes/cli"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ func marshal(contentType string, data interface{}) ([]byte, error) {
|
|||
}
|
||||
|
||||
func unmarshal(contentType string, body []byte, returnBody interface{}) error {
|
||||
// Note: contentType can look look like: "application/json" or "application/json; charset=utf-8"
|
||||
// Note: contentType can look like: "application/json" or "application/json; charset=utf-8"
|
||||
mediaType, _, err := mime.ParseMediaType(contentType)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -2,12 +2,12 @@ package utils
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
|
@ -18,7 +18,10 @@ func GetResponseAsJSONObject(response *http.Response) (map[string]interface{}, e
|
|||
return nil, err
|
||||
}
|
||||
|
||||
responseObject := responseData.(map[string]interface{})
|
||||
responseObject, ok := responseData.(map[string]interface{})
|
||||
if !ok {
|
||||
return nil, nil
|
||||
}
|
||||
return responseObject, nil
|
||||
}
|
||||
|
||||
|
@ -28,6 +31,9 @@ func GetResponseAsJSONArray(response *http.Response) ([]interface{}, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if responseData == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
switch responseObject := responseData.(type) {
|
||||
case []interface{}:
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
)
|
||||
|
||||
type (
|
||||
// Manager represents a service used to manage proxies to environments (endpoints).
|
||||
// Manager represents a service used to manage proxies to environments (endpoints) and extensions.
|
||||
Manager struct {
|
||||
proxyFactory *factory.ProxyFactory
|
||||
endpointProxies cmap.ConcurrentMap
|
||||
|
|
|
@ -42,7 +42,7 @@ func AuthorizedResourceControlAccess(resourceControl *portainer.ResourceControl,
|
|||
// AuthorizedResourceControlUpdate ensure that the user can update a resource control object.
|
||||
// A non-administrator user cannot create a resource control where:
|
||||
// * the Public flag is set false
|
||||
// * the AdministatorsOnly flag is set to true
|
||||
// * the AdministratorsOnly flag is set to true
|
||||
// * he wants to create a resource control without any user/team accesses
|
||||
// * he wants to add more than one user in the user accesses
|
||||
// * he wants to add a user in the user accesses that is not corresponding to its id
|
||||
|
|
|
@ -409,7 +409,7 @@ func (bouncer *RequestBouncer) newRestrictedContextRequest(userID portainer.User
|
|||
}, nil
|
||||
}
|
||||
|
||||
// EdgeComputeOperation defines a restriced edge compute operation.
|
||||
// EdgeComputeOperation defines a restricted edge compute operation.
|
||||
// Use of this operation will only be authorized if edgeCompute is enabled in settings
|
||||
func (bouncer *RequestBouncer) EdgeComputeOperation(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"github.com/portainer/portainer/api/datastore"
|
||||
httperrors "github.com/portainer/portainer/api/http/errors"
|
||||
"github.com/portainer/portainer/api/jwt"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
|
|
@ -74,7 +74,6 @@ func FilterRegistries(registries []portainer.Registry, user *portainer.User, tea
|
|||
}
|
||||
|
||||
filteredRegistries := []portainer.Registry{}
|
||||
|
||||
for _, registry := range registries {
|
||||
if AuthorizedRegistryAccess(®istry, user, teamMemberships, endpointID) {
|
||||
filteredRegistries = append(filteredRegistries, registry)
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package edge
|
||||
|
||||
import (
|
||||
"github.com/portainer/portainer/api"
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"github.com/portainer/portainer/api/internal/endpointutils"
|
||||
"github.com/portainer/portainer/api/internal/tag"
|
||||
)
|
||||
|
||||
|
@ -13,7 +14,7 @@ func EdgeGroupRelatedEndpoints(edgeGroup *portainer.EdgeGroup, endpoints []porta
|
|||
|
||||
endpointIDs := []portainer.EndpointID{}
|
||||
for _, endpoint := range endpoints {
|
||||
if endpoint.Type != portainer.EdgeAgentOnDockerEnvironment && endpoint.Type != portainer.EdgeAgentOnKubernetesEnvironment {
|
||||
if !endpointutils.IsEdgeEndpoint(&endpoint) {
|
||||
continue
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package edge
|
|||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"github.com/portainer/portainer/api"
|
||||
)
|
||||
|
||||
|
|
|
@ -23,5 +23,4 @@ func EndpointRelatedEdgeStacks(endpoint *portainer.Endpoint, endpointGroup *port
|
|||
}
|
||||
|
||||
return relatedEdgeStacks
|
||||
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package registryutils
|
|||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
)
|
||||
|
||||
|
|
|
@ -213,6 +213,10 @@ func (service *Service) snapshotEndpoints() error {
|
|||
continue
|
||||
}
|
||||
|
||||
if endpoint.URL == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
snapshotError := service.SnapshotEndpoint(&endpoint)
|
||||
|
||||
latestEndpointReference, err := service.dataStore.Endpoint().Endpoint(endpoint.ID)
|
||||
|
|
|
@ -11,7 +11,6 @@ import (
|
|||
// to prevent an error when url has port but no protocol prefix
|
||||
// we add `//` prefix if needed
|
||||
func ParseURL(endpointURL string) (*url.URL, error) {
|
||||
|
||||
if !strings.HasPrefix(endpointURL, "http") &&
|
||||
!strings.HasPrefix(endpointURL, "tcp") &&
|
||||
!strings.HasPrefix(endpointURL, "//") &&
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package jwt
|
||||
|
||||
import (
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
"time"
|
||||
|
||||
portainer "github.com/portainer/portainer/api"
|
||||
)
|
||||
|
||||
// GenerateTokenForKubeconfig generates a new JWT token for Kubeconfig
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue