Compare commits
3 Commits
develop
...
feat/EE-47
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d33b69ebbf | ||
|
|
8265c22349 | ||
|
|
1c65eb228a |
@@ -48,6 +48,7 @@ func (store *Store) MigrateData() error {
|
||||
|
||||
err = store.FailSafeMigrate(migrator, version)
|
||||
if err != nil {
|
||||
log.Error().Err(err).Msg("migration failed, restoring database to previous version")
|
||||
err = store.restoreWithOptions(&BackupOptions{BackupPath: backupPath})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "failed to restore database")
|
||||
|
||||
@@ -26,7 +26,7 @@ func (m *Migrator) migrateDBVersionToDB70() error {
|
||||
snapshot.Docker = &endpoint.Snapshots[len(endpoint.Snapshots)-1]
|
||||
}
|
||||
|
||||
if len(endpoint.Kubernetes.Snapshots) > 0 {
|
||||
if endpoint.Kubernetes != nil && len(endpoint.Kubernetes.Snapshots) > 0 {
|
||||
snapshot.Kubernetes = &endpoint.Kubernetes.Snapshots[len(endpoint.Kubernetes.Snapshots)-1]
|
||||
}
|
||||
|
||||
@@ -39,7 +39,10 @@ func (m *Migrator) migrateDBVersionToDB70() error {
|
||||
// set to nil old fields
|
||||
log.Info().Msg("deleting snapshot from endpoint")
|
||||
endpoint.Snapshots = []portainer.DockerSnapshot{}
|
||||
endpoint.Kubernetes.Snapshots = []portainer.KubernetesSnapshot{}
|
||||
|
||||
if endpoint.Kubernetes != nil {
|
||||
endpoint.Kubernetes.Snapshots = []portainer.KubernetesSnapshot{}
|
||||
}
|
||||
|
||||
// update endpoint
|
||||
err = m.endpointService.UpdateEndpoint(endpoint.ID, &endpoint)
|
||||
@@ -58,9 +61,11 @@ func (m *Migrator) updateIngressFieldsForEnvDB70() error {
|
||||
}
|
||||
|
||||
for _, endpoint := range endpoints {
|
||||
endpoint.Kubernetes.Configuration.IngressAvailabilityPerNamespace = true
|
||||
endpoint.Kubernetes.Configuration.AllowNoneIngressClass = false
|
||||
endpoint.PostInitMigrations.MigrateIngresses = true
|
||||
if endpoint.Kubernetes != nil {
|
||||
endpoint.Kubernetes.Configuration.IngressAvailabilityPerNamespace = true
|
||||
endpoint.Kubernetes.Configuration.AllowNoneIngressClass = false
|
||||
endpoint.PostInitMigrations.MigrateIngresses = true
|
||||
}
|
||||
|
||||
err = m.endpointService.UpdateEndpoint(endpoint.ID, &endpoint)
|
||||
if err != nil {
|
||||
|
||||
@@ -7,22 +7,6 @@ import (
|
||||
"github.com/rs/zerolog/log"
|
||||
)
|
||||
|
||||
func (m *Migrator) migrateDBVersionToDB80() error {
|
||||
if err := m.updateEdgeStackStatusForDB80(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := m.updateExistingEndpointsToNotDetectMetricsAPIForDB80(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := m.updateExistingEndpointsToNotDetectStorageAPIForDB80(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *Migrator) updateExistingEndpointsToNotDetectMetricsAPIForDB80() error {
|
||||
log.Info().Msg("updating existing endpoints to not detect metrics API for existing endpoints (k8s)")
|
||||
|
||||
|
||||
@@ -6,10 +6,6 @@ import (
|
||||
portainerDsErrors "github.com/portainer/portainer/api/dataservices/errors"
|
||||
)
|
||||
|
||||
func (m *Migrator) migrateDBVersionToDB81() error {
|
||||
return m.updateEdgeStackStatusForDB81()
|
||||
}
|
||||
|
||||
func (m *Migrator) updateEdgeStackStatusForDB81() error {
|
||||
log.Info().Msg("clean up deleted endpoints from edge jobs")
|
||||
|
||||
|
||||
@@ -208,11 +208,17 @@ func (m *Migrator) initMigrations() {
|
||||
m.addMigrations("2.15", m.migrateDBVersionToDB60)
|
||||
m.addMigrations("2.16", m.migrateDBVersionToDB70)
|
||||
m.addMigrations("2.16.1", m.migrateDBVersionToDB71)
|
||||
m.addMigrations("2.17", m.migrateDBVersionToDB80)
|
||||
m.addMigrations("2.18", m.migrateDBVersionToDB81)
|
||||
|
||||
// Add new migrations below...
|
||||
// One function per migration, each versions migration funcs in the same file.
|
||||
m.addMigrations("2.17",
|
||||
m.updateEdgeStackStatusForDB80,
|
||||
m.updateExistingEndpointsToNotDetectMetricsAPIForDB80,
|
||||
m.updateExistingEndpointsToNotDetectStorageAPIForDB80,
|
||||
)
|
||||
|
||||
m.addMigrations("2.18", m.updateEdgeStackStatusForDB81)
|
||||
|
||||
// Add new migrations above...
|
||||
// One function per migration, each versions migration funcs in the same file, but called like above.
|
||||
}
|
||||
|
||||
// Always is always run at the end of migrations
|
||||
|
||||
@@ -30,16 +30,12 @@
|
||||
"Agent": {
|
||||
"Version": ""
|
||||
},
|
||||
"AuthorizedTeams": null,
|
||||
"AuthorizedUsers": null,
|
||||
"AzureCredentials": {
|
||||
"ApplicationID": "",
|
||||
"AuthenticationKey": "",
|
||||
"TenantID": ""
|
||||
},
|
||||
"ComposeSyntaxMaxVersion": "",
|
||||
"Edge": {
|
||||
"AsyncMode": false,
|
||||
"CommandInterval": 0,
|
||||
"PingInterval": 0,
|
||||
"SnapshotInterval": 0
|
||||
@@ -49,32 +45,11 @@
|
||||
"Gpus": [],
|
||||
"GroupId": 1,
|
||||
"Id": 1,
|
||||
"IsEdgeDevice": false,
|
||||
"Kubernetes": {
|
||||
"Configuration": {
|
||||
"AllowNoneIngressClass": false,
|
||||
"EnableResourceOverCommit": false,
|
||||
"IngressAvailabilityPerNamespace": true,
|
||||
"IngressClasses": null,
|
||||
"ResourceOverCommitPercentage": 0,
|
||||
"RestrictDefaultNamespace": false,
|
||||
"StorageClasses": null,
|
||||
"UseLoadBalancer": false,
|
||||
"UseServerMetrics": false
|
||||
},
|
||||
"Flags": {
|
||||
"IsServerMetricsDetected": false,
|
||||
"IsServerStorageDetected": false
|
||||
},
|
||||
"Snapshots": []
|
||||
},
|
||||
"LastCheckInDate": 0,
|
||||
"Name": "local",
|
||||
"PostInitMigrations": {
|
||||
"MigrateIngresses": true
|
||||
"MigrateIngresses": false
|
||||
},
|
||||
"PublicURL": "",
|
||||
"QueryDate": 0,
|
||||
"PublicURL.omitempty": "",
|
||||
"SecuritySettings": {
|
||||
"allowBindMountsForRegularUsers": true,
|
||||
"allowContainerCapabilitiesForRegularUsers": true,
|
||||
@@ -93,12 +68,10 @@
|
||||
"TLSSkipVerify": false
|
||||
},
|
||||
"TagIds": [],
|
||||
"Tags": null,
|
||||
"TeamAccessPolicies": {},
|
||||
"Type": 1,
|
||||
"URL": "unix:///var/run/docker.sock",
|
||||
"UserAccessPolicies": {},
|
||||
"UserTrusted": false
|
||||
"UserAccessPolicies": {}
|
||||
}
|
||||
],
|
||||
"registries": [
|
||||
|
||||
@@ -319,14 +319,14 @@ func (handler *Handler) createEndpoint(payload *endpointCreatePayload) (*portain
|
||||
}
|
||||
|
||||
func (handler *Handler) createAzureEndpoint(payload *endpointCreatePayload) (*portainer.Endpoint, *httperror.HandlerError) {
|
||||
credentials := portainer.AzureCredentials{
|
||||
credentials := &portainer.AzureCredentials{
|
||||
ApplicationID: payload.AzureApplicationID,
|
||||
TenantID: payload.AzureTenantID,
|
||||
AuthenticationKey: payload.AzureAuthenticationKey,
|
||||
}
|
||||
|
||||
httpClient := client.NewHTTPClient()
|
||||
_, err := httpClient.ExecuteAzureAuthenticationRequest(&credentials)
|
||||
_, err := httpClient.ExecuteAzureAuthenticationRequest(credentials)
|
||||
if err != nil {
|
||||
return nil, httperror.InternalServerError("Unable to authenticate against Azure", err)
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) *
|
||||
updateAuthorizations = true
|
||||
}
|
||||
|
||||
endpoint.Kubernetes = *payload.Kubernetes
|
||||
endpoint.Kubernetes = payload.Kubernetes
|
||||
}
|
||||
|
||||
if payload.UserAccessPolicies != nil && !reflect.DeepEqual(payload.UserAccessPolicies, endpoint.UserAccessPolicies) {
|
||||
@@ -208,7 +208,7 @@ func (handler *Handler) endpointUpdate(w http.ResponseWriter, r *http.Request) *
|
||||
}
|
||||
|
||||
httpClient := client.NewHTTPClient()
|
||||
_, authErr := httpClient.ExecuteAzureAuthenticationRequest(&credentials)
|
||||
_, authErr := httpClient.ExecuteAzureAuthenticationRequest(credentials)
|
||||
if authErr != nil {
|
||||
return httperror.InternalServerError("Unable to authenticate against Azure", authErr)
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
)
|
||||
|
||||
func hideFields(endpoint *portainer.Endpoint) {
|
||||
endpoint.AzureCredentials = portainer.AzureCredentials{}
|
||||
endpoint.AzureCredentials = &portainer.AzureCredentials{}
|
||||
if len(endpoint.Snapshots) > 0 {
|
||||
endpoint.Snapshots[0].SnapshotRaw = portainer.DockerSnapshotRaw{}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,6 @@ func newAzureProxy(endpoint *portainer.Endpoint, dataStore dataservices.DataStor
|
||||
}
|
||||
|
||||
proxy := newSingleHostReverseProxyWithHostHeader(remoteURL)
|
||||
proxy.Transport = azure.NewTransport(&endpoint.AzureCredentials, dataStore, endpoint)
|
||||
proxy.Transport = azure.NewTransport(endpoint.AzureCredentials, dataStore, endpoint)
|
||||
return proxy, nil
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ func countNodes(endpoint *portainer.Endpoint) int {
|
||||
return max(endpoint.Snapshots[0].NodeCount, 1)
|
||||
}
|
||||
|
||||
if len(endpoint.Kubernetes.Snapshots) == 1 {
|
||||
if endpoint.Kubernetes != nil && len(endpoint.Kubernetes.Snapshots) == 1 {
|
||||
return max(endpoint.Kubernetes.Snapshots[0].NodeCount, 1)
|
||||
}
|
||||
|
||||
|
||||
@@ -131,7 +131,10 @@ func FillSnapshotData(dataStore dataservices.DataStore, endpoint *portainer.Endp
|
||||
snapshot, err := dataStore.Snapshot().Snapshot(endpoint.ID)
|
||||
if dataStore.IsErrObjectNotFound(err) {
|
||||
endpoint.Snapshots = []portainer.DockerSnapshot{}
|
||||
endpoint.Kubernetes.Snapshots = []portainer.KubernetesSnapshot{}
|
||||
|
||||
if endpoint.Kubernetes != nil {
|
||||
endpoint.Kubernetes.Snapshots = []portainer.KubernetesSnapshot{}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package portainer
|
||||
|
||||
func KubernetesDefault() KubernetesData {
|
||||
return KubernetesData{
|
||||
func KubernetesDefault() *KubernetesData {
|
||||
return &KubernetesData{
|
||||
Configuration: KubernetesConfiguration{
|
||||
UseLoadBalancer: false,
|
||||
UseServerMetrics: false,
|
||||
|
||||
@@ -336,10 +336,10 @@ type (
|
||||
// Environment(Endpoint) group identifier
|
||||
GroupID EndpointGroupID `json:"GroupId" example:"1"`
|
||||
// URL or IP address where exposed containers will be reachable
|
||||
PublicURL string `json:"PublicURL" example:"docker.mydomain.tld:2375"`
|
||||
Gpus []Pair `json:"Gpus"`
|
||||
TLSConfig TLSConfiguration `json:"TLSConfig"`
|
||||
AzureCredentials AzureCredentials `json:"AzureCredentials,omitempty"`
|
||||
PublicURL string `json:"PublicURL.omitempty" example:"docker.mydomain.tld:2375"`
|
||||
Gpus []Pair `json:"Gpus"`
|
||||
TLSConfig TLSConfiguration `json:"TLSConfig"`
|
||||
AzureCredentials *AzureCredentials `json:"AzureCredentials,omitempty"`
|
||||
// List of tag identifiers to which this environment(endpoint) is associated
|
||||
TagIDs []TagID `json:"TagIds"`
|
||||
// The status of the environment(endpoint) (1 - up, 2 - down)
|
||||
@@ -357,35 +357,26 @@ type (
|
||||
// The check in interval for edge agent (in seconds)
|
||||
EdgeCheckinInterval int `json:"EdgeCheckinInterval" example:"5"`
|
||||
// Associated Kubernetes data
|
||||
Kubernetes KubernetesData `json:"Kubernetes"`
|
||||
Kubernetes *KubernetesData `json:"Kubernetes,omitempty"`
|
||||
// Maximum version of docker-compose
|
||||
ComposeSyntaxMaxVersion string `json:"ComposeSyntaxMaxVersion" example:"3.8"`
|
||||
ComposeSyntaxMaxVersion string `json:"ComposeSyntaxMaxVersion,omitempty" example:"3.8"`
|
||||
// Environment(Endpoint) specific security settings
|
||||
SecuritySettings EndpointSecuritySettings
|
||||
// The identifier of the AMT Device associated with this environment(endpoint)
|
||||
AMTDeviceGUID string `json:"AMTDeviceGUID,omitempty" example:"4c4c4544-004b-3910-8037-b6c04f504633"`
|
||||
// LastCheckInDate mark last check-in date on checkin
|
||||
LastCheckInDate int64
|
||||
LastCheckInDate int64 `json:",omitempty"`
|
||||
// QueryDate of each query with the endpoints list
|
||||
QueryDate int64
|
||||
QueryDate int64 `json:",omitempty"`
|
||||
// IsEdgeDevice marks if the environment was created as an EdgeDevice
|
||||
IsEdgeDevice bool
|
||||
IsEdgeDevice bool `json:",omitempty"`
|
||||
// Whether the device has been trusted or not by the user
|
||||
UserTrusted bool
|
||||
UserTrusted bool `json:",omitempty"`
|
||||
|
||||
// Whether we need to run any "post init migrations".
|
||||
PostInitMigrations EndpointPostInitMigrations `json:"PostInitMigrations"`
|
||||
|
||||
Edge struct {
|
||||
// Whether the device has been started in edge async mode
|
||||
AsyncMode bool
|
||||
// The ping interval for edge agent - used in edge async mode [seconds]
|
||||
PingInterval int `json:"PingInterval" example:"60"`
|
||||
// The snapshot interval for edge agent - used in edge async mode [seconds]
|
||||
SnapshotInterval int `json:"SnapshotInterval" example:"60"`
|
||||
// The command list interval for edge agent - used in edge async mode [seconds]
|
||||
CommandInterval int `json:"CommandInterval" example:"60"`
|
||||
}
|
||||
Edge EdgeSettings
|
||||
|
||||
Agent struct {
|
||||
Version string `example:"1.0.0"`
|
||||
@@ -399,11 +390,22 @@ type (
|
||||
TLSKeyPath string `json:"TLSKey,omitempty"`
|
||||
|
||||
// Deprecated in DBVersion == 18
|
||||
AuthorizedUsers []UserID `json:"AuthorizedUsers"`
|
||||
AuthorizedTeams []TeamID `json:"AuthorizedTeams"`
|
||||
AuthorizedUsers []UserID `json:"AuthorizedUsers,omitempty"`
|
||||
AuthorizedTeams []TeamID `json:"AuthorizedTeams,omitempty"`
|
||||
|
||||
// Deprecated in DBVersion == 22
|
||||
Tags []string `json:"Tags"`
|
||||
Tags []string `json:"Tags,omitempty"`
|
||||
}
|
||||
|
||||
EdgeSettings struct {
|
||||
// Whether the device has been started in edge async mode
|
||||
AsyncMode bool `json:"AsyncMode,omitempty" example:"false"`
|
||||
// The ping interval for edge agent - used in edge async mode [seconds]
|
||||
PingInterval int `json:"PingInterval" example:"60"`
|
||||
// The snapshot interval for edge agent - used in edge async mode [seconds]
|
||||
SnapshotInterval int `json:"SnapshotInterval" example:"60"`
|
||||
// The command list interval for edge agent - used in edge async mode [seconds]
|
||||
CommandInterval int `json:"CommandInterval" example:"60"`
|
||||
}
|
||||
|
||||
// EndpointAuthorizations represents the authorizations associated to a set of environments(endpoints)
|
||||
@@ -579,15 +581,15 @@ type (
|
||||
|
||||
// KubernetesConfiguration represents the configuration of a Kubernetes environment(endpoint)
|
||||
KubernetesConfiguration struct {
|
||||
UseLoadBalancer bool `json:"UseLoadBalancer"`
|
||||
UseServerMetrics bool `json:"UseServerMetrics"`
|
||||
EnableResourceOverCommit bool `json:"EnableResourceOverCommit"`
|
||||
ResourceOverCommitPercentage int `json:"ResourceOverCommitPercentage"`
|
||||
UseLoadBalancer bool `json:"UseLoadBalancer,omitempty"`
|
||||
UseServerMetrics bool `json:"UseServerMetrics,omitempty"`
|
||||
EnableResourceOverCommit bool `json:"EnableResourceOverCommit,omitempty"`
|
||||
ResourceOverCommitPercentage int `json:"ResourceOverCommitPercentage,omitempty"`
|
||||
StorageClasses []KubernetesStorageClassConfig `json:"StorageClasses"`
|
||||
IngressClasses []KubernetesIngressClassConfig `json:"IngressClasses"`
|
||||
RestrictDefaultNamespace bool `json:"RestrictDefaultNamespace"`
|
||||
IngressAvailabilityPerNamespace bool `json:"IngressAvailabilityPerNamespace"`
|
||||
AllowNoneIngressClass bool `json:"AllowNoneIngressClass"`
|
||||
RestrictDefaultNamespace bool `json:"RestrictDefaultNamespace,omitempty"`
|
||||
IngressAvailabilityPerNamespace bool `json:"IngressAvailabilityPerNamespace,omitempty"`
|
||||
AllowNoneIngressClass bool `json:"AllowNoneIngressClass,omitempty"`
|
||||
}
|
||||
|
||||
// KubernetesStorageClassConfig represents a Kubernetes Storage Class configuration
|
||||
|
||||
Reference in New Issue
Block a user