mirror of
https://github.com/portainer/portainer.git
synced 2025-08-02 20:35:25 +02:00
feat(endpoint-groups): add endpoint-groups (#1837)
This commit is contained in:
parent
2ffcb946b1
commit
1162549209
58 changed files with 1838 additions and 265 deletions
|
@ -20,6 +20,7 @@ type Store struct {
|
|||
TeamService *TeamService
|
||||
TeamMembershipService *TeamMembershipService
|
||||
EndpointService *EndpointService
|
||||
EndpointGroupService *EndpointGroupService
|
||||
ResourceControlService *ResourceControlService
|
||||
VersionService *VersionService
|
||||
SettingsService *SettingsService
|
||||
|
@ -38,6 +39,7 @@ const (
|
|||
teamBucketName = "teams"
|
||||
teamMembershipBucketName = "team_membership"
|
||||
endpointBucketName = "endpoints"
|
||||
endpointGroupBucketName = "endpoint_groups"
|
||||
resourceControlBucketName = "resource_control"
|
||||
settingsBucketName = "settings"
|
||||
registryBucketName = "registries"
|
||||
|
@ -53,6 +55,7 @@ func NewStore(storePath string) (*Store, error) {
|
|||
TeamService: &TeamService{},
|
||||
TeamMembershipService: &TeamMembershipService{},
|
||||
EndpointService: &EndpointService{},
|
||||
EndpointGroupService: &EndpointGroupService{},
|
||||
ResourceControlService: &ResourceControlService{},
|
||||
VersionService: &VersionService{},
|
||||
SettingsService: &SettingsService{},
|
||||
|
@ -64,6 +67,7 @@ func NewStore(storePath string) (*Store, error) {
|
|||
store.TeamService.store = store
|
||||
store.TeamMembershipService.store = store
|
||||
store.EndpointService.store = store
|
||||
store.EndpointGroupService.store = store
|
||||
store.ResourceControlService.store = store
|
||||
store.VersionService.store = store
|
||||
store.SettingsService.store = store
|
||||
|
@ -94,7 +98,7 @@ func (store *Store) Open() error {
|
|||
store.db = db
|
||||
|
||||
bucketsToCreate := []string{versionBucketName, userBucketName, teamBucketName, endpointBucketName,
|
||||
resourceControlBucketName, teamMembershipBucketName, settingsBucketName,
|
||||
endpointGroupBucketName, resourceControlBucketName, teamMembershipBucketName, settingsBucketName,
|
||||
registryBucketName, dockerhubBucketName, stackBucketName}
|
||||
|
||||
return db.Update(func(tx *bolt.Tx) error {
|
||||
|
@ -110,6 +114,28 @@ func (store *Store) Open() error {
|
|||
})
|
||||
}
|
||||
|
||||
// Init creates the default data set.
|
||||
func (store *Store) Init() error {
|
||||
groups, err := store.EndpointGroupService.EndpointGroups()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(groups) == 0 {
|
||||
unassignedGroup := &portainer.EndpointGroup{
|
||||
Name: "Unassigned",
|
||||
Description: "Unassigned endpoints",
|
||||
Labels: []portainer.Pair{},
|
||||
AuthorizedUsers: []portainer.UserID{},
|
||||
AuthorizedTeams: []portainer.TeamID{},
|
||||
}
|
||||
|
||||
return store.EndpointGroupService.CreateEndpointGroup(unassignedGroup)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Close closes the BoltDB database.
|
||||
func (store *Store) Close() error {
|
||||
if store.db != nil {
|
||||
|
|
114
api/bolt/endpoint_group_service.go
Normal file
114
api/bolt/endpoint_group_service.go
Normal file
|
@ -0,0 +1,114 @@
|
|||
package bolt
|
||||
|
||||
import (
|
||||
"github.com/portainer/portainer"
|
||||
"github.com/portainer/portainer/bolt/internal"
|
||||
|
||||
"github.com/boltdb/bolt"
|
||||
)
|
||||
|
||||
// EndpointGroupService represents a service for managing endpoint groups.
|
||||
type EndpointGroupService struct {
|
||||
store *Store
|
||||
}
|
||||
|
||||
// EndpointGroup returns an endpoint group by ID.
|
||||
func (service *EndpointGroupService) EndpointGroup(ID portainer.EndpointGroupID) (*portainer.EndpointGroup, error) {
|
||||
var data []byte
|
||||
err := service.store.db.View(func(tx *bolt.Tx) error {
|
||||
bucket := tx.Bucket([]byte(endpointGroupBucketName))
|
||||
value := bucket.Get(internal.Itob(int(ID)))
|
||||
if value == nil {
|
||||
return portainer.ErrEndpointGroupNotFound
|
||||
}
|
||||
|
||||
data = make([]byte, len(value))
|
||||
copy(data, value)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var endpointGroup portainer.EndpointGroup
|
||||
err = internal.UnmarshalEndpointGroup(data, &endpointGroup)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &endpointGroup, nil
|
||||
}
|
||||
|
||||
// EndpointGroups return an array containing all the endpoint groups.
|
||||
func (service *EndpointGroupService) EndpointGroups() ([]portainer.EndpointGroup, error) {
|
||||
var endpointGroups = make([]portainer.EndpointGroup, 0)
|
||||
err := service.store.db.View(func(tx *bolt.Tx) error {
|
||||
bucket := tx.Bucket([]byte(endpointGroupBucketName))
|
||||
|
||||
cursor := bucket.Cursor()
|
||||
for k, v := cursor.First(); k != nil; k, v = cursor.Next() {
|
||||
var endpointGroup portainer.EndpointGroup
|
||||
err := internal.UnmarshalEndpointGroup(v, &endpointGroup)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
endpointGroups = append(endpointGroups, endpointGroup)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return endpointGroups, nil
|
||||
}
|
||||
|
||||
// CreateEndpointGroup assign an ID to a new endpoint group and saves it.
|
||||
func (service *EndpointGroupService) CreateEndpointGroup(endpointGroup *portainer.EndpointGroup) error {
|
||||
return service.store.db.Update(func(tx *bolt.Tx) error {
|
||||
bucket := tx.Bucket([]byte(endpointGroupBucketName))
|
||||
|
||||
id, _ := bucket.NextSequence()
|
||||
endpointGroup.ID = portainer.EndpointGroupID(id)
|
||||
|
||||
data, err := internal.MarshalEndpointGroup(endpointGroup)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = bucket.Put(internal.Itob(int(endpointGroup.ID)), data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// UpdateEndpointGroup updates an endpoint group.
|
||||
func (service *EndpointGroupService) UpdateEndpointGroup(ID portainer.EndpointGroupID, endpointGroup *portainer.EndpointGroup) error {
|
||||
data, err := internal.MarshalEndpointGroup(endpointGroup)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return service.store.db.Update(func(tx *bolt.Tx) error {
|
||||
bucket := tx.Bucket([]byte(endpointGroupBucketName))
|
||||
err = bucket.Put(internal.Itob(int(ID)), data)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
// DeleteEndpointGroup deletes an endpoint group.
|
||||
func (service *EndpointGroupService) DeleteEndpointGroup(ID portainer.EndpointGroupID) error {
|
||||
return service.store.db.Update(func(tx *bolt.Tx) error {
|
||||
bucket := tx.Bucket([]byte(endpointGroupBucketName))
|
||||
err := bucket.Delete(internal.Itob(int(ID)))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
|
@ -47,6 +47,16 @@ func UnmarshalEndpoint(data []byte, endpoint *portainer.Endpoint) error {
|
|||
return json.Unmarshal(data, endpoint)
|
||||
}
|
||||
|
||||
// MarshalEndpointGroup encodes an endpoint group to binary format.
|
||||
func MarshalEndpointGroup(group *portainer.EndpointGroup) ([]byte, error) {
|
||||
return json.Marshal(group)
|
||||
}
|
||||
|
||||
// UnmarshalEndpointGroup decodes an endpoint group from a binary data.
|
||||
func UnmarshalEndpointGroup(data []byte, group *portainer.EndpointGroup) error {
|
||||
return json.Unmarshal(data, group)
|
||||
}
|
||||
|
||||
// MarshalStack encodes a stack to binary format.
|
||||
func MarshalStack(stack *portainer.Stack) ([]byte, error) {
|
||||
return json.Marshal(stack)
|
||||
|
|
20
api/bolt/migrate_dbversion8.go
Normal file
20
api/bolt/migrate_dbversion8.go
Normal file
|
@ -0,0 +1,20 @@
|
|||
package bolt
|
||||
|
||||
import "github.com/portainer/portainer"
|
||||
|
||||
func (m *Migrator) updateEndpointsToVersion9() error {
|
||||
legacyEndpoints, err := m.EndpointService.Endpoints()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, endpoint := range legacyEndpoints {
|
||||
endpoint.GroupID = portainer.EndpointGroupID(1)
|
||||
err = m.EndpointService.UpdateEndpoint(endpoint.ID, &endpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -96,6 +96,14 @@ func (m *Migrator) Migrate() error {
|
|||
}
|
||||
}
|
||||
|
||||
// https: //github.com/portainer/portainer/issues/1396
|
||||
if m.CurrentDBVersion < 9 {
|
||||
err := m.updateEndpointsToVersion9()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
err := m.VersionService.StoreDBVersion(portainer.DBVersion)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue