mirror of https://github.com/portainer/portainer
resolve conflicts
commit
1991475437
|
@ -1,54 +0,0 @@
|
||||||
# Config for Stalebot, limited to only `issues`
|
|
||||||
only: issues
|
|
||||||
|
|
||||||
# Issues config
|
|
||||||
issues:
|
|
||||||
daysUntilStale: 60
|
|
||||||
daysUntilClose: 7
|
|
||||||
|
|
||||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
|
||||||
limitPerRun: 30
|
|
||||||
|
|
||||||
# Issues with these labels will never be considered stale
|
|
||||||
exemptLabels:
|
|
||||||
- kind/enhancement
|
|
||||||
- kind/question
|
|
||||||
- kind/style
|
|
||||||
- kind/workaround
|
|
||||||
- kind/refactor
|
|
||||||
- bug/need-confirmation
|
|
||||||
- bug/confirmed
|
|
||||||
- status/discuss
|
|
||||||
|
|
||||||
# Only issues with all of these labels are checked if stale. Defaults to `[]` (disabled)
|
|
||||||
onlyLabels: []
|
|
||||||
|
|
||||||
# Set to true to ignore issues in a project (defaults to false)
|
|
||||||
exemptProjects: true
|
|
||||||
# Set to true to ignore issues in a milestone (defaults to false)
|
|
||||||
exemptMilestones: true
|
|
||||||
# Set to true to ignore issues with an assignee (defaults to false)
|
|
||||||
exemptAssignees: true
|
|
||||||
|
|
||||||
# Label to use when marking an issue as stale
|
|
||||||
staleLabel: status/stale
|
|
||||||
|
|
||||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
|
||||||
markComment: >
|
|
||||||
This issue has been marked as stale as it has not had recent activity,
|
|
||||||
it will be closed if no further activity occurs in the next 7 days.
|
|
||||||
If you believe that it has been incorrectly labelled as stale,
|
|
||||||
leave a comment and the label will be removed.
|
|
||||||
|
|
||||||
# Comment to post when removing the stale label.
|
|
||||||
# unmarkComment: >
|
|
||||||
# Your comment here.
|
|
||||||
|
|
||||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
|
||||||
closeComment: >
|
|
||||||
Since no further activity has appeared on this issue it will be closed.
|
|
||||||
If you believe that it has been incorrectly closed, leave a comment
|
|
||||||
mentioning `ametdoohan`, `balasu` or `keverv` and one of our staff will then review the issue.
|
|
||||||
|
|
||||||
Note - If it is an old bug report, make sure that it is reproduceable in the
|
|
||||||
latest version of Portainer as it may have already been fixed.
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
name: Close Stale Issues
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 12 * * *'
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
issues: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v4.0.0
|
||||||
|
with:
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
# Issue Config
|
||||||
|
days-before-issue-stale: 60
|
||||||
|
days-before-issue-close: 7
|
||||||
|
stale-issue-label: 'status/stale'
|
||||||
|
exempt-all-issue-milestones: true # Do not stale issues in a milestone
|
||||||
|
exempt-issue-labels: kind/enhancement, kind/style, kind/workaround, kind/refactor, bug/need-confirmation, bug/confirmed, status/discuss
|
||||||
|
stale-issue-message: 'This issue has been marked as stale as it has not had recent activity, it will be closed if no further activity occurs in the next 7 days. If you believe that it has been incorrectly labelled as stale, leave a comment and the label will be removed.'
|
||||||
|
close-issue-message: 'Since no further activity has appeared on this issue it will be closed. If you believe that it has been incorrectly closed, leave a comment mentioning `portainer/support` and one of our staff will then review the issue. Note - If it is an old bug report, make sure that it is reproduceable in the latest version of Portainer as it may have already been fixed.'
|
||||||
|
|
||||||
|
# Pull Request Config
|
||||||
|
days-before-pr-stale: -1 # Do not stale pull request
|
||||||
|
days-before-pr-close: -1 # Do not close pull request
|
|
@ -28,7 +28,6 @@ import (
|
||||||
"github.com/portainer/portainer/api/kubernetes"
|
"github.com/portainer/portainer/api/kubernetes"
|
||||||
kubecli "github.com/portainer/portainer/api/kubernetes/cli"
|
kubecli "github.com/portainer/portainer/api/kubernetes/cli"
|
||||||
"github.com/portainer/portainer/api/ldap"
|
"github.com/portainer/portainer/api/ldap"
|
||||||
"github.com/portainer/portainer/api/libcompose"
|
|
||||||
"github.com/portainer/portainer/api/oauth"
|
"github.com/portainer/portainer/api/oauth"
|
||||||
"github.com/portainer/portainer/api/scheduler"
|
"github.com/portainer/portainer/api/scheduler"
|
||||||
"github.com/portainer/portainer/api/stacks"
|
"github.com/portainer/portainer/api/stacks"
|
||||||
|
@ -86,18 +85,17 @@ func shutdownDatastore(shutdownCtx context.Context, datastore portainer.DataStor
|
||||||
datastore.Close()
|
datastore.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
func initComposeStackManager(assetsPath string, dataStorePath string, reverseTunnelService portainer.ReverseTunnelService, proxyManager *proxy.Manager) portainer.ComposeStackManager {
|
func initComposeStackManager(assetsPath string, configPath string, reverseTunnelService portainer.ReverseTunnelService, proxyManager *proxy.Manager) portainer.ComposeStackManager {
|
||||||
composeWrapper, err := exec.NewComposeStackManager(assetsPath, dataStorePath, proxyManager)
|
composeWrapper, err := exec.NewComposeStackManager(assetsPath, configPath, proxyManager)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("[INFO] [main,compose] [message: falling-back to libcompose] [error: %s]", err)
|
log.Fatalf("failed creating compose manager: %s", err)
|
||||||
return libcompose.NewComposeStackManager(dataStorePath, reverseTunnelService)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return composeWrapper
|
return composeWrapper
|
||||||
}
|
}
|
||||||
|
|
||||||
func initSwarmStackManager(assetsPath string, dataStorePath string, signatureService portainer.DigitalSignatureService, fileService portainer.FileService, reverseTunnelService portainer.ReverseTunnelService) (portainer.SwarmStackManager, error) {
|
func initSwarmStackManager(assetsPath string, configPath string, signatureService portainer.DigitalSignatureService, fileService portainer.FileService, reverseTunnelService portainer.ReverseTunnelService) (portainer.SwarmStackManager, error) {
|
||||||
return exec.NewSwarmStackManager(assetsPath, dataStorePath, signatureService, fileService, reverseTunnelService)
|
return exec.NewSwarmStackManager(assetsPath, configPath, signatureService, fileService, reverseTunnelService)
|
||||||
}
|
}
|
||||||
|
|
||||||
func initKubernetesDeployer(kubernetesTokenCacheManager *kubeproxy.TokenCacheManager, kubernetesClientFactory *kubecli.ClientFactory, dataStore portainer.DataStore, reverseTunnelService portainer.ReverseTunnelService, signatureService portainer.DigitalSignatureService, proxyManager *proxy.Manager, assetsPath string) portainer.KubernetesDeployer {
|
func initKubernetesDeployer(kubernetesTokenCacheManager *kubeproxy.TokenCacheManager, kubernetesClientFactory *kubecli.ClientFactory, dataStore portainer.DataStore, reverseTunnelService portainer.ReverseTunnelService, signatureService portainer.DigitalSignatureService, proxyManager *proxy.Manager, assetsPath string) portainer.KubernetesDeployer {
|
||||||
|
@ -446,14 +444,17 @@ func buildServer(flags *portainer.CLIFlags) portainer.Server {
|
||||||
authorizationService := authorization.NewService(dataStore)
|
authorizationService := authorization.NewService(dataStore)
|
||||||
authorizationService.K8sClientFactory = kubernetesClientFactory
|
authorizationService.K8sClientFactory = kubernetesClientFactory
|
||||||
|
|
||||||
swarmStackManager, err := initSwarmStackManager(*flags.Assets, *flags.Data, digitalSignatureService, fileService, reverseTunnelService)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("failed initializing swarm stack manager: %v", err)
|
|
||||||
}
|
|
||||||
kubernetesTokenCacheManager := kubeproxy.NewTokenCacheManager()
|
kubernetesTokenCacheManager := kubeproxy.NewTokenCacheManager()
|
||||||
proxyManager := proxy.NewManager(dataStore, digitalSignatureService, reverseTunnelService, dockerClientFactory, kubernetesClientFactory, kubernetesTokenCacheManager)
|
proxyManager := proxy.NewManager(dataStore, digitalSignatureService, reverseTunnelService, dockerClientFactory, kubernetesClientFactory, kubernetesTokenCacheManager)
|
||||||
|
|
||||||
composeStackManager := initComposeStackManager(*flags.Assets, *flags.Data, reverseTunnelService, proxyManager)
|
dockerConfigPath := fileService.GetDockerConfigPath()
|
||||||
|
|
||||||
|
composeStackManager := initComposeStackManager(*flags.Assets, dockerConfigPath, reverseTunnelService, proxyManager)
|
||||||
|
|
||||||
|
swarmStackManager, err := initSwarmStackManager(*flags.Assets, dockerConfigPath, digitalSignatureService, fileService, reverseTunnelService)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("failed initializing swarm stack manager: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
kubernetesDeployer := initKubernetesDeployer(kubernetesTokenCacheManager, kubernetesClientFactory, dataStore, reverseTunnelService, digitalSignatureService, proxyManager, *flags.Assets)
|
kubernetesDeployer := initKubernetesDeployer(kubernetesTokenCacheManager, kubernetesClientFactory, dataStore, reverseTunnelService, digitalSignatureService, proxyManager, *flags.Assets)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package exec
|
package exec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
@ -8,7 +9,10 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
wrapper "github.com/portainer/docker-compose-wrapper"
|
|
||||||
|
libstack "github.com/portainer/docker-compose-wrapper"
|
||||||
|
"github.com/portainer/docker-compose-wrapper/compose"
|
||||||
|
|
||||||
portainer "github.com/portainer/portainer/api"
|
portainer "github.com/portainer/portainer/api"
|
||||||
"github.com/portainer/portainer/api/http/proxy"
|
"github.com/portainer/portainer/api/http/proxy"
|
||||||
"github.com/portainer/portainer/api/http/proxy/factory"
|
"github.com/portainer/portainer/api/http/proxy/factory"
|
||||||
|
@ -16,33 +20,31 @@ import (
|
||||||
|
|
||||||
// ComposeStackManager is a wrapper for docker-compose binary
|
// ComposeStackManager is a wrapper for docker-compose binary
|
||||||
type ComposeStackManager struct {
|
type ComposeStackManager struct {
|
||||||
wrapper *wrapper.ComposeWrapper
|
deployer libstack.Deployer
|
||||||
configPath string
|
|
||||||
proxyManager *proxy.Manager
|
proxyManager *proxy.Manager
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewComposeStackManager returns a docker-compose wrapper if corresponding binary present, otherwise nil
|
// NewComposeStackManager returns a docker-compose wrapper if corresponding binary present, otherwise nil
|
||||||
func NewComposeStackManager(binaryPath string, configPath string, proxyManager *proxy.Manager) (*ComposeStackManager, error) {
|
func NewComposeStackManager(binaryPath string, configPath string, proxyManager *proxy.Manager) (*ComposeStackManager, error) {
|
||||||
wrap, err := wrapper.NewComposeWrapper(binaryPath)
|
deployer, err := compose.NewComposeDeployer(binaryPath, configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ComposeStackManager{
|
return &ComposeStackManager{
|
||||||
wrapper: wrap,
|
deployer: deployer,
|
||||||
proxyManager: proxyManager,
|
proxyManager: proxyManager,
|
||||||
configPath: configPath,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ComposeSyntaxMaxVersion returns the maximum supported version of the docker compose syntax
|
// ComposeSyntaxMaxVersion returns the maximum supported version of the docker compose syntax
|
||||||
func (w *ComposeStackManager) ComposeSyntaxMaxVersion() string {
|
func (manager *ComposeStackManager) ComposeSyntaxMaxVersion() string {
|
||||||
return portainer.ComposeSyntaxMaxVersion
|
return portainer.ComposeSyntaxMaxVersion
|
||||||
}
|
}
|
||||||
|
|
||||||
// Up builds, (re)creates and starts containers in the background. Wraps `docker-compose up -d` command
|
// Up builds, (re)creates and starts containers in the background. Wraps `docker-compose up -d` command
|
||||||
func (w *ComposeStackManager) Up(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
func (manager *ComposeStackManager) Up(ctx context.Context, stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
||||||
url, proxy, err := w.fetchEndpointProxy(endpoint)
|
url, proxy, err := manager.fetchEndpointProxy(endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to fetch endpoint proxy")
|
return errors.Wrap(err, "failed to fetch endpoint proxy")
|
||||||
}
|
}
|
||||||
|
@ -57,13 +59,12 @@ func (w *ComposeStackManager) Up(stack *portainer.Stack, endpoint *portainer.End
|
||||||
}
|
}
|
||||||
|
|
||||||
filePaths := append([]string{stack.EntryPoint}, stack.AdditionalFiles...)
|
filePaths := append([]string{stack.EntryPoint}, stack.AdditionalFiles...)
|
||||||
_, err = w.wrapper.Up(filePaths, stack.ProjectPath, url, stack.Name, envFilePath, w.configPath)
|
return manager.deployer.Deploy(ctx, stack.ProjectPath, url, stack.Name, filePaths, envFilePath)
|
||||||
return errors.Wrap(err, "failed to deploy a stack")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Down stops and removes containers, networks, images, and volumes. Wraps `docker-compose down --remove-orphans` command
|
// Down stops and removes containers, networks, images, and volumes. Wraps `docker-compose down --remove-orphans` command
|
||||||
func (w *ComposeStackManager) Down(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
func (manager *ComposeStackManager) Down(ctx context.Context, stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
||||||
url, proxy, err := w.fetchEndpointProxy(endpoint)
|
url, proxy, err := manager.fetchEndpointProxy(endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -73,27 +74,26 @@ func (w *ComposeStackManager) Down(stack *portainer.Stack, endpoint *portainer.E
|
||||||
|
|
||||||
filePaths := append([]string{stack.EntryPoint}, stack.AdditionalFiles...)
|
filePaths := append([]string{stack.EntryPoint}, stack.AdditionalFiles...)
|
||||||
|
|
||||||
_, err = w.wrapper.Down(filePaths, stack.ProjectPath, url, stack.Name)
|
return manager.deployer.Remove(ctx, stack.ProjectPath, url, stack.Name, filePaths)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NormalizeStackName returns a new stack name with unsupported characters replaced
|
// NormalizeStackName returns a new stack name with unsupported characters replaced
|
||||||
func (w *ComposeStackManager) NormalizeStackName(name string) string {
|
func (manager *ComposeStackManager) NormalizeStackName(name string) string {
|
||||||
r := regexp.MustCompile("[^a-z0-9]+")
|
r := regexp.MustCompile("[^a-z0-9]+")
|
||||||
return r.ReplaceAllString(strings.ToLower(name), "")
|
return r.ReplaceAllString(strings.ToLower(name), "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (w *ComposeStackManager) fetchEndpointProxy(endpoint *portainer.Endpoint) (string, *factory.ProxyServer, error) {
|
func (manager *ComposeStackManager) fetchEndpointProxy(endpoint *portainer.Endpoint) (string, *factory.ProxyServer, error) {
|
||||||
if strings.HasPrefix(endpoint.URL, "unix://") || strings.HasPrefix(endpoint.URL, "npipe://") {
|
if strings.HasPrefix(endpoint.URL, "unix://") || strings.HasPrefix(endpoint.URL, "npipe://") {
|
||||||
return "", nil, nil
|
return "", nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
proxy, err := w.proxyManager.CreateAgentProxyServer(endpoint)
|
proxy, err := manager.proxyManager.CreateAgentProxyServer(endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return fmt.Sprintf("http://127.0.0.1:%d", proxy.Port), proxy, nil
|
return fmt.Sprintf("tcp://127.0.0.1:%d", proxy.Port), proxy, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createEnvFile(stack *portainer.Stack) (string, error) {
|
func createEnvFile(stack *portainer.Stack) (string, error) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package exec
|
package exec
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
|
@ -47,7 +48,9 @@ func Test_UpAndDown(t *testing.T) {
|
||||||
t.Fatalf("Failed creating manager: %s", err)
|
t.Fatalf("Failed creating manager: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = w.Up(stack, endpoint)
|
ctx := context.TODO()
|
||||||
|
|
||||||
|
err = w.Up(ctx, stack, endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error calling docker-compose up: %s", err)
|
t.Fatalf("Error calling docker-compose up: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -56,7 +59,7 @@ func Test_UpAndDown(t *testing.T) {
|
||||||
t.Fatal("container should exist")
|
t.Fatal("container should exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
err = w.Down(stack, endpoint)
|
err = w.Down(ctx, stack, endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Error calling docker-compose down: %s", err)
|
t.Fatalf("Error calling docker-compose down: %s", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,7 @@ import (
|
||||||
// SwarmStackManager represents a service for managing stacks.
|
// SwarmStackManager represents a service for managing stacks.
|
||||||
type SwarmStackManager struct {
|
type SwarmStackManager struct {
|
||||||
binaryPath string
|
binaryPath string
|
||||||
dataPath string
|
configPath string
|
||||||
signatureService portainer.DigitalSignatureService
|
signatureService portainer.DigitalSignatureService
|
||||||
fileService portainer.FileService
|
fileService portainer.FileService
|
||||||
reverseTunnelService portainer.ReverseTunnelService
|
reverseTunnelService portainer.ReverseTunnelService
|
||||||
|
@ -27,16 +27,16 @@ type SwarmStackManager struct {
|
||||||
|
|
||||||
// NewSwarmStackManager initializes a new SwarmStackManager service.
|
// NewSwarmStackManager initializes a new SwarmStackManager service.
|
||||||
// It also updates the configuration of the Docker CLI binary.
|
// It also updates the configuration of the Docker CLI binary.
|
||||||
func NewSwarmStackManager(binaryPath, dataPath string, signatureService portainer.DigitalSignatureService, fileService portainer.FileService, reverseTunnelService portainer.ReverseTunnelService) (*SwarmStackManager, error) {
|
func NewSwarmStackManager(binaryPath, configPath string, signatureService portainer.DigitalSignatureService, fileService portainer.FileService, reverseTunnelService portainer.ReverseTunnelService) (*SwarmStackManager, error) {
|
||||||
manager := &SwarmStackManager{
|
manager := &SwarmStackManager{
|
||||||
binaryPath: binaryPath,
|
binaryPath: binaryPath,
|
||||||
dataPath: dataPath,
|
configPath: configPath,
|
||||||
signatureService: signatureService,
|
signatureService: signatureService,
|
||||||
fileService: fileService,
|
fileService: fileService,
|
||||||
reverseTunnelService: reverseTunnelService,
|
reverseTunnelService: reverseTunnelService,
|
||||||
}
|
}
|
||||||
|
|
||||||
err := manager.updateDockerCLIConfiguration(dataPath)
|
err := manager.updateDockerCLIConfiguration(manager.configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ func NewSwarmStackManager(binaryPath, dataPath string, signatureService portaine
|
||||||
|
|
||||||
// Login executes the docker login command against a list of registries (including DockerHub).
|
// Login executes the docker login command against a list of registries (including DockerHub).
|
||||||
func (manager *SwarmStackManager) Login(registries []portainer.Registry, endpoint *portainer.Endpoint) {
|
func (manager *SwarmStackManager) Login(registries []portainer.Registry, endpoint *portainer.Endpoint) {
|
||||||
command, args := manager.prepareDockerCommandAndArgs(manager.binaryPath, manager.dataPath, endpoint)
|
command, args := manager.prepareDockerCommandAndArgs(manager.binaryPath, manager.configPath, endpoint)
|
||||||
for _, registry := range registries {
|
for _, registry := range registries {
|
||||||
if registry.Authentication {
|
if registry.Authentication {
|
||||||
registryArgs := append(args, "login", "--username", registry.Username, "--password", registry.Password, registry.URL)
|
registryArgs := append(args, "login", "--username", registry.Username, "--password", registry.Password, registry.URL)
|
||||||
|
@ -57,7 +57,7 @@ func (manager *SwarmStackManager) Login(registries []portainer.Registry, endpoin
|
||||||
|
|
||||||
// Logout executes the docker logout command.
|
// Logout executes the docker logout command.
|
||||||
func (manager *SwarmStackManager) Logout(endpoint *portainer.Endpoint) error {
|
func (manager *SwarmStackManager) Logout(endpoint *portainer.Endpoint) error {
|
||||||
command, args := manager.prepareDockerCommandAndArgs(manager.binaryPath, manager.dataPath, endpoint)
|
command, args := manager.prepareDockerCommandAndArgs(manager.binaryPath, manager.configPath, endpoint)
|
||||||
args = append(args, "logout")
|
args = append(args, "logout")
|
||||||
return runCommandAndCaptureStdErr(command, args, nil, "")
|
return runCommandAndCaptureStdErr(command, args, nil, "")
|
||||||
}
|
}
|
||||||
|
@ -65,7 +65,7 @@ func (manager *SwarmStackManager) Logout(endpoint *portainer.Endpoint) error {
|
||||||
// Deploy executes the docker stack deploy command.
|
// Deploy executes the docker stack deploy command.
|
||||||
func (manager *SwarmStackManager) Deploy(stack *portainer.Stack, prune bool, endpoint *portainer.Endpoint) error {
|
func (manager *SwarmStackManager) Deploy(stack *portainer.Stack, prune bool, endpoint *portainer.Endpoint) error {
|
||||||
filePaths := stackutils.GetStackFilePaths(stack)
|
filePaths := stackutils.GetStackFilePaths(stack)
|
||||||
command, args := manager.prepareDockerCommandAndArgs(manager.binaryPath, manager.dataPath, endpoint)
|
command, args := manager.prepareDockerCommandAndArgs(manager.binaryPath, manager.configPath, endpoint)
|
||||||
|
|
||||||
if prune {
|
if prune {
|
||||||
args = append(args, "stack", "deploy", "--prune", "--with-registry-auth")
|
args = append(args, "stack", "deploy", "--prune", "--with-registry-auth")
|
||||||
|
@ -85,7 +85,7 @@ func (manager *SwarmStackManager) Deploy(stack *portainer.Stack, prune bool, end
|
||||||
|
|
||||||
// Remove executes the docker stack rm command.
|
// Remove executes the docker stack rm command.
|
||||||
func (manager *SwarmStackManager) Remove(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
func (manager *SwarmStackManager) Remove(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
||||||
command, args := manager.prepareDockerCommandAndArgs(manager.binaryPath, manager.dataPath, endpoint)
|
command, args := manager.prepareDockerCommandAndArgs(manager.binaryPath, manager.configPath, endpoint)
|
||||||
args = append(args, "stack", "rm", stack.Name)
|
args = append(args, "stack", "rm", stack.Name)
|
||||||
return runCommandAndCaptureStdErr(command, args, nil, "")
|
return runCommandAndCaptureStdErr(command, args, nil, "")
|
||||||
}
|
}
|
||||||
|
@ -109,7 +109,7 @@ func runCommandAndCaptureStdErr(command string, args []string, env []string, wor
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *SwarmStackManager) prepareDockerCommandAndArgs(binaryPath, dataPath string, endpoint *portainer.Endpoint) (string, []string) {
|
func (manager *SwarmStackManager) prepareDockerCommandAndArgs(binaryPath, configPath string, endpoint *portainer.Endpoint) (string, []string) {
|
||||||
// Assume Linux as a default
|
// Assume Linux as a default
|
||||||
command := path.Join(binaryPath, "docker")
|
command := path.Join(binaryPath, "docker")
|
||||||
|
|
||||||
|
@ -118,7 +118,7 @@ func (manager *SwarmStackManager) prepareDockerCommandAndArgs(binaryPath, dataPa
|
||||||
}
|
}
|
||||||
|
|
||||||
args := make([]string, 0)
|
args := make([]string, 0)
|
||||||
args = append(args, "--config", dataPath)
|
args = append(args, "--config", configPath)
|
||||||
|
|
||||||
endpointURL := endpoint.URL
|
endpointURL := endpoint.URL
|
||||||
if endpoint.Type == portainer.EdgeAgentOnDockerEnvironment {
|
if endpoint.Type == portainer.EdgeAgentOnDockerEnvironment {
|
||||||
|
@ -145,8 +145,8 @@ func (manager *SwarmStackManager) prepareDockerCommandAndArgs(binaryPath, dataPa
|
||||||
return command, args
|
return command, args
|
||||||
}
|
}
|
||||||
|
|
||||||
func (manager *SwarmStackManager) updateDockerCLIConfiguration(dataPath string) error {
|
func (manager *SwarmStackManager) updateDockerCLIConfiguration(configPath string) error {
|
||||||
configFilePath := path.Join(dataPath, "config.json")
|
configFilePath := path.Join(configPath, "config.json")
|
||||||
config, err := manager.retrieveConfigurationFromDisk(configFilePath)
|
config, err := manager.retrieveConfigurationFromDisk(configFilePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -43,6 +43,8 @@ const (
|
||||||
BinaryStorePath = "bin"
|
BinaryStorePath = "bin"
|
||||||
// EdgeJobStorePath represents the subfolder where schedule files are stored.
|
// EdgeJobStorePath represents the subfolder where schedule files are stored.
|
||||||
EdgeJobStorePath = "edge_jobs"
|
EdgeJobStorePath = "edge_jobs"
|
||||||
|
// DockerConfigPath represents the subfolder where docker configuration is stored.
|
||||||
|
DockerConfigPath = "docker_config"
|
||||||
// ExtensionRegistryManagementStorePath represents the subfolder where files related to the
|
// ExtensionRegistryManagementStorePath represents the subfolder where files related to the
|
||||||
// registry management extension are stored.
|
// registry management extension are stored.
|
||||||
ExtensionRegistryManagementStorePath = "extensions"
|
ExtensionRegistryManagementStorePath = "extensions"
|
||||||
|
@ -100,6 +102,11 @@ func NewService(dataStorePath, fileStorePath string) (*Service, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
err = service.createDirectoryInStore(DockerConfigPath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return service, nil
|
return service, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +115,11 @@ func (service *Service) GetBinaryFolder() string {
|
||||||
return path.Join(service.fileStorePath, BinaryStorePath)
|
return path.Join(service.fileStorePath, BinaryStorePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetDockerConfigPath returns the full path to the docker config store on the filesystem
|
||||||
|
func (service *Service) GetDockerConfigPath() string {
|
||||||
|
return path.Join(service.fileStorePath, DockerConfigPath)
|
||||||
|
}
|
||||||
|
|
||||||
// RemoveDirectory removes a directory on the filesystem.
|
// RemoveDirectory removes a directory on the filesystem.
|
||||||
func (service *Service) RemoveDirectory(directoryPath string) error {
|
func (service *Service) RemoveDirectory(directoryPath string) error {
|
||||||
return os.RemoveAll(directoryPath)
|
return os.RemoveAll(directoryPath)
|
||||||
|
|
20
api/go.mod
20
api/go.mod
|
@ -3,15 +3,21 @@ module github.com/portainer/portainer/api
|
||||||
go 1.16
|
go 1.16
|
||||||
|
|
||||||
require (
|
require (
|
||||||
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect
|
||||||
github.com/Microsoft/go-winio v0.4.16
|
github.com/Microsoft/go-winio v0.4.16
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
||||||
|
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 // indirect
|
||||||
|
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535
|
||||||
github.com/boltdb/bolt v1.3.1
|
github.com/boltdb/bolt v1.3.1
|
||||||
github.com/containerd/containerd v1.3.1 // indirect
|
github.com/containerd/containerd v1.3.1 // indirect
|
||||||
github.com/coreos/go-semver v0.3.0
|
github.com/coreos/go-semver v0.3.0
|
||||||
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9
|
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||||
github.com/docker/cli v0.0.0-20191126203649-54d085b857e9
|
github.com/docker/cli v0.0.0-20191126203649-54d085b857e9
|
||||||
github.com/docker/docker v0.0.0-00010101000000-000000000000
|
github.com/docker/distribution v2.7.1+incompatible // indirect
|
||||||
|
github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0
|
||||||
|
github.com/docker/go-connections v0.4.0 // indirect
|
||||||
|
github.com/docker/go-units v0.4.0 // indirect
|
||||||
github.com/g07cha/defender v0.0.0-20180505193036-5665c627c814
|
github.com/g07cha/defender v0.0.0-20180505193036-5665c627c814
|
||||||
github.com/go-git/go-git/v5 v5.3.0
|
github.com/go-git/go-git/v5 v5.3.0
|
||||||
github.com/go-ldap/ldap/v3 v3.1.8
|
github.com/go-ldap/ldap/v3 v3.1.8
|
||||||
|
@ -21,23 +27,27 @@ require (
|
||||||
github.com/gorilla/websocket v1.4.1
|
github.com/gorilla/websocket v1.4.1
|
||||||
github.com/joho/godotenv v1.3.0
|
github.com/joho/godotenv v1.3.0
|
||||||
github.com/jpillora/chisel v0.0.0-20190724232113-f3a8df20e389
|
github.com/jpillora/chisel v0.0.0-20190724232113-f3a8df20e389
|
||||||
github.com/json-iterator/go v1.1.8
|
github.com/json-iterator/go v1.1.10
|
||||||
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
|
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c
|
||||||
github.com/mattn/go-shellwords v1.0.6 // indirect
|
github.com/mattn/go-shellwords v1.0.6 // indirect
|
||||||
github.com/mitchellh/mapstructure v1.1.2 // indirect
|
github.com/mitchellh/mapstructure v1.1.2 // indirect
|
||||||
|
github.com/morikuni/aec v1.0.0 // indirect
|
||||||
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
|
github.com/opencontainers/image-spec v1.0.1 // indirect
|
||||||
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6
|
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/portainer/docker-compose-wrapper v0.0.0-20210810234209-d01bc85eb481
|
github.com/portainer/docker-compose-wrapper v0.0.0-20210906052132-ef24824f7548
|
||||||
github.com/portainer/libcompose v0.5.3
|
|
||||||
github.com/portainer/libcrypto v0.0.0-20210422035235-c652195c5c3a
|
github.com/portainer/libcrypto v0.0.0-20210422035235-c652195c5c3a
|
||||||
github.com/portainer/libhttp v0.0.0-20190806161843-ba068f58be33
|
github.com/portainer/libhttp v0.0.0-20190806161843-ba068f58be33
|
||||||
github.com/robfig/cron/v3 v3.0.1
|
github.com/robfig/cron/v3 v3.0.1
|
||||||
github.com/sirupsen/logrus v1.8.1
|
github.com/sirupsen/logrus v1.8.1
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
|
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
|
||||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
|
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2
|
||||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
|
||||||
|
gotest.tools v2.2.0+incompatible // indirect
|
||||||
k8s.io/api v0.17.2
|
k8s.io/api v0.17.2
|
||||||
k8s.io/apimachinery v0.17.2
|
k8s.io/apimachinery v0.17.2
|
||||||
k8s.io/client-go v0.17.2
|
k8s.io/client-go v0.17.2
|
||||||
|
|
109
api/go.sum
109
api/go.sum
|
@ -1,8 +1,8 @@
|
||||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||||
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8=
|
||||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||||
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
github.com/Azure/go-autorest/autorest v0.9.0/go.mod h1:xyHB1BMZT0cuDHU7I0+g046+BFDTQ8rEZB0s4Yfa6bI=
|
||||||
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
github.com/Azure/go-autorest/autorest/adal v0.5.0/go.mod h1:8Z9fGy2MpX0PvDjB1pEgQTmVqjGhiHBW7RJJEciWzS0=
|
||||||
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
github.com/Azure/go-autorest/autorest/date v0.1.0/go.mod h1:plvfp3oPSKwf2DNjlBjWF/7vwR+cUD/ELuzDCXwHUVA=
|
||||||
|
@ -11,40 +11,31 @@ github.com/Azure/go-autorest/autorest/mocks v0.2.0/go.mod h1:OTyCOPRA2IgIlWxVYxB
|
||||||
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
github.com/Azure/go-autorest/logger v0.1.0/go.mod h1:oExouG+K6PryycPJfVSxi/koC6LSNgds39diKLz7Vrc=
|
||||||
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
|
||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||||
github.com/Microsoft/go-winio v0.3.8/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
|
||||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||||
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
||||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||||
github.com/Microsoft/hcsshim v0.8.6 h1:ZfF0+zZeYdzMIVMZHKtDKJvLHj76XCuVae/jNkjj0IA=
|
|
||||||
github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg=
|
|
||||||
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
|
||||||
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||||
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7 h1:uSoVVbwJiQipAclBbw+8quDsfcvFjOpI5iCf4p/cqCs=
|
||||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc h1:cAKDfWh5VpdgMhJosfJnn5/FoN2SRZ4p7fJNX58YPaU=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf h1:qet1QNfXsQxTZqLG4oE62mJzwPIB8+Tee4RNCL9ulrY=
|
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15 h1:AUNCr9CiJuwrRYS3XieqF+Z9B9gNxo/eANAJCF2eiN4=
|
||||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
github.com/alecthomas/units v0.0.0-20210208195552-ff826a37aa15/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
|
||||||
github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2 h1:axBiC50cNZOs7ygH5BgQp4N+aYrZ2DNpWZ1KG3VOSOM=
|
github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2 h1:axBiC50cNZOs7ygH5BgQp4N+aYrZ2DNpWZ1KG3VOSOM=
|
||||||
github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2/go.mod h1:jnzFpU88PccN/tPPhCpnNU8mZphvKxYM9lLNkd8e+os=
|
github.com/andrew-d/go-termutil v0.0.0-20150726205930-009166a695a2/go.mod h1:jnzFpU88PccN/tPPhCpnNU8mZphvKxYM9lLNkd8e+os=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a h1:idn718Q4B6AGu/h5Sxe66HYVdqdGu2l9Iebqhi/AEoA=
|
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0S6Vi7/lbWECcX0j45yZReDZ56BQsrVBOEEY=
|
||||||
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY=
|
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
|
||||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
|
||||||
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
|
|
||||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
|
||||||
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4=
|
||||||
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps=
|
||||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||||
github.com/containerd/containerd v1.3.1 h1:LdbWxLhkAIxGO7h3mATHkyav06WuDs/yTWxIljJOTks=
|
github.com/containerd/containerd v1.3.1 h1:LdbWxLhkAIxGO7h3mATHkyav06WuDs/yTWxIljJOTks=
|
||||||
github.com/containerd/containerd v1.3.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
github.com/containerd/containerd v1.3.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA=
|
||||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc h1:TP+534wVlf61smEIq1nwLLAjQVEK2EADoW3CX9AuT+8=
|
|
||||||
github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y=
|
|
||||||
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
|
||||||
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
|
||||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||||
|
@ -56,23 +47,16 @@ github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9 h1:74lLNRzvsdIlkTgfD
|
||||||
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4=
|
github.com/dchest/uniuri v0.0.0-20160212164326-8902c56451e9/go.mod h1:GgB8SF9nRG+GqaDtLcwJZsQFhcogVCJ79j4EdT0c2V4=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||||
github.com/docker/cli v0.0.0-20190711175710-5b38d82aa076/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
|
||||||
github.com/docker/cli v0.0.0-20191126203649-54d085b857e9 h1:Q6D6b2iRKhvtL3Wj9p0SyPOvUDJ1ht62mbiBoNJ3Aus=
|
github.com/docker/cli v0.0.0-20191126203649-54d085b857e9 h1:Q6D6b2iRKhvtL3Wj9p0SyPOvUDJ1ht62mbiBoNJ3Aus=
|
||||||
github.com/docker/cli v0.0.0-20191126203649-54d085b857e9/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
github.com/docker/cli v0.0.0-20191126203649-54d085b857e9/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||||
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
|
||||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||||
github.com/docker/docker-credential-helpers v0.6.3 h1:zI2p9+1NQYdnG6sMU26EX4aVGlqbInSQxQXLvzJ4RPQ=
|
|
||||||
github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
|
|
||||||
github.com/docker/engine v1.4.2-0.20200204220554-5f6d6f3f2203 h1:QeBh8wW8pIZKlXxlMOQ8hSCMdJA+2Z/bD/iDyCAS8XU=
|
github.com/docker/engine v1.4.2-0.20200204220554-5f6d6f3f2203 h1:QeBh8wW8pIZKlXxlMOQ8hSCMdJA+2Z/bD/iDyCAS8XU=
|
||||||
github.com/docker/engine v1.4.2-0.20200204220554-5f6d6f3f2203/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY=
|
github.com/docker/engine v1.4.2-0.20200204220554-5f6d6f3f2203/go.mod h1:3CPr2caMgTHxxIAZgEMd3uLYPDlRvPqCpyeRf6ncPcY=
|
||||||
github.com/docker/go-connections v0.3.0 h1:3lOnM9cSzgGwx8VfK/NGOW5fLQ0GjIlCkaktF+n1M6o=
|
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
|
||||||
github.com/docker/go-connections v0.3.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
|
||||||
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82 h1:X0fj836zx99zFu83v/M79DuBn84IL/Syx1SY6Y5ZEMA=
|
|
||||||
github.com/docker/go-metrics v0.0.0-20181218153428-b84716841b82/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
|
|
||||||
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
|
||||||
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
|
||||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7 h1:UhxFibDNY/bfvqU5CAUmr9zpesgbU6SWc8/B4mflAE4=
|
|
||||||
github.com/docker/libtrust v0.0.0-20160708172513-aabc10ec26b7/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
|
|
||||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
|
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg=
|
||||||
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
|
||||||
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M=
|
github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e h1:p1yVGRW3nmb85p1Sh1ZJSDm4A4iKLS5QNbvUHMgGu/M=
|
||||||
|
@ -82,7 +66,6 @@ github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg
|
||||||
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||||
github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I=
|
github.com/evanphx/json-patch v4.2.0+incompatible h1:fUDGZCv/7iAN7u0puUVhvKCcsR6vRfwrJatElLBEf0I=
|
||||||
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
|
||||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||||
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
github.com/fsnotify/fsnotify v1.4.7 h1:IXs+QLmnXW2CcXuY+8Mzv/fWEsPGWxqefPtCP5CnV9I=
|
||||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||||
|
@ -102,20 +85,15 @@ github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12 h1:PbK
|
||||||
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
github.com/go-git/go-git-fixtures/v4 v4.0.2-0.20200613231340-f56387b50c12/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
||||||
github.com/go-git/go-git/v5 v5.3.0 h1:8WKMtJR2j8RntEXR/uvTKagfEt4GYlwQ7mntE4+0GWc=
|
github.com/go-git/go-git/v5 v5.3.0 h1:8WKMtJR2j8RntEXR/uvTKagfEt4GYlwQ7mntE4+0GWc=
|
||||||
github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw=
|
github.com/go-git/go-git/v5 v5.3.0/go.mod h1:xdX4bWJ48aOrdhnl2XqHYstHbbp6+LFS4r4X+lNVprw=
|
||||||
github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as=
|
|
||||||
github.com/go-ldap/ldap/v3 v3.1.8 h1:5vU/2jOh9HqprwXp8aF915s9p6Z8wmbSEVF7/gdTFhM=
|
github.com/go-ldap/ldap/v3 v3.1.8 h1:5vU/2jOh9HqprwXp8aF915s9p6Z8wmbSEVF7/gdTFhM=
|
||||||
github.com/go-ldap/ldap/v3 v3.1.8/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q=
|
github.com/go-ldap/ldap/v3 v3.1.8/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q=
|
||||||
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
|
|
||||||
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
|
|
||||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||||
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0=
|
||||||
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg=
|
||||||
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc=
|
||||||
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I=
|
||||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
|
||||||
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
|
github.com/gofrs/uuid v3.2.0+incompatible h1:y12jRkkFxsd7GpqdSZ+/KCs/fJbqpEXSGd4+jfEaewE=
|
||||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||||
github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
|
|
||||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
|
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d h1:3PaI8p3seN09VjbTYC/QWlUZdZ1qS1zGjy7LH2Wt07I=
|
||||||
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o=
|
||||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||||
|
@ -124,7 +102,6 @@ github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfb
|
||||||
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||||
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
|
||||||
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
|
||||||
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||||
|
@ -142,8 +119,6 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
|
||||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
|
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d h1:7XGaL1e6bYS1yIonGp9761ExpPPV1ui0SAC59Yube9k=
|
||||||
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
github.com/googleapis/gnostic v0.0.0-20170729233727-0c5108395e2d/go.mod h1:sJBsCZ4ayReDTBIg8b9dl28c5xFWyhBTVRp3pOg5EKY=
|
||||||
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8=
|
||||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
|
||||||
github.com/gorilla/mux v0.0.0-20160317213430-0eeaf8392f5b/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
|
||||||
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw=
|
||||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||||
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
github.com/gorilla/securecookie v1.1.1 h1:miw7JPhV+b/lAHSXz4qd/nN9jRiAFV5FwjeKyCS8BvQ=
|
||||||
|
@ -174,12 +149,10 @@ github.com/jpillora/requestlog v0.0.0-20181015073026-df8817be5f82/go.mod h1:w8bu
|
||||||
github.com/jpillora/sizestr v0.0.0-20160130011556-e2ea2fa42fb9 h1:0c9jcgBtHRtDU//jTrcCgWG6UHjMZytiq/3WhraNgUM=
|
github.com/jpillora/sizestr v0.0.0-20160130011556-e2ea2fa42fb9 h1:0c9jcgBtHRtDU//jTrcCgWG6UHjMZytiq/3WhraNgUM=
|
||||||
github.com/jpillora/sizestr v0.0.0-20160130011556-e2ea2fa42fb9/go.mod h1:1ffp+CRe0eAwwRb0/BownUAjMBsmTLwgAvRbfj9dRwE=
|
github.com/jpillora/sizestr v0.0.0-20160130011556-e2ea2fa42fb9/go.mod h1:1ffp+CRe0eAwwRb0/BownUAjMBsmTLwgAvRbfj9dRwE=
|
||||||
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
|
||||||
github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
|
||||||
github.com/json-iterator/go v1.1.8 h1:QiWkFLKq0T7mpzwOTu6BzNDbfTE8OLrYhVKYMLF46Ok=
|
|
||||||
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
|
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||||
|
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||||
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
|
||||||
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
|
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
||||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||||
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00=
|
||||||
|
@ -187,11 +160,9 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
|
||||||
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c h1:N7A4JCA2G+j5fuFxCsJqjFU/sZe0mj8H0sSoSwbaikw=
|
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c h1:N7A4JCA2G+j5fuFxCsJqjFU/sZe0mj8H0sSoSwbaikw=
|
||||||
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c/go.mod h1:Nn5wlyECw3iJrzi0AhIWg+AJUb4PlRQVW4/3XHH1LZA=
|
github.com/koding/websocketproxy v0.0.0-20181220232114-7ed82d81a28c/go.mod h1:Nn5wlyECw3iJrzi0AhIWg+AJUb4PlRQVW4/3XHH1LZA=
|
||||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||||
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
|
|
||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||||
github.com/kr/pty v0.0.0-20150511174710-5cf931ef8f76/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
|
||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||||
|
@ -199,8 +170,6 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||||
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||||
github.com/mattn/go-shellwords v1.0.6 h1:9Jok5pILi5S1MnDirGVTufYGtksUs/V2BWUP3ZkeUUI=
|
github.com/mattn/go-shellwords v1.0.6 h1:9Jok5pILi5S1MnDirGVTufYGtksUs/V2BWUP3ZkeUUI=
|
||||||
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o=
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
|
|
||||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
|
||||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||||
|
@ -212,10 +181,9 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN
|
||||||
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
|
||||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c h1:nXxl5PrvVm2L/wCy8dQu6DMTwH4oIuGN8GJDAlqDdVE=
|
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
|
||||||
github.com/morikuni/aec v0.0.0-20170113033406-39771216ff4c/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
|
||||||
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
|
||||||
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
|
|
||||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||||
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||||
|
@ -225,49 +193,29 @@ github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+
|
||||||
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
|
||||||
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
github.com/onsi/gomega v1.7.0 h1:XPnZz8VVBHjVsy1vzJmRwIcSwiUO+JFfrv/xGiigmME=
|
||||||
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420 h1:Yu3681ykYHDfLoI6XVjL4JWmkE+3TX9yfIWwRCh1kFM=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/image-spec v0.0.0-20170515205857-f03dbe35d449 h1:Aq8iG72akPb/kszE7ksZ5ldV+JYPYii/KZOxlpJF07s=
|
github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
|
||||||
github.com/opencontainers/image-spec v0.0.0-20170515205857-f03dbe35d449/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
|
||||||
github.com/opencontainers/runc v0.0.0-20161109192122-51371867a01c h1:iOMba/KmaXgSX5PFKu1u6s+DZXiq+EzPayawa76w6aA=
|
|
||||||
github.com/opencontainers/runc v0.0.0-20161109192122-51371867a01c/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
|
|
||||||
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6 h1:lNCW6THrCKBiJBpz8kbVGjC7MgdCGKwuvBgc7LoD6sw=
|
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6 h1:lNCW6THrCKBiJBpz8kbVGjC7MgdCGKwuvBgc7LoD6sw=
|
||||||
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
|
github.com/orcaman/concurrent-map v0.0.0-20190826125027-8c72a8bb44f6/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
|
||||||
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
|
||||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
github.com/portainer/docker-compose-wrapper v0.0.0-20210810234209-d01bc85eb481 h1:5c8N9Gh21Ja/9EIpfyHFmQvTCKgOjnRhosmo0ZshkFk=
|
github.com/portainer/docker-compose-wrapper v0.0.0-20210906052132-ef24824f7548 h1:5I9j0e6f9KG/RV6YBKWyks8LSHheE+ltJgpMyyWYUoo=
|
||||||
github.com/portainer/docker-compose-wrapper v0.0.0-20210810234209-d01bc85eb481/go.mod h1:WxDlJWZxCnicdLCPnLNEv7/gRhjeIVuCGmsv+iOPH3c=
|
github.com/portainer/docker-compose-wrapper v0.0.0-20210906052132-ef24824f7548/go.mod h1:WxDlJWZxCnicdLCPnLNEv7/gRhjeIVuCGmsv+iOPH3c=
|
||||||
github.com/portainer/libcompose v0.5.3 h1:tE4WcPuGvo+NKeDkDWpwNavNLZ5GHIJ4RvuZXsI9uI8=
|
|
||||||
github.com/portainer/libcompose v0.5.3/go.mod h1:7SKd/ho69rRKHDFSDUwkbMcol2TMKU5OslDsajr8Ro8=
|
|
||||||
github.com/portainer/libcrypto v0.0.0-20210422035235-c652195c5c3a h1:qY8TbocN75n5PDl16o0uVr5MevtM5IhdwSelXEd4nFM=
|
github.com/portainer/libcrypto v0.0.0-20210422035235-c652195c5c3a h1:qY8TbocN75n5PDl16o0uVr5MevtM5IhdwSelXEd4nFM=
|
||||||
github.com/portainer/libcrypto v0.0.0-20210422035235-c652195c5c3a/go.mod h1:n54EEIq+MM0NNtqLeCby8ljL+l275VpolXO0ibHegLE=
|
github.com/portainer/libcrypto v0.0.0-20210422035235-c652195c5c3a/go.mod h1:n54EEIq+MM0NNtqLeCby8ljL+l275VpolXO0ibHegLE=
|
||||||
github.com/portainer/libhttp v0.0.0-20190806161843-ba068f58be33 h1:H8HR2dHdBf8HANSkUyVw4o8+4tegGcd+zyKZ3e599II=
|
github.com/portainer/libhttp v0.0.0-20190806161843-ba068f58be33 h1:H8HR2dHdBf8HANSkUyVw4o8+4tegGcd+zyKZ3e599II=
|
||||||
github.com/portainer/libhttp v0.0.0-20190806161843-ba068f58be33/go.mod h1:Y2TfgviWI4rT2qaOTHr+hq6MdKIE5YjgQAu7qwptTV0=
|
github.com/portainer/libhttp v0.0.0-20190806161843-ba068f58be33/go.mod h1:Y2TfgviWI4rT2qaOTHr+hq6MdKIE5YjgQAu7qwptTV0=
|
||||||
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
|
|
||||||
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
|
|
||||||
github.com/prometheus/client_golang v1.1.0 h1:BQ53HtBmfOitExawJ6LokA4x8ov/z0SYYb0+HxJfRI8=
|
|
||||||
github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90 h1:S/YWwWx/RA8rT8tKFRuGUZhuA90OyIBpPCXkcbwU8DE=
|
|
||||||
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
|
||||||
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
|
|
||||||
github.com/prometheus/common v0.6.0 h1:kRhiuYSXR3+uv2IbVbZhUxK5zVD/2pp3Gd2PpvPkpEo=
|
|
||||||
github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc=
|
|
||||||
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
|
|
||||||
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
|
|
||||||
github.com/prometheus/procfs v0.0.3 h1:CTwfnzjQ+8dS6MhHHu4YswVAD99sL2wjPqP+VkURmKE=
|
|
||||||
github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ=
|
|
||||||
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
|
||||||
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
|
||||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||||
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
|
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE=
|
||||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||||
|
@ -285,17 +233,15 @@ github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5Cc
|
||||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc=
|
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce h1:fb190+cK2Xz/dvi9Hv8eCYJYvIGUTN2/KLq1pT6CjEc=
|
||||||
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
|
github.com/tomasen/realip v0.0.0-20180522021738-f0c99a92ddce/go.mod h1:o8v6yHRoik09Xen7gje4m9ERNah1d1PPsVq1VEx9vE4=
|
||||||
github.com/urfave/cli v1.21.0/go.mod h1:lxDj6qX9Q6lWQxIrbrT0nwecwUtRnhVZAJjJZrVUZZQ=
|
|
||||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
|
||||||
github.com/xeipuuv/gojsonschema v1.1.0 h1:ngVtJC9TY/lg0AA/1k48FYhBrhRoFlEmWzsehpNAaZg=
|
github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74=
|
||||||
github.com/xeipuuv/gojsonschema v1.1.0/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs=
|
github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
|
||||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||||
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
|
||||||
golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20181015023909-0c41d7ab0a0e/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||||
|
@ -307,18 +253,15 @@ golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL
|
||||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||||
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
|
||||||
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181017193950-04a2e542c03f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20181017193950-04a2e542c03f/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
|
||||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
|
||||||
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs=
|
golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs=
|
||||||
|
@ -331,8 +274,6 @@ golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJ
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58 h1:8gQV6CLnAEikrhgkHFbMAEhagSSnXWGV915qUMm9mrU=
|
|
||||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
|
||||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456 h1:ng0gs1AKnRRuEMZoTLLlbOd+C17zUDepwGQBb/n+JVg=
|
||||||
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||||
|
@ -351,9 +292,7 @@ golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGm
|
||||||
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
|
||||||
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
|
||||||
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
|
||||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
@ -363,9 +302,8 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
|
||||||
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7 h1:ZUjXAXmrAyrmmCPHgCA/vChHcpsX27MZ3yBonD/z1KE=
|
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7 h1:ZUjXAXmrAyrmmCPHgCA/vChHcpsX27MZ3yBonD/z1KE=
|
||||||
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
|
||||||
|
google.golang.org/grpc v1.19.0 h1:cfg4PD8YEdSFnm7qLV4++93WcmhH2nIUhMjhdCvl3j8=
|
||||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||||
google.golang.org/grpc v1.22.1 h1:/7cs52RnTJmD43s3uxzlq2U7nqVTd/37viQwMrMNlOM=
|
|
||||||
google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc=
|
||||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
@ -394,7 +332,6 @@ gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
|
||||||
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
|
||||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
|
||||||
k8s.io/api v0.17.2 h1:NF1UFXcKN7/OOv1uxdRz3qfra8AHsPav5M93hlV9+Dc=
|
k8s.io/api v0.17.2 h1:NF1UFXcKN7/OOv1uxdRz3qfra8AHsPav5M93hlV9+Dc=
|
||||||
k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4=
|
k8s.io/api v0.17.2/go.mod h1:BS9fjjLc4CMuqfSO8vgbHPKMt5+SF0ET6u/RVDihTo4=
|
||||||
k8s.io/apimachinery v0.17.2 h1:hwDQQFbdRlpnnsR64Asdi55GyCaIP/3WQpMmbNBeWr4=
|
k8s.io/apimachinery v0.17.2 h1:hwDQQFbdRlpnnsR64Asdi55GyCaIP/3WQpMmbNBeWr4=
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package stacks
|
package stacks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -177,7 +178,7 @@ func (handler *Handler) deleteStack(stack *portainer.Stack, endpoint *portainer.
|
||||||
return handler.SwarmStackManager.Remove(stack, endpoint)
|
return handler.SwarmStackManager.Remove(stack, endpoint)
|
||||||
}
|
}
|
||||||
if stack.Type == portainer.DockerComposeStack {
|
if stack.Type == portainer.DockerComposeStack {
|
||||||
return handler.ComposeStackManager.Down(stack, endpoint)
|
return handler.ComposeStackManager.Down(context.TODO(), stack, endpoint)
|
||||||
}
|
}
|
||||||
if stack.Type == portainer.KubernetesStack {
|
if stack.Type == portainer.KubernetesStack {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package stacks
|
package stacks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -120,7 +121,7 @@ func (handler *Handler) stackStart(w http.ResponseWriter, r *http.Request) *http
|
||||||
func (handler *Handler) startStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
func (handler *Handler) startStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
||||||
switch stack.Type {
|
switch stack.Type {
|
||||||
case portainer.DockerComposeStack:
|
case portainer.DockerComposeStack:
|
||||||
return handler.ComposeStackManager.Up(stack, endpoint)
|
return handler.ComposeStackManager.Up(context.TODO(), stack, endpoint)
|
||||||
case portainer.DockerSwarmStack:
|
case portainer.DockerSwarmStack:
|
||||||
return handler.SwarmStackManager.Deploy(stack, true, endpoint)
|
return handler.SwarmStackManager.Deploy(stack, true, endpoint)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package stacks
|
package stacks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
@ -104,7 +105,7 @@ func (handler *Handler) stackStop(w http.ResponseWriter, r *http.Request) *httpe
|
||||||
func (handler *Handler) stopStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
func (handler *Handler) stopStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
||||||
switch stack.Type {
|
switch stack.Type {
|
||||||
case portainer.DockerComposeStack:
|
case portainer.DockerComposeStack:
|
||||||
return handler.ComposeStackManager.Down(stack, endpoint)
|
return handler.ComposeStackManager.Down(context.TODO(), stack, endpoint)
|
||||||
case portainer.DockerSwarmStack:
|
case portainer.DockerSwarmStack:
|
||||||
return handler.SwarmStackManager.Remove(stack, endpoint)
|
return handler.SwarmStackManager.Remove(stack, endpoint)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
type userUpdatePayload struct {
|
type userUpdatePayload struct {
|
||||||
Username string `validate:"required" example:"bob"`
|
Username string `validate:"required" example:"bob"`
|
||||||
Password string `validate:"required" example:"cg9Wgky3"`
|
Password string `validate:"required" example:"cg9Wgky3"`
|
||||||
|
UserTheme string `example:"dark"`
|
||||||
// User role (1 for administrator account and 2 for regular account)
|
// User role (1 for administrator account and 2 for regular account)
|
||||||
Role int `validate:"required" enums:"1,2" example:"2"`
|
Role int `validate:"required" enums:"1,2" example:"2"`
|
||||||
}
|
}
|
||||||
|
@ -104,6 +105,10 @@ func (handler *Handler) userUpdate(w http.ResponseWriter, r *http.Request) *http
|
||||||
user.Role = portainer.UserRole(payload.Role)
|
user.Role = portainer.UserRole(payload.Role)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if payload.UserTheme != "" {
|
||||||
|
user.UserTheme = payload.UserTheme
|
||||||
|
}
|
||||||
|
|
||||||
err = handler.DataStore.User().UpdateUser(user.ID, user)
|
err = handler.DataStore.User().UpdateUser(user.ID, user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist user changes inside the database", err}
|
return &httperror.HandlerError{http.StatusInternalServerError, "Unable to persist user changes inside the database", err}
|
||||||
|
|
|
@ -68,7 +68,7 @@ func (factory *ProxyFactory) NewAgentProxy(endpoint *portainer.Endpoint) (*Proxy
|
||||||
return nil, errors.Wrap(err, "failed starting proxy server")
|
return nil, errors.Wrap(err, "failed starting proxy server")
|
||||||
}
|
}
|
||||||
|
|
||||||
return proxyServer, err
|
return proxyServer, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (proxy *ProxyServer) start() error {
|
func (proxy *ProxyServer) start() error {
|
||||||
|
|
|
@ -1,148 +0,0 @@
|
||||||
package libcompose
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
"regexp"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/portainer/libcompose/config"
|
|
||||||
"github.com/portainer/libcompose/docker"
|
|
||||||
"github.com/portainer/libcompose/docker/client"
|
|
||||||
"github.com/portainer/libcompose/docker/ctx"
|
|
||||||
"github.com/portainer/libcompose/lookup"
|
|
||||||
"github.com/portainer/libcompose/project"
|
|
||||||
"github.com/portainer/libcompose/project/options"
|
|
||||||
portainer "github.com/portainer/portainer/api"
|
|
||||||
"github.com/portainer/portainer/api/internal/stackutils"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
dockerClientVersion = "1.24"
|
|
||||||
composeSyntaxMaxVersion = "2"
|
|
||||||
)
|
|
||||||
|
|
||||||
// ComposeStackManager represents a service for managing compose stacks.
|
|
||||||
type ComposeStackManager struct {
|
|
||||||
dataPath string
|
|
||||||
reverseTunnelService portainer.ReverseTunnelService
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewComposeStackManager initializes a new ComposeStackManager service.
|
|
||||||
func NewComposeStackManager(dataPath string, reverseTunnelService portainer.ReverseTunnelService) *ComposeStackManager {
|
|
||||||
return &ComposeStackManager{
|
|
||||||
dataPath: dataPath,
|
|
||||||
reverseTunnelService: reverseTunnelService,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (manager *ComposeStackManager) createClient(endpoint *portainer.Endpoint) (client.Factory, error) {
|
|
||||||
|
|
||||||
endpointURL := endpoint.URL
|
|
||||||
if endpoint.Type == portainer.EdgeAgentOnDockerEnvironment {
|
|
||||||
tunnel := manager.reverseTunnelService.GetTunnelDetails(endpoint.ID)
|
|
||||||
endpointURL = fmt.Sprintf("tcp://127.0.0.1:%d", tunnel.Port)
|
|
||||||
}
|
|
||||||
|
|
||||||
clientOpts := client.Options{
|
|
||||||
Host: endpointURL,
|
|
||||||
APIVersion: dockerClientVersion,
|
|
||||||
}
|
|
||||||
|
|
||||||
if endpoint.TLSConfig.TLS {
|
|
||||||
clientOpts.TLS = endpoint.TLSConfig.TLS
|
|
||||||
clientOpts.TLSVerify = !endpoint.TLSConfig.TLSSkipVerify
|
|
||||||
clientOpts.TLSCAFile = endpoint.TLSConfig.TLSCACertPath
|
|
||||||
clientOpts.TLSCertFile = endpoint.TLSConfig.TLSCertPath
|
|
||||||
clientOpts.TLSKeyFile = endpoint.TLSConfig.TLSKeyPath
|
|
||||||
}
|
|
||||||
|
|
||||||
return client.NewDefaultFactory(clientOpts)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ComposeSyntaxMaxVersion returns the maximum supported version of the docker compose syntax
|
|
||||||
func (manager *ComposeStackManager) ComposeSyntaxMaxVersion() string {
|
|
||||||
return composeSyntaxMaxVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
// NormalizeStackName returns a new stack name with unsupported characters replaced
|
|
||||||
func (manager *ComposeStackManager) NormalizeStackName(name string) string {
|
|
||||||
// this is coming from libcompose
|
|
||||||
// https://github.com/portainer/libcompose/blob/master/project/context.go#L117-L120
|
|
||||||
r := regexp.MustCompile("[^a-z0-9]+")
|
|
||||||
return r.ReplaceAllString(strings.ToLower(name), "")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Up will deploy a compose stack (equivalent of docker-compose up)
|
|
||||||
func (manager *ComposeStackManager) Up(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
|
||||||
|
|
||||||
clientFactory, err := manager.createClient(endpoint)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
env := make(map[string]string)
|
|
||||||
for _, envvar := range stack.Env {
|
|
||||||
env[envvar.Name] = envvar.Value
|
|
||||||
}
|
|
||||||
filePaths := stackutils.GetStackFilePaths(stack)
|
|
||||||
|
|
||||||
proj, err := docker.NewProject(&ctx.Context{
|
|
||||||
ConfigDir: manager.dataPath,
|
|
||||||
Context: project.Context{
|
|
||||||
ComposeFiles: filePaths,
|
|
||||||
EnvironmentLookup: &lookup.ComposableEnvLookup{
|
|
||||||
Lookups: []config.EnvironmentLookup{
|
|
||||||
&lookup.EnvfileLookup{
|
|
||||||
Path: filepath.Join(stack.ProjectPath, ".env"),
|
|
||||||
},
|
|
||||||
&lookup.MapLookup{
|
|
||||||
Vars: env,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
ProjectName: stack.Name,
|
|
||||||
},
|
|
||||||
ClientFactory: clientFactory,
|
|
||||||
}, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return proj.Up(context.Background(), options.Up{})
|
|
||||||
}
|
|
||||||
|
|
||||||
// Down will shutdown a compose stack (equivalent of docker-compose down)
|
|
||||||
func (manager *ComposeStackManager) Down(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
|
||||||
clientFactory, err := manager.createClient(endpoint)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var composeFiles []string
|
|
||||||
for _, file := range append([]string{stack.EntryPoint}, stack.AdditionalFiles...) {
|
|
||||||
composeFiles = append(composeFiles, path.Join(stack.ProjectPath, file))
|
|
||||||
}
|
|
||||||
proj, err := docker.NewProject(&ctx.Context{
|
|
||||||
Context: project.Context{
|
|
||||||
ComposeFiles: composeFiles,
|
|
||||||
ProjectName: stack.Name,
|
|
||||||
},
|
|
||||||
ClientFactory: clientFactory,
|
|
||||||
}, nil)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return proj.Down(context.Background(), options.Down{RemoveVolume: false, RemoveOrphans: true})
|
|
||||||
}
|
|
||||||
|
|
||||||
func stackFilePaths(stack *portainer.Stack) []string {
|
|
||||||
var filePaths []string
|
|
||||||
for _, file := range append([]string{stack.EntryPoint}, stack.AdditionalFiles...) {
|
|
||||||
filePaths = append(filePaths, path.Join(stack.ProjectPath, file))
|
|
||||||
}
|
|
||||||
return filePaths
|
|
||||||
}
|
|
|
@ -1003,6 +1003,8 @@ type (
|
||||||
ID UserID `json:"Id" example:"1"`
|
ID UserID `json:"Id" example:"1"`
|
||||||
Username string `json:"Username" example:"bob"`
|
Username string `json:"Username" example:"bob"`
|
||||||
Password string `json:"Password,omitempty" example:"passwd"`
|
Password string `json:"Password,omitempty" example:"passwd"`
|
||||||
|
// User Theme
|
||||||
|
UserTheme string `example:"dark"`
|
||||||
// User role (1 for administrator account and 2 for regular account)
|
// User role (1 for administrator account and 2 for regular account)
|
||||||
Role UserRole `json:"Role" example:"1"`
|
Role UserRole `json:"Role" example:"1"`
|
||||||
|
|
||||||
|
@ -1054,8 +1056,8 @@ type (
|
||||||
ComposeStackManager interface {
|
ComposeStackManager interface {
|
||||||
ComposeSyntaxMaxVersion() string
|
ComposeSyntaxMaxVersion() string
|
||||||
NormalizeStackName(name string) string
|
NormalizeStackName(name string) string
|
||||||
Up(stack *Stack, endpoint *Endpoint) error
|
Up(ctx context.Context, stack *Stack, endpoint *Endpoint) error
|
||||||
Down(stack *Stack, endpoint *Endpoint) error
|
Down(ctx context.Context, stack *Stack, endpoint *Endpoint) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// CryptoService represents a service for encrypting/hashing data
|
// CryptoService represents a service for encrypting/hashing data
|
||||||
|
@ -1179,6 +1181,7 @@ type (
|
||||||
|
|
||||||
// FileService represents a service for managing files
|
// FileService represents a service for managing files
|
||||||
FileService interface {
|
FileService interface {
|
||||||
|
GetDockerConfigPath() string
|
||||||
GetFileContent(filePath string) ([]byte, error)
|
GetFileContent(filePath string) ([]byte, error)
|
||||||
Rename(oldPath, newPath string) error
|
Rename(oldPath, newPath string) error
|
||||||
RemoveDirectory(directoryPath string) error
|
RemoveDirectory(directoryPath string) error
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package stacks
|
package stacks
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"os"
|
"os"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
|
@ -50,7 +51,7 @@ func (d *stackDeployer) DeployComposeStack(stack *portainer.Stack, endpoint *por
|
||||||
d.swarmStackManager.Login(registries, endpoint)
|
d.swarmStackManager.Login(registries, endpoint)
|
||||||
defer d.swarmStackManager.Logout(endpoint)
|
defer d.swarmStackManager.Logout(endpoint)
|
||||||
|
|
||||||
return d.composeStackManager.Up(stack, endpoint)
|
return d.composeStackManager.Up(context.TODO(), stack, endpoint)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (d *stackDeployer) DeployKubernetesStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
func (d *stackDeployer) DeployKubernetesStack(stack *portainer.Stack, endpoint *portainer.Endpoint) error {
|
||||||
|
|
|
@ -59,10 +59,10 @@ body,
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-section-title {
|
.form-section-title {
|
||||||
border-bottom: 1px solid #777;
|
border-bottom: 1px solid var(--border-form-section-title-color);
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
color: #777;
|
color: var(--text-form-section-title-color);
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,12 +108,33 @@ a[ng-click] {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.datatable-highlighted {
|
||||||
|
background-color: var(--bg-item-highlighted-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.datatable-unhighlighted {
|
||||||
|
background-color: var(--bg-item-highlighted-null-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-datatable {
|
||||||
|
background-color: var(--bg-item-highlighted-color);
|
||||||
|
padding: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-datatable thead {
|
||||||
|
background-color: var(--bg-service-datatable-thead) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.service-datatable tbody {
|
||||||
|
background-color: var(--bg-service-datatable-tbody);
|
||||||
|
}
|
||||||
|
|
||||||
.tooltip.portainer-tooltip .tooltip-inner {
|
.tooltip.portainer-tooltip .tooltip-inner {
|
||||||
font-family: Montserrat;
|
font-family: Montserrat;
|
||||||
background-color: #ffffff;
|
background-color: var(--bg-tooltip-color);
|
||||||
padding: 0.833em 1em;
|
padding: 0.833em 1em;
|
||||||
color: #333333;
|
color: var(--text-tooltip-color);
|
||||||
border: 1px solid #d4d4d5;
|
border: 1px solid var(--border-tooltip-color);
|
||||||
border-radius: 0.14285714rem;
|
border-radius: 0.14285714rem;
|
||||||
box-shadow: 0 2px 4px 0 rgba(34, 36, 38, 0.12), 0 2px 10px 0 rgba(34, 36, 38, 0.15);
|
box-shadow: 0 2px 4px 0 rgba(34, 36, 38, 0.12), 0 2px 10px 0 rgba(34, 36, 38, 0.15);
|
||||||
}
|
}
|
||||||
|
@ -145,7 +166,7 @@ a[ng-click] {
|
||||||
|
|
||||||
.fa.blue-icon,
|
.fa.blue-icon,
|
||||||
.fab.blue-icon {
|
.fab.blue-icon {
|
||||||
color: #337ab7;
|
color: var(--blue-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.text-warning {
|
.text-warning {
|
||||||
|
@ -207,25 +228,25 @@ a[ng-click] {
|
||||||
padding: 0.7rem;
|
padding: 0.7rem;
|
||||||
margin-bottom: 0.7rem;
|
margin-bottom: 0.7rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border: 1px solid #cccccc;
|
border: 1px solid var(--border-blocklist-color);
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
box-shadow: 0 3px 10px -2px rgba(161, 170, 166, 0.5);
|
box-shadow: var(--shadow-box-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.blocklist-item--disabled {
|
.blocklist-item--disabled {
|
||||||
cursor: auto;
|
cursor: auto;
|
||||||
background-color: #ececec;
|
background-color: var(--grey-12);
|
||||||
}
|
}
|
||||||
|
|
||||||
.blocklist-item--selected {
|
.blocklist-item--selected {
|
||||||
border: 2px solid #bbbbbb;
|
background-color: var(--bg-blocklist-item-selected-color);
|
||||||
background-color: #ececec;
|
border: 2px solid var(--border-blocklist-item-selected-color);
|
||||||
color: #2d3e63;
|
color: var(--text-blocklist-item-selected-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.blocklist-item:hover {
|
.blocklist-item:hover {
|
||||||
background-color: #ececec;
|
background-color: var(--bg-blocklist-hover-color);
|
||||||
color: #2d3e63;
|
color: var(--text-blocklist-hover-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.blocklist-item-box {
|
.blocklist-item-box {
|
||||||
|
@ -360,7 +381,7 @@ a[ng-click] {
|
||||||
|
|
||||||
.panel-body {
|
.panel-body {
|
||||||
padding-top: 30px;
|
padding-top: 30px;
|
||||||
background-color: #ffffff;
|
background-color: var(--white-color) fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.pagination-controls {
|
.pagination-controls {
|
||||||
|
@ -443,8 +464,8 @@ a[ng-click] {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
padding: 0px 6px;
|
padding: 0px 6px;
|
||||||
margin-left: 10px;
|
margin-left: 10px;
|
||||||
color: #555555;
|
color: var(--text-small-select-color);
|
||||||
background-color: #fff;
|
background-color: var(--bg-small-select-color);
|
||||||
background-image: none;
|
background-image: none;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
|
@ -462,11 +483,11 @@ a[ng-click] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.visualizer_container .node {
|
.visualizer_container .node {
|
||||||
border: 1px dashed #337ab7;
|
border: 1px dashed var(--blue-2);
|
||||||
background-color: rgb(51, 122, 183);
|
background-color: rgb(51, 122, 183);
|
||||||
background-color: rgba(51, 122, 183, 0.1);
|
background-color: rgba(51, 122, 183, 0.1);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
box-shadow: 0 3px 10px -2px rgba(161, 170, 166, 0.5);
|
box-shadow: 0 3px 10px -2px var(--grey-50);
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
}
|
}
|
||||||
|
@ -476,7 +497,7 @@ a[ng-click] {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
border-bottom: 1px solid #777;
|
border-bottom: 1px solid var(--grey-26);
|
||||||
padding-bottom: 10px;
|
padding-bottom: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -486,7 +507,7 @@ a[ng-click] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.visualizer_container .node .node_info .node_labels {
|
.visualizer_container .node .node_info .node_labels {
|
||||||
border-top: 1px solid #777;
|
border-top: 1px solid var(--grey-26);
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
margin-top: 10px;
|
margin-top: 10px;
|
||||||
}
|
}
|
||||||
|
@ -503,9 +524,9 @@ a[ng-click] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.visualizer_container .node .tasks .task {
|
.visualizer_container .node .tasks .task {
|
||||||
border: 1px solid #333333;
|
border: 1px solid var(--grey-6);
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
box-shadow: 0 3px 10px -2px rgba(161, 170, 166, 0.5);
|
box-shadow: 0 3px 10px -2px var(--grey-50);
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
margin: 5px;
|
margin: 5px;
|
||||||
font-size: 10px;
|
font-size: 10px;
|
||||||
|
@ -547,9 +568,9 @@ a[ng-click] {
|
||||||
.log_viewer {
|
.log_viewer {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
color: black;
|
color: var(--text-log-viewer-color);
|
||||||
font-size: 0.85em;
|
font-size: 0.85em;
|
||||||
background-color: white;
|
background-color: var(--bg-log-viewer-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.log_viewer.wrap_lines {
|
.log_viewer.wrap_lines {
|
||||||
|
@ -568,7 +589,7 @@ a[ng-click] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.log_viewer .line_selected {
|
.log_viewer .line_selected {
|
||||||
background-color: #c5cae9;
|
background-color: var(--bg-log-line-selected-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.row.header .meta .page {
|
.row.header .meta .page {
|
||||||
|
@ -578,7 +599,7 @@ a[ng-click] {
|
||||||
.tag {
|
.tag {
|
||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
color: white;
|
color: white;
|
||||||
background-color: #337ab7;
|
background-color: var(--blue-2);
|
||||||
border: 1px solid #2e6da4;
|
border: 1px solid #2e6da4;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
|
@ -588,7 +609,7 @@ a[ng-click] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.line-separator {
|
.line-separator {
|
||||||
border-bottom: 1px solid #777;
|
border-bottom: 1px solid var(--grey-26);
|
||||||
width: 50%;
|
width: 50%;
|
||||||
margin: 20px auto 10px auto;
|
margin: 20px auto 10px auto;
|
||||||
}
|
}
|
||||||
|
@ -613,7 +634,7 @@ a[ng-click] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.striked::after {
|
.striked::after {
|
||||||
border-bottom: 0.2em solid #777777;
|
border-bottom: 0.2em solid var(--grey-26);
|
||||||
content: '';
|
content: '';
|
||||||
left: 0;
|
left: 0;
|
||||||
margin-top: calc(0.2em / 2 * -1);
|
margin-top: calc(0.2em / 2 * -1);
|
||||||
|
@ -625,7 +646,7 @@ a[ng-click] {
|
||||||
|
|
||||||
.striketext:before,
|
.striketext:before,
|
||||||
.striketext:after {
|
.striketext:after {
|
||||||
background-color: #777777;
|
background-color: var(--grey-26);
|
||||||
content: '';
|
content: '';
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
|
@ -657,20 +678,51 @@ a[ng-click] {
|
||||||
/*angular-multi-select override*/
|
/*angular-multi-select override*/
|
||||||
.multiSelect > button {
|
.multiSelect > button {
|
||||||
min-height: 30px !important;
|
min-height: 30px !important;
|
||||||
background-color: unset;
|
background-image: var(--bg-image-multiselect-button);
|
||||||
background-image: unset;
|
border-color: var(--border-multiselect);
|
||||||
|
color: var(--text-multiselect);
|
||||||
|
background-color: var(--bg-multiselect-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiSelect > button:hover {
|
||||||
|
background-image: var(--bg-image-multiselect-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiSelect .checkboxLayer {
|
||||||
|
border-color: var(--border-multiselect-checkboxlayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiSelect .checkBoxContainer {
|
||||||
|
background-color: var(--bg-multiselect-checkboxcontainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiSelect .multiSelectItem {
|
||||||
|
color: var(--text-multiselect-item);
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiSelect .helperContainer {
|
||||||
|
background-color: var(--bg-multiselect-helpercontainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
.multiSelect .multiSelectFocus {
|
||||||
|
background-image: var(--bg-image-multiselect);
|
||||||
}
|
}
|
||||||
|
|
||||||
.multiSelect .multiSelectItem:not(.multiSelectGroup).selected {
|
.multiSelect .multiSelectItem:not(.multiSelectGroup).selected {
|
||||||
background-image: linear-gradient(#337ab7, #337ab7);
|
background-image: var(--bg-image-multiselect);
|
||||||
color: #fff;
|
color: var(--white-color);
|
||||||
border: none;
|
border: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.multiSelect .multiSelectItem:hover,
|
.multiSelect .multiSelectItem:hover,
|
||||||
.multiSelect .multiSelectGroup:hover {
|
.multiSelect .multiSelectGroup:hover {
|
||||||
background-image: linear-gradient(#337ab7, #337ab7) !important;
|
border-color: var(--grey-3);
|
||||||
color: #fff !important;
|
}
|
||||||
|
|
||||||
|
.multiSelect .multiSelectItem:hover,
|
||||||
|
.multiSelect .multiSelectGroup:hover {
|
||||||
|
background-image: var(--bg-image-multiselect) !important;
|
||||||
|
color: var(--white-color) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.multiSelect .tickMark,
|
.multiSelect .tickMark,
|
||||||
|
@ -696,7 +748,7 @@ a[ng-click] {
|
||||||
#loading-bar .bar {
|
#loading-bar .bar {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 3px;
|
height: 3px;
|
||||||
background: #738bc0;
|
background: var(--blue-3);
|
||||||
}
|
}
|
||||||
/*!angular-loading-bar override*/
|
/*!angular-loading-bar override*/
|
||||||
|
|
||||||
|
@ -708,11 +760,11 @@ a[ng-click] {
|
||||||
/* json-tree override */
|
/* json-tree override */
|
||||||
json-tree {
|
json-tree {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
color: #30426a;
|
color: var(--blue-5);
|
||||||
}
|
}
|
||||||
|
|
||||||
json-tree .key {
|
json-tree .key {
|
||||||
color: #738bc0;
|
color: var(--blue-3);
|
||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -725,7 +777,7 @@ json-tree .branch-preview {
|
||||||
|
|
||||||
/* uib-progressbar override */
|
/* uib-progressbar override */
|
||||||
.progress-bar {
|
.progress-bar {
|
||||||
color: #4e4e4e;
|
color: var(--text-progress-bar-color);
|
||||||
}
|
}
|
||||||
/* !uib-progressbar override */
|
/* !uib-progressbar override */
|
||||||
|
|
||||||
|
@ -756,7 +808,7 @@ json-tree .branch-preview {
|
||||||
}
|
}
|
||||||
|
|
||||||
.sk-fold-cube:before {
|
.sk-fold-cube:before {
|
||||||
background-color: #337ab7;
|
background-color: var(--blue-2);
|
||||||
}
|
}
|
||||||
/* !spinkit override */
|
/* !spinkit override */
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
import './rdash.css';
|
import './rdash.css';
|
||||||
import './app.css';
|
import './app.css';
|
||||||
|
import './theme.css';
|
||||||
|
import './vendor-override.css';
|
||||||
|
|
|
@ -52,7 +52,8 @@
|
||||||
* Header
|
* Header
|
||||||
*/
|
*/
|
||||||
.row.header {
|
.row.header {
|
||||||
background: #fff;
|
height: 60px;
|
||||||
|
background: var(--bg-row-header-color);
|
||||||
margin-bottom: 15px;
|
margin-bottom: 15px;
|
||||||
}
|
}
|
||||||
.row.header > div:last-child {
|
.row.header > div:last-child {
|
||||||
|
@ -202,9 +203,9 @@ html {
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
background: #f3f3f3;
|
background: var(--bg-body-color);
|
||||||
font-family: 'Montserrat';
|
font-family: 'Montserrat';
|
||||||
color: #333333 !important;
|
color: var(--text-body-color) !important;
|
||||||
}
|
}
|
||||||
.row {
|
.row {
|
||||||
margin-left: 0 !important;
|
margin-left: 0 !important;
|
||||||
|
@ -236,7 +237,7 @@ body {
|
||||||
background: #23ae89 !important;
|
background: #23ae89 !important;
|
||||||
}
|
}
|
||||||
.blue {
|
.blue {
|
||||||
background: #2361ae !important;
|
background: var(--blue-color) !important;
|
||||||
}
|
}
|
||||||
.orange {
|
.orange {
|
||||||
background: #d3a938 !important;
|
background: #d3a938 !important;
|
||||||
|
@ -258,20 +259,20 @@ div.input-mask {
|
||||||
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
-webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
||||||
-moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
-moz-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
||||||
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);
|
||||||
background: #ffffff;
|
background: var(--bg-widget-color);
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
border-color: #e9e9e9;
|
border-color: var(--border-widget-color);
|
||||||
}
|
}
|
||||||
.widget .widget-header .pagination,
|
.widget .widget-header .pagination,
|
||||||
.widget .widget-footer .pagination {
|
.widget .widget-footer .pagination {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
.widget .widget-header {
|
.widget .widget-header {
|
||||||
color: #767676;
|
color: var(--text-widget-header-color);
|
||||||
background-color: #f6f6f6;
|
background-color: var(--bg-widget-header-color);
|
||||||
padding: 10px 15px;
|
padding: 10px 15px;
|
||||||
border-bottom: 1px solid #e9e9e9;
|
border-bottom: 1px solid var(--border-widget-color);
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
}
|
}
|
||||||
.widget .widget-header i {
|
.widget .widget-header i {
|
||||||
|
@ -281,7 +282,7 @@ div.input-mask {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
.widget .widget-body table thead {
|
.widget .widget-body table thead {
|
||||||
background: #fafafa;
|
background: var(--bg-widget-table-color);
|
||||||
}
|
}
|
||||||
.widget .widget-body table thead * {
|
.widget .widget-body table thead * {
|
||||||
font-size: 14px !important;
|
font-size: 14px !important;
|
||||||
|
|
|
@ -0,0 +1,576 @@
|
||||||
|
/* Color Variable */
|
||||||
|
html {
|
||||||
|
--black-color: #000;
|
||||||
|
--white-color: #fff;
|
||||||
|
|
||||||
|
--grey-1: #212121;
|
||||||
|
--grey-2: #181818;
|
||||||
|
--grey-3: #383838;
|
||||||
|
--grey-4: #585858;
|
||||||
|
--grey-5: #323c48;
|
||||||
|
--grey-6: #333333;
|
||||||
|
--grey-7: #767676;
|
||||||
|
--grey-8: #aaa;
|
||||||
|
--grey-9: #f3f3f3;
|
||||||
|
--grey-10: #f6f6f6;
|
||||||
|
--grey-11: #eeeeee;
|
||||||
|
--grey-12: #ececec;
|
||||||
|
--grey-13: #fafafa;
|
||||||
|
--grey-14: #f5f5f5;
|
||||||
|
--grey-15: #f9f2f4;
|
||||||
|
--grey-16: #eee;
|
||||||
|
--grey-17: #f7f7f7;
|
||||||
|
--grey-18: #c5cae9;
|
||||||
|
--grey-19: #ddd;
|
||||||
|
--grey-20: #dae3f3;
|
||||||
|
--grey-21: #d5e8f3;
|
||||||
|
--grey-22: #c3c3e4;
|
||||||
|
--grey-23: #e7f6ff;
|
||||||
|
--grey-24: #f1f9fd;
|
||||||
|
--grey-25: #555555;
|
||||||
|
--grey-26: #777777;
|
||||||
|
--grey-27: #4e4e4e;
|
||||||
|
--grey-28: #262626;
|
||||||
|
--grey-29: #555;
|
||||||
|
--grey-30: #444;
|
||||||
|
--grey-31: #868686;
|
||||||
|
--grey-32: #65798e;
|
||||||
|
--grey-34: #314252;
|
||||||
|
--grey-35: #546477;
|
||||||
|
--grey-36: #55637d;
|
||||||
|
--grey-37: #2d3e63;
|
||||||
|
--grey-38: #434343;
|
||||||
|
--grey-39: #194973;
|
||||||
|
--grey-40: #cfddfc;
|
||||||
|
--grey-41: #b4b4b4;
|
||||||
|
--grey-42: #d2d1d1;
|
||||||
|
--grey-43: #e9e9e9;
|
||||||
|
--grey-44: #ccc;
|
||||||
|
--grey-45: #e5e5e5;
|
||||||
|
--grey-46: #bbbbbb;
|
||||||
|
--grey-47: #d4d4d5;
|
||||||
|
--grey-48: #c6c6c6;
|
||||||
|
--grey-49: rgba(0, 0, 0, 0.54);
|
||||||
|
--grey-50: rgba(161, 170, 166, 0.5);
|
||||||
|
--grey-51: rgba(0, 0, 0, 0.15);
|
||||||
|
--grey-52: rgba(255, 255, 255, 0.3);
|
||||||
|
--grey-53: rgba(255, 255, 255, 0.6);
|
||||||
|
--grey-54: rgb(54, 54, 54);
|
||||||
|
--grey-55: rgba(255, 255, 255, 0.8);
|
||||||
|
--grey-56: #b2bfdc;
|
||||||
|
--grey-57: #999;
|
||||||
|
--grey-58: #ebf4f8;
|
||||||
|
--grey-59: #e6e6e6;
|
||||||
|
--grey-60: #cacaca;
|
||||||
|
|
||||||
|
--blue-1: #219;
|
||||||
|
--blue-2: #337ab7;
|
||||||
|
--blue-3: #738bc0;
|
||||||
|
--blue-4: #23527c;
|
||||||
|
--blue-5: #30426a;
|
||||||
|
--blue-6: #577bc9;
|
||||||
|
--blue-7: #6b9aff;
|
||||||
|
--blue-8: #90ccff;
|
||||||
|
--blue-9: #3ea6ff;
|
||||||
|
--blue-10: #61b6ff;
|
||||||
|
--blue-11: #3ea5ff;
|
||||||
|
--blue-12: #41a6ff;
|
||||||
|
--blue-13: #2361ae;
|
||||||
|
--blue-14: #357ebd;
|
||||||
|
|
||||||
|
--red-1: #a94442;
|
||||||
|
--red-2: #c7254e;
|
||||||
|
--red-3: #a11;
|
||||||
|
--red-4: #d9534f;
|
||||||
|
--red-5: #ff2727;
|
||||||
|
--red-6: #ff00e0;
|
||||||
|
--red-7: #f00;
|
||||||
|
|
||||||
|
--green-1: #164;
|
||||||
|
--green-2: #1ec863;
|
||||||
|
}
|
||||||
|
|
||||||
|
:root {
|
||||||
|
--bg-card-color: var(--grey-10);
|
||||||
|
--bg-main-color: var(--white-color);
|
||||||
|
--bg-body-color: var(--grey-9);
|
||||||
|
--bg-checkbox-border-color: var(--grey-49);
|
||||||
|
--bg-sidebar-color: var(--grey-37);
|
||||||
|
--bg-sidebar-header-color: var(--grey-37);
|
||||||
|
--bg-widget-color: var(--white-color);
|
||||||
|
--bg-widget-header-color: var(--grey-10);
|
||||||
|
--bg-widget-table-color: var(--grey-13);
|
||||||
|
--bg-header-color: var(--white-color);
|
||||||
|
--bg-hover-table-color: var(--grey-14);
|
||||||
|
--bg-switch-box-color: var(--white-color);
|
||||||
|
--bg-input-group-addon-color: var(--grey-11);
|
||||||
|
--bg-btn-default-color: var(--white-color);
|
||||||
|
--bg-blocklist-hover-color: var(--grey-12);
|
||||||
|
--bg-boxselector-color: var(--white-color);
|
||||||
|
--bg-table-color: var(--white-color);
|
||||||
|
--bg-md-checkbox-color: var(--grey-12);
|
||||||
|
--bg-form-control-disabled-color: var(--grey-11);
|
||||||
|
--bg-modal-content-color: var(--white-color);
|
||||||
|
--bg-code-color: var(--grey-15);
|
||||||
|
--bg-navtabs-color: var(--white-color);
|
||||||
|
--bg-navtabs-hover-color: var(--grey-16);
|
||||||
|
--bg-table-selected-color: var(--grey-14);
|
||||||
|
--bg-codemirror-gutters-color: var(--grey-17);
|
||||||
|
--bg-dropdown-menu-color: var(--white-color);
|
||||||
|
--bg-log-viewer-color: var(--white-color);
|
||||||
|
--bg-log-line-selected-color: var(--grey-18);
|
||||||
|
--bg-pre-color: var(--grey-14);
|
||||||
|
--bg-blocklist-item-selected-color: var(--grey-12);
|
||||||
|
--bg-progress-color: var(--grey-14);
|
||||||
|
--bg-pagination-color: var(--white-color);
|
||||||
|
--bg-pagination-span-color: var(--white-color);
|
||||||
|
--bg-pagination-hover-color: var(--grey-11);
|
||||||
|
--bg-ui-select-hover-color: var(--grey-14);
|
||||||
|
--bg-motd-body-color: var(--grey-20);
|
||||||
|
--bg-item-highlighted-color: var(--grey-21);
|
||||||
|
--bg-item-highlighted-null-color: var(--grey-14);
|
||||||
|
--bg-row-header-color: var(--white-color);
|
||||||
|
--bg-image-multiselect-button: linear-gradient(var(--white-color), var(--grey-17));
|
||||||
|
--bg-multiselect-checkbox-color: var(--white-color);
|
||||||
|
--bg-sidebar-wrapper-color: var(--blue-5);
|
||||||
|
--bg-panel-body-color: var(--white-color);
|
||||||
|
--bg-codemirror-color: var(--white-color);
|
||||||
|
--bg-codemirror-selected-color: var(--grey-22);
|
||||||
|
--bg-multiselect-color: var(--white-color);
|
||||||
|
--bg-daterangepicker-color: var(--white-color);
|
||||||
|
--bg-calendar-color: var(--white-color);
|
||||||
|
--bg-calendar-table-color: var(--white-color);
|
||||||
|
--bg-daterangepicker-end-date: var(--white-color);
|
||||||
|
--bg-daterangepicker-hover: var(--grey-16);
|
||||||
|
--bg-daterangepicker-in-range: var(--grey-58);
|
||||||
|
--bg-daterangepicker-active: var(--blue-14);
|
||||||
|
--bg-tooltip-color: var(--white-color);
|
||||||
|
--bg-input-autofill-color: var(--white-color);
|
||||||
|
--bg-btn-default-hover-color: var(--grey-59);
|
||||||
|
--bg-btn-focus: var(--grey-59);
|
||||||
|
--bg-boxselector-disabled-color: var(--white-color);
|
||||||
|
--bg-small-select-color: var(--white-color);
|
||||||
|
|
||||||
|
--text-main-color: var(--grey-7);
|
||||||
|
--text-body-color: var(--grey-6);
|
||||||
|
--text-sidebar-title-color: var(--blue-3);
|
||||||
|
--text-widget-header-color: var(--grey-7);
|
||||||
|
--text-form-control-color: var(--grey-25);
|
||||||
|
--text-muted-color: var(--grey-26);
|
||||||
|
--text-link-color: var(--blue-2);
|
||||||
|
--text-link-hover-color: var(--blue-4);
|
||||||
|
--text-input-group-addon-color: var(--grey-25);
|
||||||
|
--text-btn-default-color: var(--grey-6);
|
||||||
|
--text-blocklist-hover-color: var(--grey-37);
|
||||||
|
--text-dashboard-item-color: var(--grey-32);
|
||||||
|
--text-danger-color: var(--red-1);
|
||||||
|
--text-code-color: var(--red-2);
|
||||||
|
--text-navtabs-color: var(--grey-25);
|
||||||
|
--text-form-section-title-color: var(--grey-26);
|
||||||
|
--text-cm-default-color: var(--blue-1);
|
||||||
|
--text-cm-meta-color: var(--black-color);
|
||||||
|
--text-cm-string-color: var(--red-3);
|
||||||
|
--text-cm-number-color: var(--green-1);
|
||||||
|
--text-codemirror-color: var(--black-color);
|
||||||
|
--text-dropdown-menu-color: var(--grey-6);
|
||||||
|
--text-log-viewer-color: var(--black-color);
|
||||||
|
--text-json-tree-color: var(--blue-3);
|
||||||
|
--text-json-tree-leaf-color: var(--blue-5);
|
||||||
|
--text-json-tree-branch-preview-color: var(--blue-5);
|
||||||
|
--text-pre-color: var(--grey-6);
|
||||||
|
--text-blocklist-item-selected-color: var(--grey-37);
|
||||||
|
--text-progress-bar-color: var(--grey-27);
|
||||||
|
--text-pagination-color: var(--grey-26);
|
||||||
|
--text-pagination-span-color: var(--blue-2);
|
||||||
|
--text-pagination-span-hover-color: var(--blue-4);
|
||||||
|
--text-ui-select-color: var(--grey-6);
|
||||||
|
--text-ui-select-hover-color: var(--grey-28);
|
||||||
|
--text-summary-color: var(--black-color);
|
||||||
|
--text-multiselect-button-color: var(--grey-29);
|
||||||
|
--text-multiselect-item-color: var(--grey-30);
|
||||||
|
--text-sidebar-list-color: var(--grey-56);
|
||||||
|
--text-rzslider-color: var(--grey-36);
|
||||||
|
--text-rzslider-limit-color: var(--grey-36);
|
||||||
|
--text-daterangepicker-end-date: var(--grey-57);
|
||||||
|
--text-daterangepicker-in-range: var(--black-color);
|
||||||
|
--text-daterangepicker-active: var(--white-color);
|
||||||
|
--text-tooltip-color: var(--grey-6);
|
||||||
|
--text-input-autofill-color: var(--black-color);
|
||||||
|
--text-button-hover-color: var(--grey-6);
|
||||||
|
--text-small-select-color: var(--grey-25);
|
||||||
|
|
||||||
|
--border-color: var(--grey-42);
|
||||||
|
--border-widget-color: var(--grey-43);
|
||||||
|
--border-sidebar-color: var(--white-color);
|
||||||
|
--border-form-control-color: var(--grey-44);
|
||||||
|
--border-table-color: var(--grey-19);
|
||||||
|
--border-table-top-color: var(--grey-19);
|
||||||
|
--border-datatable-top-color: var(--grey-10);
|
||||||
|
--border-blocklist-color: var(--grey-44) ccc;
|
||||||
|
--border-input-group-addon-color: var(--grey-44);
|
||||||
|
--border-btn-default-color: var(--grey-44);
|
||||||
|
--border-boxselector-color: var(--grey-6);
|
||||||
|
--border-md-checkbox-color: var(--grey-19);
|
||||||
|
--border-modal-header-color: var(--grey-45);
|
||||||
|
--border-navtabs-color: var(--grey-19);
|
||||||
|
--border-form-section-title-color: var(--grey-26);
|
||||||
|
--border-codemirror-cursor-color: var(--black-color);
|
||||||
|
--border-codemirror-gutters-color: var(--grey-19);
|
||||||
|
--border-pre-color: var(--grey-43);
|
||||||
|
--border-blocklist-item-selected-color: var(--grey-46);
|
||||||
|
--border-pagination-color: var(--grey-19);
|
||||||
|
--border-pagination-span-color: var(--grey-19);
|
||||||
|
--border-pagination-hover-color: var(--grey-19);
|
||||||
|
--border-multiselect-button-color: var(--grey-48);
|
||||||
|
--border-searchbar-color: var(--grey-10);
|
||||||
|
--border-panel-color: var(--white-color);
|
||||||
|
--border-daterangepicker-color: var(--grey-19);
|
||||||
|
--border-calendar-table: var(--white-color);
|
||||||
|
--border-daterangepicker: var(--grey-19);
|
||||||
|
--border-pre-next-month: var(--black-color);
|
||||||
|
--border-daterangepicker-after: var(--white-color);
|
||||||
|
--border-tooltip-color: var(--grey-47);
|
||||||
|
--border-modal: 0px;
|
||||||
|
|
||||||
|
--hover-sidebar-color: var(--grey-37);
|
||||||
|
--shadow-box-color: 0 3px 10px -2px var(--grey-50);
|
||||||
|
--shadow-boxselector-color: 0 3px 10px -2px var(--grey-50);
|
||||||
|
--blue-color: var(--blue-13);
|
||||||
|
--button-close-color: var(--black-color);
|
||||||
|
--button-opacity: 0.2;
|
||||||
|
--button-opacity-hover: 0.5;
|
||||||
|
--bg-boxselector-wrapper-color: var(--grey-6);
|
||||||
|
|
||||||
|
--bg-image-multiselect: linear-gradient(var(--blue-2), var(--blue-2));
|
||||||
|
--bg-image-multiselect-button: linear-gradient(var(--white-color), var(--grey-17));
|
||||||
|
--bg-image-multiselect-hover: linear-gradient(var(--white-color), var(--grey-43));
|
||||||
|
--border-multiselect: var(--grey-48);
|
||||||
|
--border-multiselect-checkboxlayer: var(--grey-51);
|
||||||
|
--text-multiselect: var(--grey-29);
|
||||||
|
--text-multiselect-selectitem: var(--white-color);
|
||||||
|
--bg-multiselect-checkboxcontainer: var(--white-color);
|
||||||
|
--text-multiselect-item: var(--grey-30);
|
||||||
|
--bg-multiselect-helpercontainer: var(--white-color);
|
||||||
|
--text-input-textarea: var(--white-color);
|
||||||
|
--bg-service-datatable-thead: var(--grey-23);
|
||||||
|
--bg-service-datatable-tbody: var(--grey-24);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[theme='dark'] {
|
||||||
|
--bg-card-color: var(--grey-1);
|
||||||
|
--bg-main-color: var(--grey-2);
|
||||||
|
--bg-body-color: var(--grey-2);
|
||||||
|
--bg-checkbox-border-color: var(--grey-8);
|
||||||
|
--bg-sidebar-color: var(--grey-3);
|
||||||
|
--bg-widget-color: var(--grey-1);
|
||||||
|
--bg-widget-header-color: var(--grey-1);
|
||||||
|
--bg-widget-table-color: var(--grey-1);
|
||||||
|
--bg-header-color: var(--grey-2);
|
||||||
|
--bg-hover-table-color: var(--grey-3);
|
||||||
|
--bg-switch-box-color: var(--grey-53);
|
||||||
|
--bg-input-group-addon-color: var(--grey-3);
|
||||||
|
--bg-btn-default-color: var(--grey-3);
|
||||||
|
--bg-blocklist-hover-color: var(--grey-3);
|
||||||
|
--bg-boxselector-color: var(--grey-54);
|
||||||
|
--bg-table-color: var(--grey-1);
|
||||||
|
--bg-md-checkbox-color: var(--grey-31);
|
||||||
|
--bg-form-control-disabled-color: var(--grey-3);
|
||||||
|
--bg-modal-content-color: var(--grey-1);
|
||||||
|
--bg-code-color: var(--red-4);
|
||||||
|
--bg-navtabs-color: var(--grey-3);
|
||||||
|
--bg-navtabs-hover-color: var(--grey-3);
|
||||||
|
--bg-table-selected-color: var(--grey-3);
|
||||||
|
--bg-codemirror-color: var(--grey-2);
|
||||||
|
--bg-codemirror-gutters-color: var(--grey-2);
|
||||||
|
--bg-dropdown-menu-color: var(--grey-1);
|
||||||
|
--bg-log-viewer-color: var(--grey-2);
|
||||||
|
--bg-log-line-selected-color: var(--grey-3);
|
||||||
|
--bg-pre-color: var(--grey-2);
|
||||||
|
--bg-blocklist-item-selected-color: var(--grey-3);
|
||||||
|
--bg-progress-color: var(--grey-3);
|
||||||
|
--bg-pagination-color: var(--grey-3);
|
||||||
|
--bg-pagination-span-color: var(--grey-3);
|
||||||
|
--bg-pagination-hover-color: var(--grey-4);
|
||||||
|
--bg-ui-select-hover-color: var(--grey-3);
|
||||||
|
--bg-motd-body-color: var(--grey-1);
|
||||||
|
--bg-item-highlighted-color: var(--grey-2);
|
||||||
|
--bg-item-highlighted-null-color: var(--grey-2);
|
||||||
|
--bg-row-header-color: var(--grey-2);
|
||||||
|
--bg-multiselect-button-color: var(--grey-3);
|
||||||
|
--bg-image-multiselect-button: none !important;
|
||||||
|
--bg-multiselect-checkbox-color: var(--grey-3);
|
||||||
|
--bg-sidebar-wrapper-color: var(--grey-1);
|
||||||
|
--bg-panel-body-color: var(--grey-1);
|
||||||
|
--bg-boxselector-wrapper-disabled-color: var(--grey-39);
|
||||||
|
--bg-codemirror-selected-color: var(--grey-3);
|
||||||
|
--bg-sidebar-header-color: var(--grey-1);
|
||||||
|
--bg-multiselect-color: var(--grey-1);
|
||||||
|
--bg-daterangepicker-color: var(--grey-3);
|
||||||
|
--bg-calendar-color: var(--grey-3);
|
||||||
|
--bg-calendar-table-color: var(--grey-3);
|
||||||
|
--bg-daterangepicker-end-date: var(--grey-4);
|
||||||
|
--bg-daterangepicker-hover: var(--grey-4);
|
||||||
|
--bg-daterangepicker-in-range: var(--grey-2);
|
||||||
|
--bg-daterangepicker-active: var(--blue-14);
|
||||||
|
--bg-tooltip-color: var(--grey-3);
|
||||||
|
--bg-input-autofill-color: var(--grey-2);
|
||||||
|
--bg-btn-default-hover-color: var(--grey-3);
|
||||||
|
--bg-btn-focus: var(--grey-3);
|
||||||
|
--bg-boxselector-disabled-color: var(--grey-54);
|
||||||
|
--bg-small-select-color: var(--grey-2);
|
||||||
|
|
||||||
|
--text-main-color: var(--white-color);
|
||||||
|
--text-body-color: var(--white-color);
|
||||||
|
--text-sidebar-title-color: var(--grey-8);
|
||||||
|
--text-widget-header-color: var(--white-color);
|
||||||
|
--text-form-control-color: var(--grey-8);
|
||||||
|
--text-muted-color: var(--grey-8);
|
||||||
|
--text-link-color: var(--blue-9);
|
||||||
|
--text-link-hover-color: var(--blue-2);
|
||||||
|
--text-input-group-addon-color: var(--grey-8);
|
||||||
|
--text-btn-default-color: var(--grey-8);
|
||||||
|
--text-blocklist-hover-color: var(--white-color);
|
||||||
|
--text-dashboard-item-color: var(--blue-2);
|
||||||
|
--text-danger-color: var(--red-4);
|
||||||
|
--text-code-color: var(--white-color);
|
||||||
|
--text-navtabs-color: var(--white-color);
|
||||||
|
--text-form-section-title-color: var(--grey-8);
|
||||||
|
--text-cm-default-color: var(--blue-10);
|
||||||
|
--text-cm-meta-color: var(--white-color);
|
||||||
|
--text-cm-string-color: var(--red-5);
|
||||||
|
--text-cm-number-color: var(--green-2);
|
||||||
|
--text-codemirror-color: var(--white-color);
|
||||||
|
--text-dropdown-menu-color: var(--white-color);
|
||||||
|
--text-log-viewer-color: var(--white-color);
|
||||||
|
--text-json-tree-color: var(--grey-40);
|
||||||
|
--text-json-tree-leaf-color: var(--blue-6);
|
||||||
|
--text-json-tree-branch-preview-color: var(--blue-7);
|
||||||
|
--text-pre-color: var(--white-color);
|
||||||
|
--text-blocklist-item-selected-color: var(--white-color);
|
||||||
|
--text-progress-bar-color: var(--white-color);
|
||||||
|
--text-pagination-color: var(--white-color);
|
||||||
|
--text-pagination-span-color: var(--white-color);
|
||||||
|
--text-pagination-span-hover-color: var(--white-color);
|
||||||
|
--text-ui-select-color: var(--white-color);
|
||||||
|
--text-ui-select-hover-color: var(--white-color);
|
||||||
|
--text-summary-color: var(--white-color);
|
||||||
|
--text-multiselect-button-color: var(--white-color);
|
||||||
|
--text-multiselect-item-color: var(--white-color);
|
||||||
|
--text-sidebar-list-color: var(--white-color);
|
||||||
|
--text-boxselector-wrapper-color: var(--white-color);
|
||||||
|
--text-daterangepicker-end-date: var(--grey-7);
|
||||||
|
--text-daterangepicker-in-range: var(--white-color);
|
||||||
|
--text-daterangepicker-active: var(--white-color);
|
||||||
|
--text-tooltip-color: var(--white-color);
|
||||||
|
--text-btn-default-color: var(--white-color);
|
||||||
|
--text-input-autofill-color: var(--grey-8);
|
||||||
|
--text-button-hover-color: var(--white-color);
|
||||||
|
--text-small-select-color: var(--grey-7);
|
||||||
|
|
||||||
|
--border-color: var(--grey-3);
|
||||||
|
--border-widget-color: var(--grey-1);
|
||||||
|
--border-sidebar-color: var(--blue-9);
|
||||||
|
--border-form-control-color: var(--grey-54);
|
||||||
|
--border-table-color: var(--grey-3);
|
||||||
|
--border-table-top-color: var(--grey-3);
|
||||||
|
--border-datatable-top-color: var(--grey-3);
|
||||||
|
--border-blocklist-color: var(--grey-3);
|
||||||
|
--border-input-group-addon-color: var(--grey-38);
|
||||||
|
--border-btn-default-color: var(--grey-38);
|
||||||
|
--border-boxselector-color: var(--grey-1);
|
||||||
|
--border-md-checkbox-color: var(--grey-41);
|
||||||
|
--border-modal-header-color: var(--grey-1);
|
||||||
|
--border-navtabs-color: var(--grey-38);
|
||||||
|
--border-form-section-title-color: var(--grey-8);
|
||||||
|
--border-codemirror-cursor-color: var(--white-color);
|
||||||
|
--border-codemirror-gutters-color: var(--grey-26);
|
||||||
|
--border-pre-color: var(--grey-3);
|
||||||
|
--border-blocklist-item-selected-color: var(--grey-38);
|
||||||
|
--border-pagination-color: var(--grey-3);
|
||||||
|
--border-pagination-span-color: var(--grey-3);
|
||||||
|
--border-pagination-hover-color: var(--grey-3);
|
||||||
|
--border-pagination-hover-color: var(--grey-3);
|
||||||
|
--border-multiselect-button-color: var(--grey-3);
|
||||||
|
--border-searchbar-color: var(--grey-1);
|
||||||
|
--border-panel-color: var(--grey-2);
|
||||||
|
--border-daterangepicker-color: var(--grey-3);
|
||||||
|
--border-calendar-table: var(--grey-3);
|
||||||
|
--border-daterangepicker: var(--grey-4);
|
||||||
|
--border-pre-next-month: var(--white-color);
|
||||||
|
--border-daterangepicker-after: var(--grey-3);
|
||||||
|
--border-tooltip-color: var(--grey-3);
|
||||||
|
--border-modal: 0px;
|
||||||
|
|
||||||
|
--hover-sidebar-color: var(--grey-3);
|
||||||
|
--blue-color: var(--blue-2);
|
||||||
|
--button-close-color: var(--white-color);
|
||||||
|
--button-opacity: 0.6;
|
||||||
|
--button-opacity-hover: 0.3;
|
||||||
|
--shadow-box-color: none;
|
||||||
|
--shadow-boxselector-color: none;
|
||||||
|
|
||||||
|
--bg-image-multiselect: linear-gradient(var(--grey-38), var(--grey-38));
|
||||||
|
--bg-image-multiselect-button: linear-gradient(var(--grey-1), var(--grey-1));
|
||||||
|
--bg-image-multiselect-hover: linear-gradient(var(--grey-3), var(--grey-3));
|
||||||
|
--border-multiselect: var(--grey-3);
|
||||||
|
--border-multiselect-checkboxlayer: var(--grey-3);
|
||||||
|
--text-multiselect: var(--white-color);
|
||||||
|
--bg-multiselect-checkboxcontainer: var(--grey-3);
|
||||||
|
--text-multiselect-item: var(--white-color);
|
||||||
|
--bg-multiselect-helpercontainer: var(--grey-1);
|
||||||
|
--text-input-textarea: var(--grey-1);
|
||||||
|
--bg-service-datatable-thead: var(--grey-1);
|
||||||
|
--bg-service-datatable-tbody: var(--grey-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
:root[theme='highcontrast'] {
|
||||||
|
--bg-card-color: var(--black-color);
|
||||||
|
--bg-main-color: var(--black-color);
|
||||||
|
--bg-body-color: var(--black-color);
|
||||||
|
--bg-checkbox-border-color: var(--grey-8);
|
||||||
|
--bg-sidebar-color: var(--black-color);
|
||||||
|
--bg-widget-color: var(--black-color);
|
||||||
|
--bg-widget-header-color: var(--black-color);
|
||||||
|
--bg-widget-table-color: var(--black-color);
|
||||||
|
--bg-header-color: var(--black-color);
|
||||||
|
--bg-hover-table-color: var(--grey-3);
|
||||||
|
--bg-switch-box-color: var(--grey-53);
|
||||||
|
--bg-panel-body-color: var(--black-color);
|
||||||
|
--bg-boxselector-wrapper-disabled-color: var(--grey-39);
|
||||||
|
--bg-dropdown-menu-color: var(--black-color);
|
||||||
|
--bg-codemirror-selected-color: var(--grey-3);
|
||||||
|
--bg-row-header-color: var(--black-color);
|
||||||
|
--bg-sidebar-wrapper-color: var(--black-color);
|
||||||
|
--bg-motd-body-color: var(--black-color);
|
||||||
|
--bg-blocklist-hover-color: var(--black-color);
|
||||||
|
--bg-blocklist-item-selected-color: var(--black-color);
|
||||||
|
--bg-input-group-addon-color: var(--grey-1);
|
||||||
|
--bg-table-color: var(--black-color);
|
||||||
|
--bg-codemirror-gutters-color: var(--black-color);
|
||||||
|
--bg-codemirror-color: var(--black-color);
|
||||||
|
--bg-codemirror-selected-color: var(--grey-3);
|
||||||
|
--bg-log-viewer-color: var(--black-color);
|
||||||
|
--bg-log-line-selected-color: var(--grey-3);
|
||||||
|
--bg-sidebar-header-color: var(--black-color);
|
||||||
|
--bg-modal-content-color: var(--black-color);
|
||||||
|
--bg-form-control-disabled-color: var(--grey-1);
|
||||||
|
--bg-input-sm-color: var(--black-color);
|
||||||
|
--bg-item-highlighted-color: var(--black-color);
|
||||||
|
--bg-service-datatable-thead: var(--black-color);
|
||||||
|
--bg-service-datatable-tbody: var(--black-color);
|
||||||
|
--bg-pagination-color: var(--grey-3);
|
||||||
|
--bg-pagination-span-color: var(--grey-3);
|
||||||
|
--bg-multiselect-color: var(--grey-1);
|
||||||
|
--bg-daterangepicker-color: var(--black-color);
|
||||||
|
--bg-calendar-color: var(--black-color);
|
||||||
|
--bg-calendar-table-color: var(--black-color);
|
||||||
|
--bg-daterangepicker-end-date: var(--grey-3);
|
||||||
|
--bg-daterangepicker-hover: var(--grey-3);
|
||||||
|
--bg-daterangepicker-in-range: var(--grey-2);
|
||||||
|
--bg-daterangepicker-active: var(--blue-14);
|
||||||
|
--bg-tooltip-color: var(--black-color);
|
||||||
|
--bg-table-selected-color: var(--grey-3);
|
||||||
|
--bg-pre-color: var(--grey-2);
|
||||||
|
--bg-navtabs-hover-color: var(--grey-3);
|
||||||
|
--bg-btn-default-color: var(--black-color);
|
||||||
|
--bg-code-color: var(--red-4);
|
||||||
|
--bg-navtabs-color: var(--black-color);
|
||||||
|
--bg-input-autofill-color: var(--black-color);
|
||||||
|
--bg-code-color: var(--grey-2);
|
||||||
|
--bg-navtabs-color: var(--grey-2);
|
||||||
|
--bg-navtabs-hover-color: var(--grey-3);
|
||||||
|
--bg-btn-default-hover-color: var(--grey-3);
|
||||||
|
--bg-btn-default-color: var(--black-color);
|
||||||
|
--bg-btn-focus: var(--black-color);
|
||||||
|
--bg-boxselector-color: var(--black-color);
|
||||||
|
--bg-boxselector-disabled-color: var(--black-color);
|
||||||
|
--bg-small-select-color: var(--black-color);
|
||||||
|
|
||||||
|
--text-main-color: var(--white-color);
|
||||||
|
--text-body-color: var(--white-color);
|
||||||
|
--text-sidebar-title-color: var(--grey-8);
|
||||||
|
--text-widget-header-color: var(--white-color);
|
||||||
|
--text-link-color: var(--blue-9);
|
||||||
|
--text-link-hover-color: var(--blue-9);
|
||||||
|
--text-danger-color: var(--red-7);
|
||||||
|
--text-code-color: var(--red-7);
|
||||||
|
--text-form-control-color: var(--white-color);
|
||||||
|
--text-blocklist-hover-color: var(--blue-11);
|
||||||
|
--text-boxselector-wrapper-color: var(--white-color);
|
||||||
|
--text-dashboard-item-color: var(--blue-12);
|
||||||
|
--text-form-section-title-color: var(--white-color);
|
||||||
|
--text-muted-color: var(--white-color);
|
||||||
|
--text-tooltip-color: var(--white-color);
|
||||||
|
--text-blocklist-item-selected-color: var(--blue-9);
|
||||||
|
--text-input-group-addon-color: var(--white-color);
|
||||||
|
--text-codemirror-color: var(--white-color);
|
||||||
|
--text-log-viewer-color: var(--white-color);
|
||||||
|
--text-summary-color: var(--white-color);
|
||||||
|
--text-rzslider-color: var(--white-color);
|
||||||
|
--text-rzslider-limit-color: var(--white-color);
|
||||||
|
--text-pagination-color: var(--white-color);
|
||||||
|
--text-daterangepicker-end-date: var(--grey-7);
|
||||||
|
--text-daterangepicker-in-range: var(--white-color);
|
||||||
|
--text-daterangepicker-active: var(--white-color);
|
||||||
|
--text-sidebar-list-color: var(--white-color);
|
||||||
|
--text-ui-select-color: var(--white-color);
|
||||||
|
--text-btn-default-color: var(--white-color);
|
||||||
|
--text-json-tree-color: var(--white-color);
|
||||||
|
--text-json-tree-leaf-color: var(--white-color);
|
||||||
|
--text-json-tree-branch-preview-color: var(--white-color);
|
||||||
|
--text-pre-color: var(--white-color);
|
||||||
|
--text-navtabs-color: var(--white-color);
|
||||||
|
--text-input-autofill-color: var(--white-color);
|
||||||
|
--text-navtabs-color: var(--white-color);
|
||||||
|
--text-button-hover-color: var(--white-color);
|
||||||
|
--text-btn-default-color: var(--white-color);
|
||||||
|
--text-small-select-color: var(--white-color);
|
||||||
|
|
||||||
|
--border-color: var(--grey-55);
|
||||||
|
--border-widget-color: var(--white-color);
|
||||||
|
--border-sidebar-color: var(--blue-9);
|
||||||
|
--border-form-control-color: var(--grey-54);
|
||||||
|
--border-table-color: var(--grey-55);
|
||||||
|
--border-table-top-color: var(--grey-55);
|
||||||
|
--border-datatable-top-color: var(--grey-55);
|
||||||
|
--border-sidebar-high-contrast: 1px solid var(--blue-9);
|
||||||
|
--border-code-high-contrast: 1px solid var(--white-color);
|
||||||
|
--border-boxselector-wrapper: 3px solid var(--blue-2);
|
||||||
|
--border-boxselector-wrapper-hover: 3px solid var(--blue-8);
|
||||||
|
--border-panel-color: var(--white-color);
|
||||||
|
--border-input-group-addon-color: var(--grey-54);
|
||||||
|
--border-modal-header-color: var(--grey-3);
|
||||||
|
--border-input-sm-color: var(--white-color);
|
||||||
|
--border-pagination-color: var(--grey-3);
|
||||||
|
--border-pagination-span-color: var(--grey-3);
|
||||||
|
--border-daterangepicker-color: var(--white-color);
|
||||||
|
--border-calendar-table: var(--black-color);
|
||||||
|
--border-daterangepicker: var(--black-color);
|
||||||
|
--border-pre-next-month: var(--white-color);
|
||||||
|
--border-daterangepicker-after: var(--black-color);
|
||||||
|
--border-tooltip-color: var(--white-color);
|
||||||
|
--border-pre-color: var(--grey-3);
|
||||||
|
--border-codemirror-cursor-color: var(--white-color);
|
||||||
|
--border-modal: 1px solid var(--white-color);
|
||||||
|
|
||||||
|
--hover-sidebar-color: var(--blue-9);
|
||||||
|
--hover-sidebar-color: var(--black-color);
|
||||||
|
--shadow-box-color: none;
|
||||||
|
--shadow-boxselector-color: none;
|
||||||
|
|
||||||
|
--bg-image-multiselect: linear-gradient(var(--black-color), var(--black-color));
|
||||||
|
--bg-image-multiselect-button: linear-gradient(var(--grey-1), var(--grey-1));
|
||||||
|
--bg-image-multiselect-hover: linear-gradient(var(--grey-3), var(--grey-3));
|
||||||
|
--border-multiselect: var(--black-color);
|
||||||
|
--border-multiselect-checkboxlayer: var(--grey-3);
|
||||||
|
--text-multiselect: var(--white-color);
|
||||||
|
--bg-multiselect-checkboxcontainer: var(--grey-3);
|
||||||
|
--text-multiselect-item: var(--white-color);
|
||||||
|
--bg-multiselect-helpercontainer: var(--grey-1);
|
||||||
|
--text-input-textarea: var(--black-color);
|
||||||
|
--bg-item-highlighted-null-color: var(--grey-2);
|
||||||
|
--text-cm-default-color: var(--blue-9);
|
||||||
|
--text-cm-meta-color: var(--white-color);
|
||||||
|
--text-cm-string-color: var(--red-7);
|
||||||
|
--text-progress-bar-color: var(--black-color);
|
||||||
|
}
|
|
@ -0,0 +1,399 @@
|
||||||
|
/* Overide Vendor CSS */
|
||||||
|
.form-control {
|
||||||
|
background-color: var(--bg-main-color) !important;
|
||||||
|
border: 1px solid var(--border-form-control-color);
|
||||||
|
color: var(--text-form-control-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-muted {
|
||||||
|
color: var(--text-muted-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table > thead > tr > th {
|
||||||
|
border-bottom: 2px solid var(--border-table-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-hover > tbody > tr:hover {
|
||||||
|
background-color: var(--bg-hover-table-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.switch i,
|
||||||
|
.bootbox-form .checkbox i {
|
||||||
|
background: var(--bg-switch-box-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table > thead > tr > th,
|
||||||
|
.table > tbody > tr > th,
|
||||||
|
.table > tfoot > tr > th,
|
||||||
|
.table > thead > tr > td,
|
||||||
|
.table > tbody > tr > td,
|
||||||
|
.table > tfoot > tr > td {
|
||||||
|
border-top: 1px solid var(--border-table-top-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--text-link-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover,
|
||||||
|
a:focus {
|
||||||
|
color: var(--text-link-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-group-addon {
|
||||||
|
color: var(--text-input-group-addon-color);
|
||||||
|
background-color: var(--bg-input-group-addon-color);
|
||||||
|
border: 1px solid var(--border-input-group-addon-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-default {
|
||||||
|
color: var(--text-btn-default-color);
|
||||||
|
background-color: var(--bg-btn-default-color);
|
||||||
|
border-color: var(--border-btn-default-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-danger {
|
||||||
|
color: var(--text-danger-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table .table {
|
||||||
|
background-color: var(--bg-table-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-bordered {
|
||||||
|
border-color: var(--border-table-top-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-bordered > thead > tr > th,
|
||||||
|
.table-bordered > tbody > tr > th,
|
||||||
|
.table-bordered > tfoot > tr > th,
|
||||||
|
.table-bordered > thead > tr > td,
|
||||||
|
.table-bordered > tbody > tr > td,
|
||||||
|
.table-bordered > tfoot > tr > td {
|
||||||
|
border-color: var(--border-table-top-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.md-checkbox input[type='checkbox']:disabled + label:before {
|
||||||
|
background: var(--bg-md-checkbox-color) !important;
|
||||||
|
border-color: var(--border-md-checkbox-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control[disabled],
|
||||||
|
.form-control[readonly],
|
||||||
|
fieldset[disabled] .form-control {
|
||||||
|
background-color: var(--bg-form-control-disabled-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal.in .modal-dialog {
|
||||||
|
border: var(--border-modal);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
background-color: var(--bg-modal-content-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
border-bottom: 1px solid var(--border-modal-header-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-footer {
|
||||||
|
border-top: 1px solid var(--border-modal-header-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close {
|
||||||
|
color: var(--button-close-color);
|
||||||
|
opacity: var(--button-opacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
.close:hover,
|
||||||
|
.close:focus {
|
||||||
|
color: var(--button-close-color);
|
||||||
|
opacity: var(--button-opacity-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
code {
|
||||||
|
color: var(--text-code-color);
|
||||||
|
background-color: var(--bg-code-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs > li.active > a,
|
||||||
|
.nav-tabs > li.active > a:hover,
|
||||||
|
.nav-tabs > li.active > a:focus {
|
||||||
|
color: var(--text-navtabs-color);
|
||||||
|
background-color: var(--bg-navtabs-color);
|
||||||
|
border: 1px solid var(--border-navtabs-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs {
|
||||||
|
border-bottom: 1px solid var(--border-navtabs-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs > li > a:hover {
|
||||||
|
border-color: var(--border-navtabs-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav > li > a:hover,
|
||||||
|
.nav > li > a:focus {
|
||||||
|
background-color: var(--bg-navtabs-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.table > thead > tr > td.active,
|
||||||
|
.table > tbody > tr > td.active,
|
||||||
|
.table > tfoot > tr > td.active,
|
||||||
|
.table > thead > tr > th.active,
|
||||||
|
.table > tbody > tr > th.active,
|
||||||
|
.table > tfoot > tr > th.active,
|
||||||
|
.table > thead > tr.active > td,
|
||||||
|
.table > tbody > tr.active > td,
|
||||||
|
.table > tfoot > tr.active > td,
|
||||||
|
.table > thead > tr.active > th,
|
||||||
|
.table > tbody > tr.active > th,
|
||||||
|
.table > tfoot > tr.active > th {
|
||||||
|
background-color: var(--bg-table-selected-color);
|
||||||
|
}
|
||||||
|
.table-hover > tbody > tr > td.active:hover,
|
||||||
|
.table-hover > tbody > tr > th.active:hover,
|
||||||
|
.table-hover > tbody > tr.active:hover > td,
|
||||||
|
.table-hover > tbody > tr:hover > .active,
|
||||||
|
.table-hover > tbody > tr.active:hover > th {
|
||||||
|
background-color: var(--bg-table-selected-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.CodeMirror-gutters {
|
||||||
|
background: var(--bg-codemirror-gutters-color);
|
||||||
|
border-right: 1px solid var(--border-codemirror-gutters-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.CodeMirror {
|
||||||
|
background: var(--bg-codemirror-color);
|
||||||
|
color: var(--text-codemirror-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.CodeMirror-selected {
|
||||||
|
background: var(--bg-codemirror-selected-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.CodeMirror-cursor {
|
||||||
|
border-left: 1px solid var(--border-codemirror-cursor-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-default .cm-atom {
|
||||||
|
color: var(--text-cm-default-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-default .cm-meta {
|
||||||
|
color: var(--text-cm-meta-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-default .cm-string {
|
||||||
|
color: var(--text-cm-string-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cm-s-default .cm-number {
|
||||||
|
color: var(--text-cm-number-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu {
|
||||||
|
background: var(--bg-dropdown-menu-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-menu > li > a {
|
||||||
|
color: var(--text-dropdown-menu-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
pre {
|
||||||
|
border: 1px solid var(--border-pre-color);
|
||||||
|
background-color: var(--bg-pre-color);
|
||||||
|
color: var(--text-pre-color);
|
||||||
|
}
|
||||||
|
json-tree .key {
|
||||||
|
color: var(--text-json-tree-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
json-tree .leaf-value {
|
||||||
|
color: var(--text-json-tree-leaf-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
json-tree .branch-preview {
|
||||||
|
color: var(--text-json-tree-branch-preview-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.progress {
|
||||||
|
background-color: var(--bg-progress-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination > .disabled > span,
|
||||||
|
.pagination > .disabled > span:hover,
|
||||||
|
.pagination > .disabled > span:focus,
|
||||||
|
.pagination > .disabled > a,
|
||||||
|
.pagination > .disabled > a:hover,
|
||||||
|
.pagination > .disabled > a:focus {
|
||||||
|
color: var(--text-pagination-color);
|
||||||
|
background-color: var(--bg-pagination-color);
|
||||||
|
border-color: var(--border-pagination-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination > li > a,
|
||||||
|
.pagination > li > span {
|
||||||
|
background-color: var(--bg-pagination-span-color);
|
||||||
|
border-color: var(--border-pagination-span-color);
|
||||||
|
color: var(--text-pagination-span-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination > li > a:hover,
|
||||||
|
.pagination > li > span:hover,
|
||||||
|
.pagination > li > a:focus,
|
||||||
|
.pagination > li > span:focus {
|
||||||
|
background-color: var(--bg-pagination-hover-color);
|
||||||
|
border-color: var(--border-pagination-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.pagination > li > a:hover,
|
||||||
|
.pagination > li > span:hover,
|
||||||
|
.pagination > li > a:focus,
|
||||||
|
.pagination > li > span:focus {
|
||||||
|
color: var(--text-pagination-span-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-select-bootstrap .ui-select-choices-row > span {
|
||||||
|
color: var(--text-ui-select-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-select-bootstrap .ui-select-choices-row > span:hover,
|
||||||
|
.ui-select-bootstrap .ui-select-choices-row > span:focus {
|
||||||
|
background-color: var(--bg-ui-select-hover-color);
|
||||||
|
color: var(--text-ui-select-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.motd-body {
|
||||||
|
background-color: var(--bg-motd-body-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-body {
|
||||||
|
background-color: var(--bg-panel-body-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel {
|
||||||
|
border: 1px solid var(--border-panel-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-information .col-sm-12 {
|
||||||
|
padding-left: 0px;
|
||||||
|
padding-right: 0px;
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.theme-panel {
|
||||||
|
margin-top: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.summary {
|
||||||
|
color: var(--text-summary-color);
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-sm {
|
||||||
|
background-color: var(--bg-input-sm-color);
|
||||||
|
border: 1px solid var(--border-input-sm-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rzslider .rz-bubble {
|
||||||
|
color: var(--text-rzslider-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.rzslider .rz-bubble.rz-limit {
|
||||||
|
color: var(--text-rzslider-limit-color);
|
||||||
|
}
|
||||||
|
input,
|
||||||
|
button,
|
||||||
|
select,
|
||||||
|
textarea {
|
||||||
|
background: var(--text-input-textarea);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker {
|
||||||
|
background-color: var(--bg-daterangepicker-color);
|
||||||
|
border: 1px solid var(--border-daterangepicker-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker .drp-calendar.left {
|
||||||
|
background: var(--bg-calendar-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker .drp-calendar.left .calendar-table {
|
||||||
|
background: var(--bg-calendar-table-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker .drp-calendar.right {
|
||||||
|
background: var(--bg-calendar-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker .drp-calendar.right .calendar-table {
|
||||||
|
background: var(--bg-calendar-table-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker .calendar-table {
|
||||||
|
border: 1px solid var(--border-calendar-table);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker td.off,
|
||||||
|
.daterangepicker td.off.in-range,
|
||||||
|
.daterangepicker td.off.start-date,
|
||||||
|
.daterangepicker td.off.end-date {
|
||||||
|
background-color: var(--bg-daterangepicker-end-date);
|
||||||
|
color: var(--text-daterangepicker-end-date);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker td.available:hover,
|
||||||
|
.daterangepicker th.available:hover {
|
||||||
|
background-color: var(--bg-daterangepicker-hover);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker td.in-range {
|
||||||
|
background-color: var(--bg-daterangepicker-in-range);
|
||||||
|
color: var(--text-daterangepicker-in-range);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker td.active,
|
||||||
|
.daterangepicker td.active:hover {
|
||||||
|
background-color: var(--bg-daterangepicker-active);
|
||||||
|
color: var(--text-daterangepicker-active);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker .drp-buttons {
|
||||||
|
border-top: 1px solid var(--border-daterangepicker);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker .calendar-table .next span,
|
||||||
|
.daterangepicker .calendar-table .prev span {
|
||||||
|
border-color: var(--border-pre-next-month);
|
||||||
|
}
|
||||||
|
|
||||||
|
.daterangepicker:after {
|
||||||
|
border-bottom: 6px solid var(--border-daterangepicker-after);
|
||||||
|
}
|
||||||
|
|
||||||
|
input:-webkit-autofill,
|
||||||
|
input:-webkit-autofill:hover,
|
||||||
|
input:-webkit-autofill:focus,
|
||||||
|
input:-webkit-autofill:active {
|
||||||
|
-webkit-box-shadow: 0 0 0 30px var(--bg-input-autofill-color) inset !important;
|
||||||
|
box-shadow: 0 0 0 30px var(--bg-input-autofill-color) inset !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:-webkit-autofill {
|
||||||
|
-webkit-text-fill-color: var(--text-input-autofill-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn:hover {
|
||||||
|
color: var(--text-button-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-default:hover {
|
||||||
|
background-color: var(--bg-btn-default-hover-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-primary:hover {
|
||||||
|
color: var(--white-color) !important;
|
||||||
|
}
|
||||||
|
/* Overide Vendor CSS */
|
|
@ -73,7 +73,11 @@
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr dir-paginate-end ng-show="$ctrl.itemCanExpand(value) && value.Expanded" ng-style="{ background: value.Highlighted ? '#d5e8f3' : '#f5f5f5' }">
|
<tr
|
||||||
|
dir-paginate-end
|
||||||
|
ng-show="$ctrl.itemCanExpand(value) && value.Expanded"
|
||||||
|
ng-class="{ 'datatable-highlighted': value.Highlighted, 'datatable-unhighlighted': !value.Highlighted }"
|
||||||
|
>
|
||||||
<td colspan="1"></td>
|
<td colspan="1"></td>
|
||||||
<td colspan="1">
|
<td colspan="1">
|
||||||
{{ value.GlobalIPv6Address }}
|
{{ value.GlobalIPv6Address }}
|
||||||
|
|
|
@ -171,7 +171,7 @@
|
||||||
allow-checkbox="true"
|
allow-checkbox="true"
|
||||||
>
|
>
|
||||||
</tr>
|
</tr>
|
||||||
<tr dir-paginate-end ng-show="item.Expanded" ng-repeat="it in item.Subs" style="background: #d5e8f3;" network-row-content item="it" parent-ctrl="$ctrl"> </tr>
|
<tr dir-paginate-end ng-show="item.Expanded" ng-repeat="it in item.Subs" class="datatable-highlighted" network-row-content item="it" parent-ctrl="$ctrl"> </tr>
|
||||||
<tr ng-if="!$ctrl.dataset">
|
<tr ng-if="!$ctrl.dataset">
|
||||||
<td colspan="9" class="text-center text-muted">Loading...</td>
|
<td colspan="9" class="text-center text-muted">Loading...</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<div style="background-color: #d5e8f3; padding: 2px;">
|
<div class="service-datatable">
|
||||||
<table class="table table-condensed table-hover nowrap-cells">
|
<table class="table table-condensed table-hover nowrap-cells">
|
||||||
<thead style="background-color: #e7f6ff;">
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th uib-dropdown dropdown-append-to-body auto-close="disabled" is-open="$ctrl.filters.state.open" style="width: 10%;">
|
<th uib-dropdown dropdown-append-to-body auto-close="disabled" is-open="$ctrl.filters.state.open" style="width: 10%;">
|
||||||
<a ng-click="$ctrl.changeOrderBy('Status.State')">
|
<a ng-click="$ctrl.changeOrderBy('Status.State')">
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody style="background-color: #f1f9fd;">
|
<tbody>
|
||||||
<tr
|
<tr
|
||||||
ng-repeat="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter: $ctrl.applyFilters | filter:$ctrl.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder))"
|
ng-repeat="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter: $ctrl.applyFilters | filter:$ctrl.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder))"
|
||||||
>
|
>
|
||||||
|
|
|
@ -105,8 +105,7 @@
|
||||||
<!-- dir-paginate-start track by $index -->
|
<!-- dir-paginate-start track by $index -->
|
||||||
<tr
|
<tr
|
||||||
dir-paginate-start="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | filter: $ctrl.isDisplayed | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit: $ctrl.tableKey))"
|
dir-paginate-start="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | filter: $ctrl.isDisplayed | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit: $ctrl.tableKey))"
|
||||||
ng-class="{ active: item.Checked }"
|
ng-class="{ active: item.Checked, 'datatable-highlighted': item.Highlighted }"
|
||||||
ng-style="{ background: item.Highlighted ? '#d5e8f3' : '' }"
|
|
||||||
ng-click="$ctrl.expandItem(item, !item.Expanded)"
|
ng-click="$ctrl.expandItem(item, !item.Expanded)"
|
||||||
pagination-id="$ctrl.tableKey"
|
pagination-id="$ctrl.tableKey"
|
||||||
>
|
>
|
||||||
|
@ -177,7 +176,7 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- sub rows -->
|
<!-- sub rows -->
|
||||||
<tr ng-show="item.Expanded" ng-repeat-start="port in item.Ports" ng-style="{ background: item.Highlighted ? '#d5e8f3' : '#f5f5f5' }">
|
<tr ng-show="item.Expanded" ng-repeat-start="port in item.Ports" ng-class="{ 'datatable-highlighted': item.Highlighted, 'datatable-unhighlighted': !item.Highlighted }">
|
||||||
<td ng-if="!$ctrl.portHasIngressRules(port)"></td>
|
<td ng-if="!$ctrl.portHasIngressRules(port)"></td>
|
||||||
<td ng-if="!$ctrl.portHasIngressRules(port)">-</td>
|
<td ng-if="!$ctrl.portHasIngressRules(port)">-</td>
|
||||||
<td ng-if="!$ctrl.portHasIngressRules(port)">-</td>
|
<td ng-if="!$ctrl.portHasIngressRules(port)">-</td>
|
||||||
|
@ -190,7 +189,12 @@
|
||||||
<td ng-if="!$ctrl.portHasIngressRules(port)">{{ port.TargetPort }}/{{ port.Protocol }}</td>
|
<td ng-if="!$ctrl.portHasIngressRules(port)">{{ port.TargetPort }}/{{ port.Protocol }}</td>
|
||||||
<td ng-if="!$ctrl.portHasIngressRules(port)">-</td>
|
<td ng-if="!$ctrl.portHasIngressRules(port)">-</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr ng-show="item.Expanded" ng-repeat-end ng-repeat="rule in port.IngressRules" ng-style="{ background: item.Highlighted ? '#d5e8f3' : '#f5f5f5' }">
|
<tr
|
||||||
|
ng-show="item.Expanded"
|
||||||
|
ng-repeat-end
|
||||||
|
ng-repeat="rule in port.IngressRules"
|
||||||
|
ng-class="{ 'datatable-highlighted': item.Highlighted, 'datatable-unhighlighted': !item.Highlighted }"
|
||||||
|
>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>-</td>
|
<td>-</td>
|
||||||
<td>-</td>
|
<td>-</td>
|
||||||
|
|
|
@ -109,8 +109,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr
|
<tr
|
||||||
dir-paginate-start="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | filter: $ctrl.isDisplayed | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit: $ctrl.tableKey))"
|
dir-paginate-start="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | filter: $ctrl.isDisplayed | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit: $ctrl.tableKey))"
|
||||||
ng-class="{ active: item.Checked }"
|
ng-class="{ active: item.Checked, 'datatable-highlighted': item.Highlighted }"
|
||||||
ng-style="{ background: item.Highlighted ? '#d5e8f3' : '' }"
|
|
||||||
ng-click="$ctrl.expandItem(item, !item.Expanded)"
|
ng-click="$ctrl.expandItem(item, !item.Expanded)"
|
||||||
pagination-id="$ctrl.tableKey"
|
pagination-id="$ctrl.tableKey"
|
||||||
>
|
>
|
||||||
|
@ -141,7 +140,12 @@
|
||||||
<a ui-sref="kubernetes.stacks.stack.logs({ namespace: item.ResourcePool, name: item.Name })"> <i class="fa fa-file-alt" aria-hidden="true"></i> Logs </a>
|
<a ui-sref="kubernetes.stacks.stack.logs({ namespace: item.ResourcePool, name: item.Name })"> <i class="fa fa-file-alt" aria-hidden="true"></i> Logs </a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr dir-paginate-end ng-show="item.Expanded" ng-repeat="app in item.Applications" ng-style="{ background: item.Highlighted ? '#d5e8f3' : '#f5f5f5' }">
|
<tr
|
||||||
|
dir-paginate-end
|
||||||
|
ng-show="item.Expanded"
|
||||||
|
ng-repeat="app in item.Applications"
|
||||||
|
ng-class="{ 'datatable-highlighted': item.Highlighted, 'datatable-unhighlighted': !item.Highlighted }"
|
||||||
|
>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td colspan="4">
|
<td colspan="4">
|
||||||
<a ui-sref="kubernetes.applications.application({ name: app.Name, namespace: app.ResourcePool })">{{ app.Name }}</a>
|
<a ui-sref="kubernetes.applications.application({ name: app.Name, namespace: app.ResourcePool })">{{ app.Name }}</a>
|
||||||
|
|
|
@ -2,9 +2,10 @@ import KubernetesNamespaceHelper from 'Kubernetes/helpers/namespaceHelper';
|
||||||
|
|
||||||
export default class KubernetesRegistryAccessController {
|
export default class KubernetesRegistryAccessController {
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
constructor($async, $state, EndpointService, Notifications, KubernetesResourcePoolService) {
|
constructor($async, $state, ModalService, EndpointService, Notifications, KubernetesResourcePoolService) {
|
||||||
this.$async = $async;
|
this.$async = $async;
|
||||||
this.$state = $state;
|
this.$state = $state;
|
||||||
|
this.ModalService = ModalService;
|
||||||
this.Notifications = Notifications;
|
this.Notifications = Notifications;
|
||||||
this.KubernetesResourcePoolService = KubernetesResourcePoolService;
|
this.KubernetesResourcePoolService = KubernetesResourcePoolService;
|
||||||
this.EndpointService = EndpointService;
|
this.EndpointService = EndpointService;
|
||||||
|
@ -26,8 +27,15 @@ export default class KubernetesRegistryAccessController {
|
||||||
|
|
||||||
handleRemove(namespaces) {
|
handleRemove(namespaces) {
|
||||||
const removeNamespaces = namespaces.map(({ value }) => value);
|
const removeNamespaces = namespaces.map(({ value }) => value);
|
||||||
|
const nsToUpdate = this.savedResourcePools.map(({ value }) => value).filter((value) => !removeNamespaces.includes(value));
|
||||||
|
|
||||||
return this.updateNamespaces(this.savedResourcePools.map(({ value }) => value).filter((value) => !removeNamespaces.includes(value)));
|
const displayedMessage =
|
||||||
|
'This registry might be used by one or more applications inside this environment. Removing the registry access could lead to a service interruption for these applications.<br/><br/>Do you wish to continue?';
|
||||||
|
this.ModalService.confirmDeletion(displayedMessage, (confirmed) => {
|
||||||
|
if (confirmed) {
|
||||||
|
return this.updateNamespaces(nsToUpdate);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
updateNamespaces(namespaces) {
|
updateNamespaces(namespaces) {
|
||||||
|
|
|
@ -75,8 +75,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr
|
<tr
|
||||||
dir-paginate-start="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | filter: $ctrl.isDisplayed | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit: $ctrl.tableKey))"
|
dir-paginate-start="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | filter: $ctrl.isDisplayed | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit: $ctrl.tableKey))"
|
||||||
ng-class="{ active: item.Checked }"
|
ng-class="{ active: item.Checked, 'datatable-highlighted': item.Highlighted }"
|
||||||
ng-style="{ background: item.Highlighted ? '#d5e8f3' : '' }"
|
|
||||||
ng-click="$ctrl.expandItem(item, !item.Expanded)"
|
ng-click="$ctrl.expandItem(item, !item.Expanded)"
|
||||||
pagination-id="$ctrl.tableKey"
|
pagination-id="$ctrl.tableKey"
|
||||||
>
|
>
|
||||||
|
@ -92,14 +91,23 @@
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- ADMIN + UNMET TAINTS -->
|
<!-- ADMIN + UNMET TAINTS -->
|
||||||
<tr ng-if="$ctrl.isAdmin" ng-show="item.Expanded" ng-repeat="taint in item.UnmetTaints" ng-style="{ background: item.Highlighted ? '#d5e8f3' : '#f5f5f5' }">
|
<tr
|
||||||
|
ng-if="$ctrl.isAdmin"
|
||||||
|
ng-show="item.Expanded"
|
||||||
|
ng-repeat="taint in item.UnmetTaints"
|
||||||
|
ng-class="{ 'datatable-highlighted': item.Highlighted, 'datatable-unhighlighted': !item.Highlighted }"
|
||||||
|
>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
This application is missing a toleration for the taint <code>{{ taint.Key }}{{ taint.Value ? '=' + taint.Value : '' }}:{{ taint.Effect }}</code>
|
This application is missing a toleration for the taint <code>{{ taint.Key }}{{ taint.Value ? '=' + taint.Value : '' }}:{{ taint.Effect }}</code>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!-- !ADMIN + UNMET TAINTS -->
|
<!-- !ADMIN + UNMET TAINTS -->
|
||||||
<!-- USER + UNMET TAINTS -->
|
<!-- USER + UNMET TAINTS -->
|
||||||
<tr ng-if="!$ctrl.isAdmin && item.UnmetTaints.length" ng-show="item.Expanded" ng-style="{ background: item.Highlighted ? '#d5e8f3' : '#f5f5f5' }">
|
<tr
|
||||||
|
ng-if="!$ctrl.isAdmin && item.UnmetTaints.length"
|
||||||
|
ng-show="item.Expanded"
|
||||||
|
ng-class="{ 'datatable-highlighted': item.Highlighted, 'datatable-unhighlighted': !item.Highlighted }"
|
||||||
|
>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
Placement constraint not respected for that node.
|
Placement constraint not respected for that node.
|
||||||
</td>
|
</td>
|
||||||
|
@ -110,7 +118,7 @@
|
||||||
ng-if="$ctrl.isAdmin"
|
ng-if="$ctrl.isAdmin"
|
||||||
ng-show="item.Expanded"
|
ng-show="item.Expanded"
|
||||||
ng-repeat="label in item.UnmatchedNodeSelectorLabels"
|
ng-repeat="label in item.UnmatchedNodeSelectorLabels"
|
||||||
ng-style="{ background: item.Highlighted ? '#d5e8f3' : '#f5f5f5' }"
|
ng-class="{ 'datatable-highlighted': item.Highlighted, 'datatable-unhighlighted': !item.Highlighted }"
|
||||||
>
|
>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
This application can only be scheduled on a node where the label <code>{{ label.key }}</code> is set to <code>{{ label.value }}</code>
|
This application can only be scheduled on a node where the label <code>{{ label.key }}</code> is set to <code>{{ label.value }}</code>
|
||||||
|
@ -121,7 +129,7 @@
|
||||||
<tr
|
<tr
|
||||||
ng-if="!$ctrl.isAdmin && (item.UnmatchedNodeSelectorLabels.length || item.UnmatchedNodeAffinities.length)"
|
ng-if="!$ctrl.isAdmin && (item.UnmatchedNodeSelectorLabels.length || item.UnmatchedNodeAffinities.length)"
|
||||||
ng-show="item.Expanded"
|
ng-show="item.Expanded"
|
||||||
ng-style="{ background: item.Highlighted ? '#d5e8f3' : '#f5f5f5' }"
|
ng-class="{ 'datatable-highlighted': item.Highlighted, 'datatable-unhighlighted': !item.Highlighted }"
|
||||||
>
|
>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
Placement label not respected for that node.
|
Placement label not respected for that node.
|
||||||
|
@ -129,7 +137,11 @@
|
||||||
</tr>
|
</tr>
|
||||||
<!-- ! USER + UNMET NODE SELECTOR LABELS || UNMET NODE AFFINITIES -->
|
<!-- ! USER + UNMET NODE SELECTOR LABELS || UNMET NODE AFFINITIES -->
|
||||||
<!-- ADMIN + UNMET NODE AFFINITIES -->
|
<!-- ADMIN + UNMET NODE AFFINITIES -->
|
||||||
<tr ng-if="$ctrl.isAdmin" ng-show="item.Expanded && item.UnmatchedNodeAffinities.length" ng-style="{ background: item.Highlighted ? '#d5e8f3' : '#f5f5f5' }">
|
<tr
|
||||||
|
ng-if="$ctrl.isAdmin"
|
||||||
|
ng-show="item.Expanded && item.UnmatchedNodeAffinities.length"
|
||||||
|
ng-class="{ 'datatable-highlighted': item.Highlighted, 'datatable-unhighlighted': !item.Highlighted }"
|
||||||
|
>
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
This application can only be scheduled on nodes respecting one of the following labels combination:
|
This application can only be scheduled on nodes respecting one of the following labels combination:
|
||||||
</td>
|
</td>
|
||||||
|
@ -139,7 +151,7 @@
|
||||||
ng-if="$ctrl.isAdmin"
|
ng-if="$ctrl.isAdmin"
|
||||||
ng-show="item.Expanded"
|
ng-show="item.Expanded"
|
||||||
ng-repeat="aff in item.UnmatchedNodeAffinities"
|
ng-repeat="aff in item.UnmatchedNodeAffinities"
|
||||||
ng-style="{ background: item.Highlighted ? '#d5e8f3' : '#f5f5f5' }"
|
ng-class="{ 'datatable-highlighted': item.Highlighted, 'datatable-unhighlighted': !item.Highlighted }"
|
||||||
>
|
>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<kubernetes-view-header title="Create a namespace" state="kubernetes.resourcePools.new" view-ready="ctrl.state.viewReady">
|
<kubernetes-view-header title="Create a namespace" state="kubernetes.resourcePools.new" view-ready="$ctrl.state.viewReady">
|
||||||
<a ui-sref="kubernetes.resourcePools">Namespaces</a> > Create a namespace
|
<a ui-sref="kubernetes.resourcePools">Namespaces</a> > Create a namespace
|
||||||
</kubernetes-view-header>
|
</kubernetes-view-header>
|
||||||
|
|
||||||
|
|
|
@ -73,8 +73,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr
|
<tr
|
||||||
dir-paginate-start="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit: $ctrl.tableKey))"
|
dir-paginate-start="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit: $ctrl.tableKey))"
|
||||||
ng-class="{ active: item.Checked }"
|
ng-class="{ active: item.Checked, 'datatable-highlighted': item.Highlighted }"
|
||||||
ng-style="{ background: item.Highlighted ? '#d5e8f3' : '' }"
|
|
||||||
ng-click="$ctrl.expandItem(item, !item.Expanded)"
|
ng-click="$ctrl.expandItem(item, !item.Expanded)"
|
||||||
pagination-id="$ctrl.tableKey"
|
pagination-id="$ctrl.tableKey"
|
||||||
>
|
>
|
||||||
|
@ -84,7 +83,12 @@
|
||||||
>{{ item.Name }}
|
>{{ item.Name }}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr dir-paginate-end ng-show="item.Expanded" ng-repeat="path in item.Paths" ng-style="{ background: item.Highlighted ? '#d5e8f3' : '#f5f5f5' }">
|
<tr
|
||||||
|
dir-paginate-end
|
||||||
|
ng-show="item.Expanded"
|
||||||
|
ng-repeat="path in item.Paths"
|
||||||
|
ng-class="{ 'datatable-highlighted': item.Highlighted, 'datatable-unhighlighted': !item.Highlighted }"
|
||||||
|
>
|
||||||
<td>
|
<td>
|
||||||
<a style="margin-left: 15px;" ng-href="http://{{ path.Host ? path.Host : path.IP }}{{ path.Path }}" target="_blank">
|
<a style="margin-left: 15px;" ng-href="http://{{ path.Host ? path.Host : path.IP }}{{ path.Path }}" target="_blank">
|
||||||
{{ path.Host ? path.Host : path.IP }}{{ path.Path }}
|
{{ path.Host ? path.Host : path.IP }}{{ path.Path }}
|
||||||
|
|
|
@ -185,20 +185,26 @@ class KubernetesResourcePoolController {
|
||||||
}
|
}
|
||||||
|
|
||||||
updateResourcePool() {
|
updateResourcePool() {
|
||||||
const willBeDeleted = _.filter(this.formValues.IngressClasses, { WasSelected: true, Selected: false });
|
const ingressesToDelete = _.filter(this.formValues.IngressClasses, { WasSelected: true, Selected: false });
|
||||||
|
const registriesToDelete = _.filter(this.registries, { WasChecked: true, Checked: false });
|
||||||
const warnings = {
|
const warnings = {
|
||||||
quota: this.hasResourceQuotaBeenReduced(),
|
quota: this.hasResourceQuotaBeenReduced(),
|
||||||
ingress: willBeDeleted.length !== 0,
|
ingress: ingressesToDelete.length !== 0,
|
||||||
|
registries: registriesToDelete.length !== 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (warnings.quota || warnings.ingress) {
|
if (warnings.quota || warnings.ingress || warnings.registries) {
|
||||||
const messages = {
|
const messages = {
|
||||||
quota:
|
quota:
|
||||||
'Reducing the quota assigned to an "in-use" namespace may have unintended consequences, including preventing running applications from functioning correctly and potentially even blocking them from running at all.',
|
'Reducing the quota assigned to an "in-use" namespace may have unintended consequences, including preventing running applications from functioning correctly and potentially even blocking them from running at all.',
|
||||||
ingress: 'Deactivating ingresses may cause applications to be unaccessible. All ingress configurations from affected applications will be removed.',
|
ingress: 'Deactivating ingresses may cause applications to be unaccessible. All ingress configurations from affected applications will be removed.',
|
||||||
|
registries:
|
||||||
|
'Some registries you removed might be used by one or more applications inside this environment. Removing the registries access could lead to a service interruption for these applications.',
|
||||||
};
|
};
|
||||||
const displayedMessage = `${warnings.quota ? messages.quota : ''}${warnings.quota && warnings.ingress ? '<br/><br/>' : ''}
|
const displayedMessage = `${warnings.quota ? messages.quota + '<br/><br/>' : ''}
|
||||||
${warnings.ingress ? messages.ingress : ''}<br/><br/>Do you wish to continue?`;
|
${warnings.ingress ? messages.ingress + '<br/><br/>' : ''}
|
||||||
|
${warnings.registries ? messages.registries + '<br/><br/>' : ''}
|
||||||
|
Do you wish to continue?`;
|
||||||
this.ModalService.confirmUpdate(displayedMessage, (confirmed) => {
|
this.ModalService.confirmUpdate(displayedMessage, (confirmed) => {
|
||||||
if (confirmed) {
|
if (confirmed) {
|
||||||
return this.$async(this.updateResourcePoolAsync, this.savedFormValues, this.formValues);
|
return this.$async(this.updateResourcePoolAsync, this.savedFormValues, this.formValues);
|
||||||
|
@ -322,6 +328,7 @@ class KubernetesResourcePoolController {
|
||||||
this.registries.forEach((reg) => {
|
this.registries.forEach((reg) => {
|
||||||
if (reg.RegistryAccesses && reg.RegistryAccesses[this.endpoint.Id] && reg.RegistryAccesses[this.endpoint.Id].Namespaces.includes(namespace)) {
|
if (reg.RegistryAccesses && reg.RegistryAccesses[this.endpoint.Id] && reg.RegistryAccesses[this.endpoint.Id].Namespaces.includes(namespace)) {
|
||||||
reg.Checked = true;
|
reg.Checked = true;
|
||||||
|
reg.WasChecked = true;
|
||||||
this.formValues.Registries.push(reg);
|
this.formValues.Registries.push(reg);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
<li ng-repeat="summary in $ctrl.state.resources" ng-if="summary.action && summary.kind && summary.name">
|
<li ng-repeat="summary in $ctrl.state.resources" ng-if="summary.action && summary.kind && summary.name">
|
||||||
{{ summary.action }}
|
{{ summary.action }}
|
||||||
{{ $ctrl.getArticle(summary.kind, summary.action) }}
|
{{ $ctrl.getArticle(summary.kind, summary.action) }}
|
||||||
<span style="color: black; font-weight: 700;">{{ summary.kind }}</span> named <code>{{ summary.name }}</code>
|
<span class="summary">{{ summary.kind }}</span> named <code>{{ summary.name }}</code>
|
||||||
<span ng-if="summary.type">
|
<span ng-if="summary.type">
|
||||||
of type <code>{{ summary.type }}</code></span
|
of type <code>{{ summary.type }}</code></span
|
||||||
>
|
>
|
||||||
|
|
|
@ -82,8 +82,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr
|
<tr
|
||||||
dir-paginate-start="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit: $ctrl.tableKey))"
|
dir-paginate-start="item in ($ctrl.state.filteredDataSet = ($ctrl.dataset | filter:$ctrl.state.textFilter | orderBy:$ctrl.state.orderBy:$ctrl.state.reverseOrder | itemsPerPage: $ctrl.state.paginatedItemLimit: $ctrl.tableKey))"
|
||||||
ng-class="{ active: item.Checked }"
|
ng-class="{ active: item.Checked, 'datatable-highlighted': item.Highlighted }"
|
||||||
ng-style="{ background: item.Highlighted ? '#d5e8f3' : '' }"
|
|
||||||
ng-click="$ctrl.expandItem(item, !item.Expanded)"
|
ng-click="$ctrl.expandItem(item, !item.Expanded)"
|
||||||
pagination-id="$ctrl.tableKey"
|
pagination-id="$ctrl.tableKey"
|
||||||
>
|
>
|
||||||
|
@ -95,7 +94,12 @@
|
||||||
<td>{{ item.Name }}</td>
|
<td>{{ item.Name }}</td>
|
||||||
<td>{{ item.Size }}</td>
|
<td>{{ item.Size }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr dir-paginate-end ng-show="item.Expanded" ng-repeat="vol in item.Volumes" ng-style="{ background: item.Highlighted ? '#d5e8f3' : '#f5f5f5' }">
|
<tr
|
||||||
|
dir-paginate-end
|
||||||
|
ng-show="item.Expanded"
|
||||||
|
ng-repeat="vol in item.Volumes"
|
||||||
|
ng-class="{ 'datatable-highlighted': item.Highlighted, 'datatable-unhighlighted': !item.Highlighted }"
|
||||||
|
>
|
||||||
<td></td>
|
<td></td>
|
||||||
<td>
|
<td>
|
||||||
<a ui-sref="kubernetes.volumes.volume({ name: vol.PersistentVolumeClaim.Name, namespace: vol.PersistentVolumeClaim.Namespace })">
|
<a ui-sref="kubernetes.volumes.volume({ name: vol.PersistentVolumeClaim.Name, namespace: vol.PersistentVolumeClaim.Namespace })">
|
||||||
|
|
|
@ -27,22 +27,27 @@
|
||||||
|
|
||||||
.boxselector_wrapper input[type='radio']:not(:disabled) ~ label {
|
.boxselector_wrapper input[type='radio']:not(:disabled) ~ label {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
background-color: var(--bg-boxselector-wrapper-disabled-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.boxselector_wrapper input[type='radio']:not(:disabled):hover ~ label:hover {
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.boxselector_wrapper label {
|
.boxselector_wrapper label {
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
display: block;
|
display: block;
|
||||||
background: white;
|
background: var(--bg-boxselector-color);
|
||||||
border: 1px solid #333333;
|
border: 1px solid var(--border-boxselector-color);
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
padding: 10px 10px 0 10px;
|
padding: 10px 10px 0 10px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
box-shadow: 0 3px 10px -2px rgba(161, 170, 166, 0.5);
|
box-shadow: var(--shadow-boxselector-color);
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
.boxselector_wrapper label.boxselector_disabled {
|
.boxselector_wrapper label.boxselector_disabled {
|
||||||
background: #cacaca;
|
background: var(--bg-boxselector-disabled-color) !important;
|
||||||
border-color: #787878;
|
border-color: #787878;
|
||||||
color: #787878;
|
color: #787878;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<button type="button" class="btn btn-sm btn-primary" ui-state="$ctrl.createPath"> <i class="fa fa-plus space-right" aria-hidden="true"></i>Add Custom Template </button>
|
<button type="button" class="btn btn-sm btn-primary" ui-state="$ctrl.createPath"> <i class="fa fa-plus space-right" aria-hidden="true"></i>Add Custom Template </button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="searchBar" style="border-top: 2px solid #f6f6f6;">
|
<div class="searchBar">
|
||||||
<i class="fa fa-search searchIcon" aria-hidden="true"></i>
|
<i class="fa fa-search searchIcon" aria-hidden="true"></i>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
.datatable .toolBar {
|
.datatable .toolBar {
|
||||||
background-color: #f6f6f6;
|
background-color: var(--bg-card-color);
|
||||||
color: #767676;
|
color: var(--text-main-color);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
}
|
}
|
||||||
|
@ -30,9 +30,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.datatable .searchBar {
|
.datatable .searchBar {
|
||||||
border-top: 1px solid #d2d1d1;
|
border-top: 1px solid var(--border-color);
|
||||||
border-bottom: 1px solid #d2d1d1;
|
border-bottom: 1px solid var(--border-color);
|
||||||
padding: 8px;
|
padding: 8px;
|
||||||
|
background: var(--bg-main-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.datatable .searchInput {
|
.datatable .searchInput {
|
||||||
|
@ -60,9 +61,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.datatable .footer {
|
.datatable .footer {
|
||||||
background-color: #f6f6f6;
|
background-color: var(--bg-card-color);
|
||||||
color: #767676;
|
color: var(--text-main-color);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
border-top: 1px solid var(--border-datatable-top-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.datatable .footer .infoBar {
|
.datatable .footer .infoBar {
|
||||||
|
@ -152,9 +154,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.md-checkbox label:before {
|
.md-checkbox label:before {
|
||||||
background: #fff;
|
background: var(--bg-main-color);
|
||||||
border: 2px solid black;
|
border: 2px solid var(--bg-checkbox-border-color);
|
||||||
border: 2px solid rgba(0, 0, 0, 0.54);
|
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
|
|
@ -0,0 +1,96 @@
|
||||||
|
class KubernetesAppGitFormController {
|
||||||
|
/* @ngInject */
|
||||||
|
constructor($async, $state, StackService, ModalService, Notifications) {
|
||||||
|
this.$async = $async;
|
||||||
|
this.$state = $state;
|
||||||
|
this.StackService = StackService;
|
||||||
|
this.ModalService = ModalService;
|
||||||
|
this.Notifications = Notifications;
|
||||||
|
|
||||||
|
this.state = {
|
||||||
|
saveGitSettingsInProgress: false,
|
||||||
|
redeployInProgress: false,
|
||||||
|
showConfig: true,
|
||||||
|
isEdit: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.formValues = {
|
||||||
|
RefName: '',
|
||||||
|
RepositoryAuthentication: false,
|
||||||
|
RepositoryUsername: '',
|
||||||
|
RepositoryPassword: '',
|
||||||
|
};
|
||||||
|
|
||||||
|
this.onChange = this.onChange.bind(this);
|
||||||
|
this.onChangeRef = this.onChangeRef.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
onChangeRef(value) {
|
||||||
|
this.onChange({ RefName: value });
|
||||||
|
}
|
||||||
|
|
||||||
|
onChange(values) {
|
||||||
|
this.formValues = {
|
||||||
|
...this.formValues,
|
||||||
|
...values,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async pullAndRedeployApplication() {
|
||||||
|
return this.$async(async () => {
|
||||||
|
try {
|
||||||
|
const confirmed = await this.ModalService.confirmAsync({
|
||||||
|
title: 'Are you sure?',
|
||||||
|
message: 'Any changes to this application will be overriden by the definition in git and may cause a service interruption. Do you wish to continue?',
|
||||||
|
buttons: {
|
||||||
|
confirm: {
|
||||||
|
label: 'Update',
|
||||||
|
className: 'btn-warning',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!confirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.state.redeployInProgress = true;
|
||||||
|
await this.StackService.updateKubeGit(this.stack.Id, this.stack.EndpointId, this.namespace, this.formValues);
|
||||||
|
this.Notifications.success('Pulled and redeployed stack successfully');
|
||||||
|
await this.$state.reload();
|
||||||
|
} catch (err) {
|
||||||
|
this.Notifications.error('Failure', err, 'Failed redeploying application');
|
||||||
|
} finally {
|
||||||
|
this.state.redeployInProgress = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async saveGitSettings() {
|
||||||
|
return this.$async(async () => {
|
||||||
|
try {
|
||||||
|
this.state.saveGitSettingsInProgress = true;
|
||||||
|
await this.StackService.updateKubeStack({ EndpointId: this.stack.EndpointId, Id: this.stack.Id }, null, this.formValues);
|
||||||
|
this.Notifications.success('Save stack settings successfully');
|
||||||
|
} catch (err) {
|
||||||
|
this.Notifications.error('Failure', err, 'Unable to save application settings');
|
||||||
|
} finally {
|
||||||
|
this.state.saveGitSettingsInProgress = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
isSubmitButtonDisabled() {
|
||||||
|
return this.state.saveGitSettingsInProgress || this.state.redeployInProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
$onInit() {
|
||||||
|
console.log(this);
|
||||||
|
this.formValues.RefName = this.stack.GitConfig.ReferenceName;
|
||||||
|
if (this.stack.GitConfig && this.stack.GitConfig.Authentication) {
|
||||||
|
this.formValues.RepositoryUsername = this.stack.GitConfig.Authentication.Username;
|
||||||
|
this.formValues.RepositoryAuthentication = true;
|
||||||
|
this.state.isEdit = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default KubernetesAppGitFormController;
|
|
@ -0,0 +1,59 @@
|
||||||
|
<form name="$ctrl.redeployGitForm">
|
||||||
|
<div class="col-sm-12 form-section-title">
|
||||||
|
Redeploy from git repository
|
||||||
|
</div>
|
||||||
|
<div class="form-group text-muted">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<p>
|
||||||
|
Pull the latest manifest from git and redeploy the application.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<p>
|
||||||
|
<a class="small interactive" ng-click="$ctrl.state.showConfig = !$ctrl.state.showConfig">
|
||||||
|
<i ng-class="['fa space-right', { 'fa-minus': $ctrl.state.showConfig, 'fa-plus': !$ctrl.state.showConfig }]" aria-hidden="true"></i>
|
||||||
|
{{ $ctrl.state.showConfig ? 'Hide' : 'Advanced' }} configuration
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<git-form-ref-field ng-if="$ctrl.state.showConfig" value="$ctrl.formValues.RefName" on-change="($ctrl.onChangeRef)"></git-form-ref-field>
|
||||||
|
<git-form-auth-fieldset
|
||||||
|
ng-if="$ctrl.state.showConfig"
|
||||||
|
model="$ctrl.formValues"
|
||||||
|
is-edit="$ctrl.state.isEdit"
|
||||||
|
on-change="($ctrl.onChange)"
|
||||||
|
show-auth-explanation="true"
|
||||||
|
></git-form-auth-fieldset>
|
||||||
|
|
||||||
|
<div class="col-sm-12 form-section-title">
|
||||||
|
Actions
|
||||||
|
</div>
|
||||||
|
<!-- #Git buttons -->
|
||||||
|
<button
|
||||||
|
class="btn btn-sm btn-primary"
|
||||||
|
ng-click="$ctrl.pullAndRedeployApplication()"
|
||||||
|
ng-disabled="$ctrl.isSubmitButtonDisabled() || !$ctrl.redeployGitForm.$valid"
|
||||||
|
style="margin-top: 7px; margin-left: 0;"
|
||||||
|
button-spinner="ctrl.state.redeployInProgress"
|
||||||
|
analytics-on
|
||||||
|
analytics-category="kubernetes"
|
||||||
|
analytics-event="kubernetes-application-edit-git-pull"
|
||||||
|
>
|
||||||
|
<span ng-show="!$ctrl.state.redeployInProgress"> <i class="fa fa-sync space-right" aria-hidden="true"></i> Pull and update application </span>
|
||||||
|
<span ng-show="$ctrl.state.redeployInProgress">In progress...</span>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-sm btn-primary"
|
||||||
|
ng-click="$ctrl.saveGitSettings()"
|
||||||
|
ng-disabled="$ctrl.isSubmitButtonDisabled() || !$ctrl.redeployGitForm.$valid"
|
||||||
|
style="margin-top: 7px; margin-left: 0;"
|
||||||
|
button-spinner="$ctrl.state.saveGitSettingsInProgress"
|
||||||
|
>
|
||||||
|
<span ng-show="!$ctrl.state.saveGitSettingsInProgress"> Save settings </span>
|
||||||
|
<span ng-show="$ctrl.state.saveGitSettingsInProgress">In progress...</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
|
@ -0,0 +1,13 @@
|
||||||
|
import angular from 'angular';
|
||||||
|
import controller from './kubernetes-app-git-form.controller';
|
||||||
|
|
||||||
|
const kubernetesAppGitForm = {
|
||||||
|
templateUrl: './kubernetes-app-git-form.html',
|
||||||
|
controller,
|
||||||
|
bindings: {
|
||||||
|
namespace: '<',
|
||||||
|
stack: '<',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
angular.module('portainer.app').component('kubernetesAppGitForm', kubernetesAppGitForm);
|
|
@ -13,7 +13,7 @@
|
||||||
* Sidebar
|
* Sidebar
|
||||||
*/
|
*/
|
||||||
#sidebar-wrapper {
|
#sidebar-wrapper {
|
||||||
background: #30426a;
|
background: var(--bg-sidebar-wrapper-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.sidebar .sidebar-main a,
|
ul.sidebar .sidebar-main a,
|
||||||
|
@ -21,7 +21,7 @@ ul.sidebar .sidebar-main a,
|
||||||
ul.sidebar .sidebar-list a:hover,
|
ul.sidebar .sidebar-list a:hover,
|
||||||
#page-wrapper:not(.open) ul.sidebar .sidebar-title.separator {
|
#page-wrapper:not(.open) ul.sidebar .sidebar-title.separator {
|
||||||
/* Sidebar header and footer color */
|
/* Sidebar header and footer color */
|
||||||
background: #2d3e63;
|
background: var(--hover-sidebar-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.sidebar {
|
ul.sidebar {
|
||||||
|
@ -63,7 +63,7 @@ ul.sidebar .sidebar-main .menu-icon {
|
||||||
}
|
}
|
||||||
|
|
||||||
ul.sidebar .sidebar-title {
|
ul.sidebar .sidebar-title {
|
||||||
color: #738bc0;
|
color: var(--text-sidebar-title-color);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
|
@ -74,7 +74,7 @@ ul.sidebar .sidebar-title {
|
||||||
ul.sidebar .sidebar-list a {
|
ul.sidebar .sidebar-list a {
|
||||||
text-indent: 25px;
|
text-indent: 25px;
|
||||||
font-size: 15px;
|
font-size: 15px;
|
||||||
color: #b2bfdc;
|
color: var(--text-sidebar-list-color);
|
||||||
line-height: 40px;
|
line-height: 40px;
|
||||||
padding-left: 5px;
|
padding-left: 5px;
|
||||||
border-left: 3px solid transparent;
|
border-left: 3px solid transparent;
|
||||||
|
@ -132,7 +132,7 @@ ul.sidebar .sidebar-list .menu-icon {
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-footer div a {
|
.sidebar-footer div a {
|
||||||
color: #b2bfdc;
|
color: var(--text-sidebar-list-color);
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
line-height: 43px;
|
line-height: 43px;
|
||||||
}
|
}
|
||||||
|
@ -172,8 +172,8 @@ ul.sidebar .sidebar-list a {
|
||||||
|
|
||||||
ul.sidebar .sidebar-list a.active {
|
ul.sidebar .sidebar-list a.active {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-left-color: #fff;
|
border-left-color: var(--border-sidebar-color);
|
||||||
background: #2d3e63;
|
background: var(--hover-sidebar-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-header {
|
.sidebar-header {
|
||||||
|
@ -181,7 +181,7 @@ ul.sidebar .sidebar-list a.active {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
text-indent: 20px;
|
text-indent: 20px;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
background: #2d3e63;
|
background: var(--bg-sidebar-header-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebar-header a {
|
.sidebar-header a {
|
||||||
|
@ -255,7 +255,7 @@ ul.sidebar .sidebar-list a.active .menu-icon {
|
||||||
ul.sidebar .sidebar-list .sidebar-sublist a {
|
ul.sidebar .sidebar-list .sidebar-sublist a {
|
||||||
text-indent: 35px;
|
text-indent: 35px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #b2bfdc;
|
color: var(--text-sidebar-list-color);
|
||||||
line-height: 36px;
|
line-height: 36px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ ul.sidebar .sidebar-list .menu-icon {
|
||||||
ul.sidebar .sidebar-list .sidebar-sublist a.active {
|
ul.sidebar .sidebar-list .sidebar-sublist a.active {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
border-left: 3px solid #fff;
|
border-left: 3px solid #fff;
|
||||||
background: #2d3e63;
|
background: var(--bg-sidebar-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-height: 785px) {
|
@media (max-height: 785px) {
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="searchBar" style="border-top: 2px solid #f6f6f6;">
|
<div class="searchBar">
|
||||||
<i class="fa fa-search searchIcon" aria-hidden="true"></i>
|
<i class="fa fa-search searchIcon" aria-hidden="true"></i>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
import { buildOption } from '@/portainer/components/box-selector';
|
||||||
|
|
||||||
|
export default class ThemeSettingsController {
|
||||||
|
/* @ngInject */
|
||||||
|
constructor($async, Authentication, ThemeManager, StateManager, UserService, Notifications) {
|
||||||
|
this.$async = $async;
|
||||||
|
this.Authentication = Authentication;
|
||||||
|
this.ThemeManager = ThemeManager;
|
||||||
|
this.StateManager = StateManager;
|
||||||
|
this.UserService = UserService;
|
||||||
|
this.Notifications = Notifications;
|
||||||
|
|
||||||
|
this.setTheme = this.setTheme.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Theme Settings Panel */
|
||||||
|
async updateTheme() {
|
||||||
|
try {
|
||||||
|
await this.UserService.updateUserTheme(this.state.userId, this.state.userTheme);
|
||||||
|
this.state.themeInProgress = false;
|
||||||
|
this.Notifications.success('Success', 'User theme successfully updated');
|
||||||
|
} catch (err) {
|
||||||
|
this.Notifications.error('Failure', err, 'Unable to update user theme');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setTheme(theme) {
|
||||||
|
this.ThemeManager.setTheme(theme);
|
||||||
|
this.state.themeInProgress = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$onInit() {
|
||||||
|
return this.$async(async () => {
|
||||||
|
this.state = {
|
||||||
|
userId: null,
|
||||||
|
userTheme: '',
|
||||||
|
initTheme: '',
|
||||||
|
defaultTheme: 'light',
|
||||||
|
themeInProgress: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
this.state.availableThemes = [
|
||||||
|
buildOption('light', 'fas fa-sun', 'Light Theme', 'Default color mode', 'light'),
|
||||||
|
buildOption('dark', 'fas fa-moon', 'Dark Theme', 'Dark color mode', 'dark'),
|
||||||
|
buildOption('highcontrast', 'fas fa-adjust', 'High Contrast', 'High contrast color mode', 'highcontrast'),
|
||||||
|
];
|
||||||
|
|
||||||
|
this.state.availableTheme = {
|
||||||
|
light: 'light',
|
||||||
|
dark: 'dark',
|
||||||
|
highContrast: 'highcontrast',
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.state.userId = await this.Authentication.getUserDetails().ID;
|
||||||
|
const data = await this.UserService.user(this.state.userId);
|
||||||
|
this.state.userTheme = data.UserTheme || this.state.defaultTheme;
|
||||||
|
this.state.initTheme = this.state.userTheme;
|
||||||
|
} catch (err) {
|
||||||
|
this.Notifications.error('Failure', err, 'Unable to get user details');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$onDestroy() {
|
||||||
|
if (this.state.themeInProgress) {
|
||||||
|
this.ThemeManager.setTheme(this.state.initTheme);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
<information-panel class="theme-information" title-text="Information">
|
||||||
|
<span class="small text-muted">
|
||||||
|
<p>
|
||||||
|
<i class="fa fa-flask orange-icon" aria-hidden="true" style="margin-right: 2px;"></i>
|
||||||
|
Dark and High-contrast theme are experimental. Some UI components might not display properly.
|
||||||
|
</p>
|
||||||
|
</span>
|
||||||
|
</information-panel>
|
||||||
|
<rd-widget>
|
||||||
|
<rd-widget-header icon="fa-palette" title-text="Change user theme"></rd-widget-header>
|
||||||
|
<rd-widget-body>
|
||||||
|
<form class="theme-panel">
|
||||||
|
<!-- Theme -->
|
||||||
|
<box-selector radio-name="theme" ng-model="$ctrl.state.userTheme" options="$ctrl.state.availableThemes" on-change="($ctrl.setTheme)"></box-selector>
|
||||||
|
<button ng-click="$ctrl.updateTheme()" class="btn btn-primary btn-sm">Update theme</button>
|
||||||
|
<!-- !Theme -->
|
||||||
|
</form>
|
||||||
|
</rd-widget-body>
|
||||||
|
</rd-widget>
|
|
@ -0,0 +1,7 @@
|
||||||
|
import angular from 'angular';
|
||||||
|
import controller from './theme-settings.controller';
|
||||||
|
|
||||||
|
angular.module('portainer.app').component('themeSettings', {
|
||||||
|
templateUrl: './theme-settings.html',
|
||||||
|
controller,
|
||||||
|
});
|
|
@ -1,6 +1,6 @@
|
||||||
import _ from 'lodash-es';
|
import _ from 'lodash-es';
|
||||||
|
|
||||||
export const KEY_REGEX = /(.+)/.source;
|
export const KEY_REGEX = /(.+?)/.source;
|
||||||
export const VALUE_REGEX = /(.*)?/.source;
|
export const VALUE_REGEX = /(.*)?/.source;
|
||||||
|
|
||||||
const KEY_VALUE_REGEX = new RegExp(`^(${KEY_REGEX})\\s*=(${VALUE_REGEX})$`);
|
const KEY_VALUE_REGEX = new RegExp(`^(${KEY_REGEX})\\s*=(${VALUE_REGEX})$`);
|
||||||
|
|
|
@ -2,6 +2,7 @@ export function UserViewModel(data) {
|
||||||
this.Id = data.Id;
|
this.Id = data.Id;
|
||||||
this.Username = data.Username;
|
this.Username = data.Username;
|
||||||
this.Role = data.Role;
|
this.Role = data.Role;
|
||||||
|
this.UserTheme = data.UserTheme;
|
||||||
if (data.Role === 1) {
|
if (data.Role === 1) {
|
||||||
this.RoleName = 'administrator';
|
this.RoleName = 'administrator';
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -12,6 +12,7 @@ angular.module('portainer.app').factory('Users', [
|
||||||
get: { method: 'GET', params: { id: '@id' } },
|
get: { method: 'GET', params: { id: '@id' } },
|
||||||
update: { method: 'PUT', params: { id: '@id' }, ignoreLoadingBar: true },
|
update: { method: 'PUT', params: { id: '@id' }, ignoreLoadingBar: true },
|
||||||
updatePassword: { method: 'PUT', params: { id: '@id', entity: 'passwd' } },
|
updatePassword: { method: 'PUT', params: { id: '@id', entity: 'passwd' } },
|
||||||
|
updateTheme: { method: 'PUT', params: { id: '@id' } },
|
||||||
remove: { method: 'DELETE', params: { id: '@id' } },
|
remove: { method: 'DELETE', params: { id: '@id' } },
|
||||||
queryMemberships: { method: 'GET', isArray: true, params: { id: '@id', entity: 'memberships' } },
|
queryMemberships: { method: 'GET', isArray: true, params: { id: '@id', entity: 'memberships' } },
|
||||||
checkAdminUser: { method: 'GET', params: { id: 'admin', entity: 'check' }, isArray: true, ignoreLoadingBar: true },
|
checkAdminUser: { method: 'GET', params: { id: 'admin', entity: 'check' }, isArray: true, ignoreLoadingBar: true },
|
||||||
|
|
|
@ -137,10 +137,10 @@ angular.module('portainer.app').factory('EndpointService', [
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
service.createLocalKubernetesEndpoint = function (name = 'local') {
|
service.createLocalKubernetesEndpoint = function (name = 'local', tagIds = []) {
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
|
|
||||||
FileUploadService.createEndpoint(name, PortainerEndpointCreationTypes.LocalKubernetesEnvironment, '', '', 1, [], true, true, true)
|
FileUploadService.createEndpoint(name, PortainerEndpointCreationTypes.LocalKubernetesEnvironment, '', '', 1, tagIds, true, true, true)
|
||||||
.then(function success(response) {
|
.then(function success(response) {
|
||||||
deferred.resolve(response.data);
|
deferred.resolve(response.data);
|
||||||
})
|
})
|
||||||
|
|
|
@ -91,6 +91,10 @@ angular.module('portainer.app').factory('UserService', [
|
||||||
return Users.updatePassword({ id: id }, payload).$promise;
|
return Users.updatePassword({ id: id }, payload).$promise;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
service.updateUserTheme = function (id, userTheme) {
|
||||||
|
return Users.updateTheme({ id }, { userTheme }).$promise;
|
||||||
|
};
|
||||||
|
|
||||||
service.userMemberships = function (id) {
|
service.userMemberships = function (id) {
|
||||||
var deferred = $q.defer();
|
var deferred = $q.defer();
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,9 @@ angular.module('portainer.app').factory('Authentication', [
|
||||||
'LocalStorage',
|
'LocalStorage',
|
||||||
'StateManager',
|
'StateManager',
|
||||||
'EndpointProvider',
|
'EndpointProvider',
|
||||||
function AuthenticationFactory($async, $state, Auth, OAuth, jwtHelper, LocalStorage, StateManager, EndpointProvider) {
|
'UserService',
|
||||||
|
'ThemeManager',
|
||||||
|
function AuthenticationFactory($async, $state, Auth, OAuth, jwtHelper, LocalStorage, StateManager, EndpointProvider, UserService, ThemeManager) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var service = {};
|
var service = {};
|
||||||
|
@ -82,12 +84,20 @@ angular.module('portainer.app').factory('Authentication', [
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function setUserTheme() {
|
||||||
|
const data = await UserService.user(user.ID);
|
||||||
|
// Initialize user theme base on Usertheme from database
|
||||||
|
const userTheme = data.UserTheme;
|
||||||
|
ThemeManager.setTheme(userTheme);
|
||||||
|
}
|
||||||
|
|
||||||
async function setUser(jwt) {
|
async function setUser(jwt) {
|
||||||
LocalStorage.storeJWT(jwt);
|
LocalStorage.storeJWT(jwt);
|
||||||
var tokenPayload = jwtHelper.decodeToken(jwt);
|
var tokenPayload = jwtHelper.decodeToken(jwt);
|
||||||
user.username = tokenPayload.username;
|
user.username = tokenPayload.username;
|
||||||
user.ID = tokenPayload.id;
|
user.ID = tokenPayload.id;
|
||||||
user.role = tokenPayload.role;
|
user.role = tokenPayload.role;
|
||||||
|
await setUserTheme();
|
||||||
}
|
}
|
||||||
|
|
||||||
function isAdmin() {
|
function isAdmin() {
|
||||||
|
|
|
@ -54,6 +54,11 @@ angular.module('portainer.app').factory('StateManager', [
|
||||||
LocalStorage.storeApplicationState(state.application);
|
LocalStorage.storeApplicationState(state.application);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
manager.updateTheme = function (theme) {
|
||||||
|
state.application.theme = theme;
|
||||||
|
LocalStorage.storeApplicationState(state.application);
|
||||||
|
};
|
||||||
|
|
||||||
manager.updateSnapshotInterval = function (interval) {
|
manager.updateSnapshotInterval = function (interval) {
|
||||||
state.application.snapshotInterval = interval;
|
state.application.snapshotInterval = interval;
|
||||||
LocalStorage.storeApplicationState(state.application);
|
LocalStorage.storeApplicationState(state.application);
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
angular.module('portainer.app').service('ThemeManager', ThemeManager);
|
||||||
|
|
||||||
|
/* @ngInject */
|
||||||
|
|
||||||
|
export function ThemeManager(StateManager) {
|
||||||
|
return {
|
||||||
|
setTheme,
|
||||||
|
defaultTheme,
|
||||||
|
};
|
||||||
|
|
||||||
|
function setTheme(theme) {
|
||||||
|
if (!theme) {
|
||||||
|
document.documentElement.removeAttribute('theme');
|
||||||
|
} else {
|
||||||
|
document.documentElement.setAttribute('theme', theme);
|
||||||
|
}
|
||||||
|
StateManager.updateTheme(theme);
|
||||||
|
}
|
||||||
|
|
||||||
|
function defaultTheme() {
|
||||||
|
document.documentElement.removeAttribute('theme');
|
||||||
|
}
|
||||||
|
}
|
|
@ -78,5 +78,6 @@
|
||||||
</form>
|
</form>
|
||||||
</rd-widget-body>
|
</rd-widget-body>
|
||||||
</rd-widget>
|
</rd-widget>
|
||||||
|
<theme-settings></theme-settings>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,11 +5,14 @@ angular.module('portainer.app').controller('AccountController', [
|
||||||
'UserService',
|
'UserService',
|
||||||
'Notifications',
|
'Notifications',
|
||||||
'SettingsService',
|
'SettingsService',
|
||||||
function ($scope, $state, Authentication, UserService, Notifications, SettingsService) {
|
'StateManager',
|
||||||
|
'ThemeManager',
|
||||||
|
function ($scope, $state, Authentication, UserService, Notifications, SettingsService, StateManager, ThemeManager) {
|
||||||
$scope.formValues = {
|
$scope.formValues = {
|
||||||
currentPassword: '',
|
currentPassword: '',
|
||||||
newPassword: '',
|
newPassword: '',
|
||||||
confirmPassword: '',
|
confirmPassword: '',
|
||||||
|
userTheme: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.updatePassword = function () {
|
$scope.updatePassword = function () {
|
||||||
|
@ -23,8 +26,30 @@ angular.module('portainer.app').controller('AccountController', [
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
function initView() {
|
// Update DOM for theme attribute & LocalStorage
|
||||||
|
$scope.setTheme = function (theme) {
|
||||||
|
ThemeManager.setTheme(theme);
|
||||||
|
StateManager.updateTheme(theme);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Rest API Call to update theme with userID in DB
|
||||||
|
$scope.updateTheme = function () {
|
||||||
|
UserService.updateUserTheme($scope.userID, $scope.formValues.userTheme)
|
||||||
|
.then(function success() {
|
||||||
|
Notifications.success('Success', 'User theme successfully updated');
|
||||||
|
$state.reload();
|
||||||
|
})
|
||||||
|
.catch(function error(err) {
|
||||||
|
Notifications.error('Failure', err, err.msg);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
async function initView() {
|
||||||
$scope.userID = Authentication.getUserDetails().ID;
|
$scope.userID = Authentication.getUserDetails().ID;
|
||||||
|
|
||||||
|
const data = await UserService.user($scope.userID);
|
||||||
|
|
||||||
|
$scope.formValues.userTheme = data.Usertheme;
|
||||||
SettingsService.publicSettings()
|
SettingsService.publicSettings()
|
||||||
.then(function success(data) {
|
.then(function success(data) {
|
||||||
$scope.AuthenticationMethod = data.AuthenticationMethod;
|
$scope.AuthenticationMethod = data.AuthenticationMethod;
|
||||||
|
|
|
@ -154,8 +154,9 @@ angular
|
||||||
|
|
||||||
$scope.addKubernetesEndpoint = function () {
|
$scope.addKubernetesEndpoint = function () {
|
||||||
var name = $scope.formValues.Name;
|
var name = $scope.formValues.Name;
|
||||||
|
var tagIds = $scope.formValues.TagIds;
|
||||||
$scope.state.actionInProgress = true;
|
$scope.state.actionInProgress = true;
|
||||||
EndpointService.createLocalKubernetesEndpoint(name)
|
EndpointService.createLocalKubernetesEndpoint(name, tagIds)
|
||||||
.then(function success(result) {
|
.then(function success(result) {
|
||||||
Notifications.success('Endpoint created', name);
|
Notifications.success('Endpoint created', name);
|
||||||
$state.go('portainer.endpoints.endpoint.kubernetesConfig', { id: result.Id });
|
$state.go('portainer.endpoints.endpoint.kubernetesConfig', { id: result.Id });
|
||||||
|
|
|
@ -168,10 +168,14 @@ function EndpointController(
|
||||||
payload.URL = 'tcp://' + endpoint.URL;
|
payload.URL = 'tcp://' + endpoint.URL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (endpoint.Type === PortainerEndpointTypes.AgentOnKubernetesEnvironment || endpoint.Type === PortainerEndpointTypes.KubernetesLocalEnvironment) {
|
if (endpoint.Type === PortainerEndpointTypes.AgentOnKubernetesEnvironment) {
|
||||||
payload.URL = endpoint.URL;
|
payload.URL = endpoint.URL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (endpoint.Type === PortainerEndpointTypes.KubernetesLocalEnvironment) {
|
||||||
|
payload.URL = 'https://' + endpoint.URL;
|
||||||
|
}
|
||||||
|
|
||||||
$scope.state.actionInProgress = true;
|
$scope.state.actionInProgress = true;
|
||||||
EndpointService.updateEndpoint(endpoint.Id, payload).then(
|
EndpointService.updateEndpoint(endpoint.Id, payload).then(
|
||||||
function success() {
|
function success() {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import angular from 'angular';
|
||||||
|
|
||||||
class LogoutController {
|
class LogoutController {
|
||||||
/* @ngInject */
|
/* @ngInject */
|
||||||
constructor($async, $state, $transition$, $window, Authentication, StateManager, Notifications, LocalStorage, SettingsService) {
|
constructor($async, $state, $transition$, $window, Authentication, StateManager, Notifications, LocalStorage, SettingsService, ThemeManager) {
|
||||||
this.$async = $async;
|
this.$async = $async;
|
||||||
this.$state = $state;
|
this.$state = $state;
|
||||||
this.$transition$ = $transition$;
|
this.$transition$ = $transition$;
|
||||||
|
@ -13,6 +13,7 @@ class LogoutController {
|
||||||
this.Notifications = Notifications;
|
this.Notifications = Notifications;
|
||||||
this.LocalStorage = LocalStorage;
|
this.LocalStorage = LocalStorage;
|
||||||
this.SettingsService = SettingsService;
|
this.SettingsService = SettingsService;
|
||||||
|
this.ThemeManager = ThemeManager;
|
||||||
|
|
||||||
this.logo = this.StateManager.getState().application.logo;
|
this.logo = this.StateManager.getState().application.logo;
|
||||||
this.logoutAsync = this.logoutAsync.bind(this);
|
this.logoutAsync = this.logoutAsync.bind(this);
|
||||||
|
@ -28,6 +29,8 @@ class LogoutController {
|
||||||
const performApiLogout = this.$transition$.params().performApiLogout;
|
const performApiLogout = this.$transition$.params().performApiLogout;
|
||||||
const settings = await this.SettingsService.publicSettings();
|
const settings = await this.SettingsService.publicSettings();
|
||||||
|
|
||||||
|
this.ThemeManager.defaultTheme();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.Authentication.logout(performApiLogout);
|
await this.Authentication.logout(performApiLogout);
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -3,6 +3,7 @@ angular.module('portainer.app').controller('MainController', [
|
||||||
'LocalStorage',
|
'LocalStorage',
|
||||||
'StateManager',
|
'StateManager',
|
||||||
'EndpointProvider',
|
'EndpointProvider',
|
||||||
|
'ThemeManager',
|
||||||
function ($scope, LocalStorage, StateManager, EndpointProvider) {
|
function ($scope, LocalStorage, StateManager, EndpointProvider) {
|
||||||
/**
|
/**
|
||||||
* Sidebar Toggle & Cookie Control
|
* Sidebar Toggle & Cookie Control
|
||||||
|
|
|
@ -21,7 +21,11 @@ angular.module('portainer.app').controller('RegistriesController', [
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.removeAction = function (selectedItems) {
|
$scope.removeAction = function (selectedItems) {
|
||||||
ModalService.confirmDeletion('Do you want to remove the selected registries?', function onConfirm(confirmed) {
|
const regAttrMsg = selectedItems.length > 1 ? 'hese' : 'his';
|
||||||
|
const registriesMsg = selectedItems.length > 1 ? 'registries' : 'registry';
|
||||||
|
const msg = `T${regAttrMsg} ${registriesMsg} might be used by applications inside one or more endpoints. Removing the ${registriesMsg} could lead to a service interruption for the applications using t${regAttrMsg} ${registriesMsg}. Do you want to remove the selected ${registriesMsg}?`;
|
||||||
|
|
||||||
|
ModalService.confirmDeletion(msg, function onConfirm(confirmed) {
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,57 @@
|
||||||
#!/usr/bin/env bash
|
#!/bin/bash
|
||||||
|
set -euo pipefail
|
||||||
|
IFS=$'\n\t'
|
||||||
|
|
||||||
PLATFORM=$1
|
PLATFORM=$1
|
||||||
ARCH=$2
|
ARCH=$2
|
||||||
DOCKER_COMPOSE_VERSION=$3
|
DOCKER_COMPOSE_VERSION=$3
|
||||||
|
|
||||||
if [ "${PLATFORM}" == 'linux' ] && [ "${ARCH}" == 'amd64' ]; then
|
function download_binary() {
|
||||||
wget -O "dist/docker-compose" "https://github.com/portainer/docker-compose-linux-amd64-static-binary/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose"
|
local PLATFORM=$1
|
||||||
chmod +x "dist/docker-compose"
|
local ARCH=$2
|
||||||
elif [ "${PLATFORM}" == 'mac' ]; then
|
local BINARY_VERSION=$3
|
||||||
wget -O "dist/docker-compose" "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-Darwin-x86_64"
|
|
||||||
chmod +x "dist/docker-compose"
|
if [ "${PLATFORM}" == 'linux' ] && [ "${ARCH}" == 'amd64' ]; then
|
||||||
elif [ "${PLATFORM}" == 'win' ]; then
|
wget -O "dist/docker-compose" "https://github.com/portainer/docker-compose-linux-amd64-static-binary/releases/download/${BINARY_VERSION}/docker-compose"
|
||||||
wget -O "dist/docker-compose.exe" "https://github.com/docker/compose/releases/download/${DOCKER_COMPOSE_VERSION}/docker-compose-Windows-x86_64.exe"
|
chmod +x "dist/docker-compose"
|
||||||
chmod +x "dist/docker-compose.exe"
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${PLATFORM}" == 'mac' ]; then
|
||||||
|
wget -O "dist/docker-compose" "https://github.com/docker/compose/releases/download/${BINARY_VERSION}/docker-compose-Darwin-x86_64"
|
||||||
|
chmod +x "dist/docker-compose"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "${PLATFORM}" == 'win' ]; then
|
||||||
|
wget -O "dist/docker-compose.exe" "https://github.com/docker/compose/releases/download/${BINARY_VERSION}/docker-compose-Windows-x86_64.exe"
|
||||||
|
chmod +x "dist/docker-compose.exe"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function download_plugin() {
|
||||||
|
local PLATFORM=$1
|
||||||
|
local ARCH=$2
|
||||||
|
local PLUGIN_VERSION=$3
|
||||||
|
|
||||||
|
if [ "${PLATFORM}" == 'mac' ]; then
|
||||||
|
PLATFORM="darwin"
|
||||||
|
fi
|
||||||
|
|
||||||
|
FILENAME="docker-compose-${PLATFORM}-${ARCH}"
|
||||||
|
TARGET_FILENAME="docker-compose.plugin"
|
||||||
|
if [[ "$PLATFORM" == "windows" ]]; then
|
||||||
|
FILENAME="$FILENAME.exe"
|
||||||
|
TARGET_FILENAME="$TARGET_FILENAME.exe"
|
||||||
|
fi
|
||||||
|
|
||||||
|
wget -O "dist/$TARGET_FILENAME" "https://github.com/docker/compose-cli/releases/download/v$PLUGIN_VERSION/$FILENAME"
|
||||||
|
chmod +x "dist/$TARGET_FILENAME"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ "${PLATFORM}" == 'linux' ] && [ "${ARCH}" != 'amd64' ]; then
|
||||||
|
download_plugin "$PLATFORM" "$ARCH" "$DOCKER_COMPOSE_VERSION"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
exit 0
|
download_binary "$PLATFORM" "$ARCH" "$DOCKER_COMPOSE_VERSION"
|
26
gruntfile.js
26
gruntfile.js
|
@ -22,6 +22,7 @@ module.exports = function (grunt) {
|
||||||
dockerWindowsVersion: '19-03-12',
|
dockerWindowsVersion: '19-03-12',
|
||||||
dockerLinuxComposeVersion: '1.27.4',
|
dockerLinuxComposeVersion: '1.27.4',
|
||||||
dockerWindowsComposeVersion: '1.28.0',
|
dockerWindowsComposeVersion: '1.28.0',
|
||||||
|
dockerComposePluginVersion: '2.0.0-beta.6',
|
||||||
komposeVersion: 'v1.22.0',
|
komposeVersion: 'v1.22.0',
|
||||||
kubectlVersion: 'v1.18.0',
|
kubectlVersion: 'v1.18.0',
|
||||||
},
|
},
|
||||||
|
@ -214,13 +215,24 @@ function shell_download_docker_compose_binary(p, a) {
|
||||||
var ia = as[a] || a;
|
var ia = as[a] || a;
|
||||||
var binaryVersion = p === 'windows' ? '<%= binaries.dockerWindowsComposeVersion %>' : '<%= binaries.dockerLinuxComposeVersion %>';
|
var binaryVersion = p === 'windows' ? '<%= binaries.dockerWindowsComposeVersion %>' : '<%= binaries.dockerLinuxComposeVersion %>';
|
||||||
|
|
||||||
return [
|
// plugin
|
||||||
'if [ -f dist/docker-compose ] || [ -f dist/docker-compose.exe ]; then',
|
if (p === 'linux' && a !== 'amd64') {
|
||||||
'echo "Docker Compose binary exists";',
|
if (a === 'arm64') {
|
||||||
'else',
|
ia = 'arm64';
|
||||||
'build/download_docker_compose_binary.sh ' + ip + ' ' + ia + ' ' + binaryVersion + ';',
|
}
|
||||||
'fi',
|
|
||||||
].join(' ');
|
if (a === 'arm') {
|
||||||
|
ia = 'armv7';
|
||||||
|
}
|
||||||
|
binaryVersion = '<%= binaries.dockerComposePluginVersion %>';
|
||||||
|
}
|
||||||
|
|
||||||
|
return `
|
||||||
|
if [ -f dist/docker-compose ] || [ -f dist/docker-compose.exe ] || [ -f dist/docker-compose.plugin ] || [ -f dist/docker-compose.plugin.exe ]; then
|
||||||
|
echo "Docker Compose binary exists";
|
||||||
|
else
|
||||||
|
build/download_docker_compose_binary.sh ${ip} ${ia} ${binaryVersion};
|
||||||
|
fi`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function shell_download_kompose_binary(p, a) {
|
function shell_download_kompose_binary(p, a) {
|
||||||
|
|
Loading…
Reference in New Issue