resolve conflicts

This commit is contained in:
ArrisLee
2021-09-20 14:18:16 +12:00
399 changed files with 7237 additions and 1590 deletions

View File

@@ -19,8 +19,8 @@ func NewService(dataStore portainer.DataStore) *Service {
}
}
// DefaultEndpointAuthorizationsForEndpointAdministratorRole returns the default endpoint authorizations
// associated to the endpoint administrator role.
// DefaultEndpointAuthorizationsForEndpointAdministratorRole returns the default environment(endpoint) authorizations
// associated to the environment(endpoint) administrator role.
func DefaultEndpointAuthorizationsForEndpointAdministratorRole() portainer.Authorizations {
return map[portainer.Authorization]bool{
portainer.OperationDockerContainerArchiveInfo: true,
@@ -157,7 +157,7 @@ func DefaultEndpointAuthorizationsForEndpointAdministratorRole() portainer.Autho
}
}
// DefaultEndpointAuthorizationsForHelpDeskRole returns the default endpoint authorizations
// DefaultEndpointAuthorizationsForHelpDeskRole returns the default environment(endpoint) authorizations
// associated to the helpdesk role.
func DefaultEndpointAuthorizationsForHelpDeskRole(volumeBrowsingAuthorizations bool) portainer.Authorizations {
authorizations := map[portainer.Authorization]bool{
@@ -216,7 +216,7 @@ func DefaultEndpointAuthorizationsForHelpDeskRole(volumeBrowsingAuthorizations b
return authorizations
}
// DefaultEndpointAuthorizationsForStandardUserRole returns the default endpoint authorizations
// DefaultEndpointAuthorizationsForStandardUserRole returns the default environment(endpoint) authorizations
// associated to the standard user role.
func DefaultEndpointAuthorizationsForStandardUserRole(volumeBrowsingAuthorizations bool) portainer.Authorizations {
authorizations := map[portainer.Authorization]bool{
@@ -350,7 +350,7 @@ func DefaultEndpointAuthorizationsForStandardUserRole(volumeBrowsingAuthorizatio
return authorizations
}
// DefaultEndpointAuthorizationsForReadOnlyUserRole returns the default endpoint authorizations
// DefaultEndpointAuthorizationsForReadOnlyUserRole returns the default environment(endpoint) authorizations
// associated to the readonly user role.
func DefaultEndpointAuthorizationsForReadOnlyUserRole(volumeBrowsingAuthorizations bool) portainer.Authorizations {
authorizations := map[portainer.Authorization]bool{

View File

@@ -5,7 +5,7 @@ import (
"github.com/portainer/portainer/api/internal/tag"
)
// EdgeGroupRelatedEndpoints returns a list of endpoints related to this Edge group
// EdgeGroupRelatedEndpoints returns a list of environments(endpoints) related to this Edge group
func EdgeGroupRelatedEndpoints(edgeGroup *portainer.EdgeGroup, endpoints []portainer.Endpoint, endpointGroups []portainer.EndpointGroup) []portainer.EndpointID {
if !edgeGroup.Dynamic {
return edgeGroup.Endpoints
@@ -33,7 +33,7 @@ func EdgeGroupRelatedEndpoints(edgeGroup *portainer.EdgeGroup, endpoints []porta
return endpointIDs
}
// edgeGroupRelatedToEndpoint returns true is edgeGroup is associated with endpoint
// edgeGroupRelatedToEndpoint returns true is edgeGroup is associated with environment(endpoint)
func edgeGroupRelatedToEndpoint(edgeGroup *portainer.EdgeGroup, endpoint *portainer.Endpoint, endpointGroup *portainer.EndpointGroup) bool {
if !edgeGroup.Dynamic {
for _, endpointID := range edgeGroup.Endpoints {

View File

@@ -2,7 +2,7 @@ package edge
import portainer "github.com/portainer/portainer/api"
// LoadEdgeJobs registers all edge jobs inside corresponding endpoint tunnel
// LoadEdgeJobs registers all edge jobs inside corresponding environment(endpoint) tunnel
func LoadEdgeJobs(dataStore portainer.DataStore, reverseTunnelService portainer.ReverseTunnelService) error {
edgeJobs, err := dataStore.EdgeJob().EdgeJobs()
if err != nil {

View File

@@ -5,7 +5,7 @@ import (
"github.com/portainer/portainer/api"
)
// EdgeStackRelatedEndpoints returns a list of endpoints related to this Edge stack
// EdgeStackRelatedEndpoints returns a list of environments(endpoints) related to this Edge stack
func EdgeStackRelatedEndpoints(edgeGroupIDs []portainer.EdgeGroupID, endpoints []portainer.Endpoint, endpointGroups []portainer.EndpointGroup, edgeGroups []portainer.EdgeGroup) ([]portainer.EndpointID, error) {
edgeStackEndpoints := []portainer.EndpointID{}

View File

@@ -2,7 +2,7 @@ package edge
import "github.com/portainer/portainer/api"
// EndpointRelatedEdgeStacks returns a list of Edge stacks related to this Endpoint
// EndpointRelatedEdgeStacks returns a list of Edge stacks related to this Environment(Endpoint)
func EndpointRelatedEdgeStacks(endpoint *portainer.Endpoint, endpointGroup *portainer.EndpointGroup, edgeGroups []portainer.EdgeGroup, edgeStacks []portainer.EdgeStack) []portainer.EdgeStackID {
relatedEdgeGroupsSet := map[portainer.EdgeGroupID]bool{}

View File

@@ -0,0 +1,47 @@
package endpointutils
import (
"testing"
portainer "github.com/portainer/portainer/api"
"github.com/stretchr/testify/assert"
)
type isEndpointTypeTest struct {
endpointType portainer.EndpointType
expected bool
}
func Test_IsDockerEndpoint(t *testing.T) {
tests := []isEndpointTypeTest{
{endpointType: portainer.DockerEnvironment, expected: true},
{endpointType: portainer.AgentOnDockerEnvironment, expected: true},
{endpointType: portainer.AzureEnvironment, expected: false},
{endpointType: portainer.EdgeAgentOnDockerEnvironment, expected: true},
{endpointType: portainer.KubernetesLocalEnvironment, expected: false},
{endpointType: portainer.AgentOnKubernetesEnvironment, expected: false},
{endpointType: portainer.EdgeAgentOnKubernetesEnvironment, expected: false},
}
for _, test := range tests {
ans := IsDockerEndpoint(&portainer.Endpoint{Type: test.endpointType})
assert.Equal(t, test.expected, ans)
}
}
func Test_IsKubernetesEndpoint(t *testing.T) {
tests := []isEndpointTypeTest{
{endpointType: portainer.DockerEnvironment, expected: false},
{endpointType: portainer.AgentOnDockerEnvironment, expected: false},
{endpointType: portainer.AzureEnvironment, expected: false},
{endpointType: portainer.EdgeAgentOnDockerEnvironment, expected: false},
{endpointType: portainer.KubernetesLocalEnvironment, expected: true},
{endpointType: portainer.AgentOnKubernetesEnvironment, expected: true},
{endpointType: portainer.EdgeAgentOnKubernetesEnvironment, expected: true},
}
for _, test := range tests {
ans := IsKubernetesEndpoint(&portainer.Endpoint{Type: test.endpointType})
assert.Equal(t, test.expected, ans)
}
}

View File

@@ -6,11 +6,12 @@ import (
portainer "github.com/portainer/portainer/api"
)
// IsLocalEndpoint returns true if this is a local endpoint
// IsLocalEndpoint returns true if this is a local environment(endpoint)
func IsLocalEndpoint(endpoint *portainer.Endpoint) bool {
return strings.HasPrefix(endpoint.URL, "unix://") || strings.HasPrefix(endpoint.URL, "npipe://") || endpoint.Type == 5
}
// IsEdgeEndpoint returns true if this is an edge endpoint
func IsEdgeEndpoint(endpoint *portainer.Endpoint) bool {
return endpoint.Type == portainer.EdgeAgentOnDockerEnvironment || endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment
}
@@ -22,7 +23,7 @@ func IsKubernetesEndpoint(endpoint *portainer.Endpoint) bool {
endpoint.Type == portainer.EdgeAgentOnKubernetesEnvironment
}
// IsDockerEndpoint returns true if this is a docker endpoint
// IsDockerEndpoint returns true if this is a docker environment(endpoint)
func IsDockerEndpoint(endpoint *portainer.Endpoint) bool {
return endpoint.Type == portainer.DockerEnvironment ||
endpoint.Type == portainer.AgentOnDockerEnvironment ||

View File

@@ -9,9 +9,9 @@ import (
portainer "github.com/portainer/portainer/api"
)
// Service repesents a service to manage endpoint snapshots.
// Service repesents a service to manage environment(endpoint) snapshots.
// It provides an interface to start background snapshots as well as
// specific Docker/Kubernetes endpoint snapshot methods.
// specific Docker/Kubernetes environment(endpoint) snapshot methods.
type Service struct {
dataStore portainer.DataStore
refreshSignal chan struct{}
@@ -37,7 +37,7 @@ func NewService(snapshotInterval string, dataStore portainer.DataStore, dockerSn
}, nil
}
// Start will start a background routine to execute periodic snapshots of endpoints
// Start will start a background routine to execute periodic snapshots of environments(endpoints)
func (service *Service) Start() {
if service.refreshSignal != nil {
return
@@ -72,8 +72,8 @@ func (service *Service) SetSnapshotInterval(snapshotInterval string) error {
return nil
}
// SupportDirectSnapshot checks whether an endpoint can be used to trigger a direct a snapshot.
// It is mostly true for all endpoints except Edge and Azure endpoints.
// SupportDirectSnapshot checks whether an environment(endpoint) can be used to trigger a direct a snapshot.
// It is mostly true for all environments(endpoints) except Edge and Azure environments(endpoints).
func SupportDirectSnapshot(endpoint *portainer.Endpoint) bool {
switch endpoint.Type {
case portainer.EdgeAgentOnDockerEnvironment, portainer.EdgeAgentOnKubernetesEnvironment, portainer.AzureEnvironment:
@@ -82,8 +82,8 @@ func SupportDirectSnapshot(endpoint *portainer.Endpoint) bool {
return true
}
// SnapshotEndpoint will create a snapshot of the endpoint based on the endpoint type.
// If the snapshot is a success, it will be associated to the endpoint.
// SnapshotEndpoint will create a snapshot of the environment(endpoint) based on the environment(endpoint) type.
// If the snapshot is a success, it will be associated to the environment(endpoint).
func (service *Service) SnapshotEndpoint(endpoint *portainer.Endpoint) error {
switch endpoint.Type {
case portainer.AzureEnvironment:
@@ -126,7 +126,7 @@ func (service *Service) startSnapshotLoop() error {
go func() {
err := service.snapshotEndpoints()
if err != nil {
log.Printf("[ERROR] [internal,snapshot] [message: background schedule error (endpoint snapshot).] [error: %s]", err)
log.Printf("[ERROR] [internal,snapshot] [message: background schedule error (environment snapshot).] [error: %s]", err)
}
for {
@@ -134,7 +134,7 @@ func (service *Service) startSnapshotLoop() error {
case <-ticker.C:
err := service.snapshotEndpoints()
if err != nil {
log.Printf("[ERROR] [internal,snapshot] [message: background schedule error (endpoint snapshot).] [error: %s]", err)
log.Printf("[ERROR] [internal,snapshot] [message: background schedule error (environment snapshot).] [error: %s]", err)
}
case <-service.shutdownCtx.Done():
log.Println("[DEBUG] [internal,snapshot] [message: shutting down snapshotting]")
@@ -166,13 +166,13 @@ func (service *Service) snapshotEndpoints() error {
latestEndpointReference, err := service.dataStore.Endpoint().Endpoint(endpoint.ID)
if latestEndpointReference == nil {
log.Printf("background schedule error (endpoint snapshot). Endpoint not found inside the database anymore (endpoint=%s, URL=%s) (err=%s)\n", endpoint.Name, endpoint.URL, err)
log.Printf("background schedule error (environment snapshot). Environment not found inside the database anymore (endpoint=%s, URL=%s) (err=%s)\n", endpoint.Name, endpoint.URL, err)
continue
}
latestEndpointReference.Status = portainer.EndpointStatusUp
if snapshotError != nil {
log.Printf("background schedule error (endpoint snapshot). Unable to create snapshot (endpoint=%s, URL=%s) (err=%s)\n", endpoint.Name, endpoint.URL, snapshotError)
log.Printf("background schedule error (environment snapshot). Unable to create snapshot (endpoint=%s, URL=%s) (err=%s)\n", endpoint.Name, endpoint.URL, snapshotError)
latestEndpointReference.Status = portainer.EndpointStatusDown
}
@@ -181,7 +181,7 @@ func (service *Service) snapshotEndpoints() error {
err = service.dataStore.Endpoint().UpdateEndpoint(latestEndpointReference.ID, latestEndpointReference)
if err != nil {
log.Printf("background schedule error (endpoint snapshot). Unable to update endpoint (endpoint=%s, URL=%s) (err=%s)\n", endpoint.Name, endpoint.URL, err)
log.Printf("background schedule error (environment snapshot). Unable to update environment (endpoint=%s, URL=%s) (err=%s)\n", endpoint.Name, endpoint.URL, err)
continue
}
}
@@ -189,7 +189,7 @@ func (service *Service) snapshotEndpoints() error {
return nil
}
// FetchDockerID fetches info.Swarm.Cluster.ID if endpoint is swarm and info.ID otherwise
// FetchDockerID fetches info.Swarm.Cluster.ID if environment(endpoint) is swarm and info.ID otherwise
func FetchDockerID(snapshot portainer.DockerSnapshot) (string, error) {
info, done := snapshot.SnapshotRaw.Info.(map[string]interface{})
if !done {
@@ -201,12 +201,12 @@ func FetchDockerID(snapshot portainer.DockerSnapshot) (string, error) {
}
if info["Swarm"] == nil {
return "", errors.New("swarm endpoint is missing swarm info snapshot")
return "", errors.New("swarm environment is missing swarm info snapshot")
}
swarmInfo := info["Swarm"].(map[string]interface{})
if swarmInfo["Cluster"] == nil {
return "", errors.New("swarm endpoint is missing cluster info snapshot")
return "", errors.New("swarm environment is missing cluster info snapshot")
}
clusterInfo := swarmInfo["Cluster"].(map[string]interface{})

View File

@@ -4,29 +4,31 @@ import (
"io"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/bolt/errors"
)
type datastore struct {
customTemplate portainer.CustomTemplateService
edgeGroup portainer.EdgeGroupService
edgeJob portainer.EdgeJobService
edgeStack portainer.EdgeStackService
endpoint portainer.EndpointService
endpointGroup portainer.EndpointGroupService
endpointRelation portainer.EndpointRelationService
registry portainer.RegistryService
resourceControl portainer.ResourceControlService
role portainer.RoleService
sslSettings portainer.SSLSettingsService
settings portainer.SettingsService
stack portainer.StackService
tag portainer.TagService
teamMembership portainer.TeamMembershipService
team portainer.TeamService
tunnelServer portainer.TunnelServerService
user portainer.UserService
version portainer.VersionService
webhook portainer.WebhookService
customTemplate portainer.CustomTemplateService
edgeGroup portainer.EdgeGroupService
edgeJob portainer.EdgeJobService
edgeStack portainer.EdgeStackService
endpoint portainer.EndpointService
endpointGroup portainer.EndpointGroupService
endpointRelation portainer.EndpointRelationService
helmUserRepository portainer.HelmUserRepositoryService
registry portainer.RegistryService
resourceControl portainer.ResourceControlService
role portainer.RoleService
sslSettings portainer.SSLSettingsService
settings portainer.SettingsService
stack portainer.StackService
tag portainer.TagService
teamMembership portainer.TeamMembershipService
team portainer.TeamService
tunnelServer portainer.TunnelServerService
user portainer.UserService
version portainer.VersionService
webhook portainer.WebhookService
}
func (d *datastore) BackupTo(io.Writer) error { return nil }
@@ -44,19 +46,22 @@ func (d *datastore) EdgeStack() portainer.EdgeStackService { retur
func (d *datastore) Endpoint() portainer.EndpointService { return d.endpoint }
func (d *datastore) EndpointGroup() portainer.EndpointGroupService { return d.endpointGroup }
func (d *datastore) EndpointRelation() portainer.EndpointRelationService { return d.endpointRelation }
func (d *datastore) Registry() portainer.RegistryService { return d.registry }
func (d *datastore) ResourceControl() portainer.ResourceControlService { return d.resourceControl }
func (d *datastore) Role() portainer.RoleService { return d.role }
func (d *datastore) Settings() portainer.SettingsService { return d.settings }
func (d *datastore) SSLSettings() portainer.SSLSettingsService { return d.sslSettings }
func (d *datastore) Stack() portainer.StackService { return d.stack }
func (d *datastore) Tag() portainer.TagService { return d.tag }
func (d *datastore) TeamMembership() portainer.TeamMembershipService { return d.teamMembership }
func (d *datastore) Team() portainer.TeamService { return d.team }
func (d *datastore) TunnelServer() portainer.TunnelServerService { return d.tunnelServer }
func (d *datastore) User() portainer.UserService { return d.user }
func (d *datastore) Version() portainer.VersionService { return d.version }
func (d *datastore) Webhook() portainer.WebhookService { return d.webhook }
func (d *datastore) HelmUserRepository() portainer.HelmUserRepositoryService {
return d.helmUserRepository
}
func (d *datastore) Registry() portainer.RegistryService { return d.registry }
func (d *datastore) ResourceControl() portainer.ResourceControlService { return d.resourceControl }
func (d *datastore) Role() portainer.RoleService { return d.role }
func (d *datastore) Settings() portainer.SettingsService { return d.settings }
func (d *datastore) SSLSettings() portainer.SSLSettingsService { return d.sslSettings }
func (d *datastore) Stack() portainer.StackService { return d.stack }
func (d *datastore) Tag() portainer.TagService { return d.tag }
func (d *datastore) TeamMembership() portainer.TeamMembershipService { return d.teamMembership }
func (d *datastore) Team() portainer.TeamService { return d.team }
func (d *datastore) TunnelServer() portainer.TunnelServerService { return d.tunnelServer }
func (d *datastore) User() portainer.UserService { return d.user }
func (d *datastore) Version() portainer.VersionService { return d.version }
func (d *datastore) Webhook() portainer.WebhookService { return d.webhook }
type datastoreOption = func(d *datastore)
@@ -70,21 +75,25 @@ func NewDatastore(options ...datastoreOption) *datastore {
return &d
}
type stubSettingsService struct {
settings *portainer.Settings
}
func (s *stubSettingsService) Settings() (*portainer.Settings, error) { return s.settings, nil }
func (s *stubSettingsService) UpdateSettings(settings *portainer.Settings) error { return nil }
func WithSettings(settings *portainer.Settings) datastoreOption {
func (s *stubSettingsService) Settings() (*portainer.Settings, error) {
return s.settings, nil
}
func (s *stubSettingsService) UpdateSettings(settings *portainer.Settings) error {
s.settings = settings
return nil
}
func WithSettingsService(settings *portainer.Settings) datastoreOption {
return func(d *datastore) {
d.settings = &stubSettingsService{settings: settings}
d.settings = &stubSettingsService{
settings: settings,
}
}
}
type stubUserService struct {
users []portainer.User
}
@@ -127,3 +136,106 @@ func WithEdgeJobs(js []portainer.EdgeJob) datastoreOption {
d.edgeJob = &stubEdgeJobService{jobs: js}
}
}
type stubEndpointRelationService struct {
relations []portainer.EndpointRelation
}
func (s *stubEndpointRelationService) EndpointRelations() ([]portainer.EndpointRelation, error) {
return s.relations, nil
}
func (s *stubEndpointRelationService) EndpointRelation(ID portainer.EndpointID) (*portainer.EndpointRelation, error) {
for _, relation := range s.relations {
if relation.EndpointID == ID {
return &relation, nil
}
}
return nil, errors.ErrObjectNotFound
}
func (s *stubEndpointRelationService) CreateEndpointRelation(EndpointRelation *portainer.EndpointRelation) error {
return nil
}
func (s *stubEndpointRelationService) UpdateEndpointRelation(ID portainer.EndpointID, relation *portainer.EndpointRelation) error {
for i, r := range s.relations {
if r.EndpointID == ID {
s.relations[i] = *relation
}
}
return nil
}
func (s *stubEndpointRelationService) DeleteEndpointRelation(ID portainer.EndpointID) error {
return nil
}
func (s *stubEndpointRelationService) GetNextIdentifier() int { return 0 }
// WithEndpointRelations option will instruct datastore to return provided jobs
func WithEndpointRelations(relations []portainer.EndpointRelation) datastoreOption {
return func(d *datastore) {
d.endpointRelation = &stubEndpointRelationService{relations: relations}
}
}
type stubEndpointService struct {
endpoints []portainer.Endpoint
}
func (s *stubEndpointService) Endpoint(ID portainer.EndpointID) (*portainer.Endpoint, error) {
for _, endpoint := range s.endpoints {
if endpoint.ID == ID {
return &endpoint, nil
}
}
return nil, errors.ErrObjectNotFound
}
func (s *stubEndpointService) Endpoints() ([]portainer.Endpoint, error) {
return s.endpoints, nil
}
func (s *stubEndpointService) CreateEndpoint(endpoint *portainer.Endpoint) error {
s.endpoints = append(s.endpoints, *endpoint)
return nil
}
func (s *stubEndpointService) UpdateEndpoint(ID portainer.EndpointID, endpoint *portainer.Endpoint) error {
for i, e := range s.endpoints {
if e.ID == ID {
s.endpoints[i] = *endpoint
}
}
return nil
}
func (s *stubEndpointService) DeleteEndpoint(ID portainer.EndpointID) error {
endpoints := []portainer.Endpoint{}
for _, endpoint := range s.endpoints {
if endpoint.ID != ID {
endpoints = append(endpoints, endpoint)
}
}
s.endpoints = endpoints
return nil
}
func (s *stubEndpointService) Synchronize(toCreate []*portainer.Endpoint, toUpdate []*portainer.Endpoint, toDelete []*portainer.Endpoint) error {
panic("not implemented")
}
func (s *stubEndpointService) GetNextIdentifier() int {
return len(s.endpoints)
}
// WithEndpoints option will instruct datastore to return provided environments(endpoints)
func WithEndpoints(endpoints []portainer.Endpoint) datastoreOption {
return func(d *datastore) {
d.endpoint = &stubEndpointService{endpoints: endpoints}
}
}

View File

@@ -0,0 +1,22 @@
package testhelpers
import (
"flag"
"os"
"testing"
)
var integration bool
func init() {
flag.BoolVar(&integration, "integration", false, "enable integration tests")
}
// IntegrationTest marks the current test as an integration test
func IntegrationTest(t *testing.T) {
_, enabled := os.LookupEnv("INTEGRATION_TEST")
if !(integration || enabled) {
t.Skip("Skipping integration test")
}
}

View File

@@ -0,0 +1,15 @@
package testhelpers
import "net/http"
type testRequestBouncer struct {
}
// NewTestRequestBouncer creates new mock for requestBouncer
func NewTestRequestBouncer() *testRequestBouncer {
return &testRequestBouncer{}
}
func (testRequestBouncer) AuthenticatedAccess(h http.Handler) http.Handler {
return h
}