1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-08-09 15:55:23 +02:00

WIP: commented error code and set CGO_ENABLED to 1

This commit is contained in:
Prabhat Khera 2023-04-19 13:32:27 +12:00
parent 8fd67d8320
commit 52142c3151
22 changed files with 251 additions and 277 deletions

View file

@ -24,7 +24,6 @@ require (
github.com/go-playground/validator/v10 v10.12.0 github.com/go-playground/validator/v10 v10.12.0
github.com/gofrs/uuid v4.2.0+incompatible github.com/gofrs/uuid v4.2.0+incompatible
github.com/golang-jwt/jwt/v4 v4.2.0 github.com/golang-jwt/jwt/v4 v4.2.0
github.com/google/go-cmp v0.5.9
github.com/gorilla/handlers v1.5.1 github.com/gorilla/handlers v1.5.1
github.com/gorilla/mux v1.8.0 github.com/gorilla/mux v1.8.0
github.com/gorilla/securecookie v1.1.1 github.com/gorilla/securecookie v1.1.1
@ -54,6 +53,8 @@ require (
golang.org/x/sync v0.1.0 golang.org/x/sync v0.1.0
gopkg.in/alecthomas/kingpin.v2 v2.2.6 gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/yaml.v3 v3.0.1 gopkg.in/yaml.v3 v3.0.1
gorm.io/driver/sqlite v1.5.0
gorm.io/gorm v1.25.0
k8s.io/api v0.26.1 k8s.io/api v0.26.1
k8s.io/apimachinery v0.26.1 k8s.io/apimachinery v0.26.1
k8s.io/client-go v0.26.1 k8s.io/client-go v0.26.1
@ -98,12 +99,15 @@ require (
github.com/golang/protobuf v1.5.3 // indirect github.com/golang/protobuf v1.5.3 // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/golang/snappy v0.0.4 // indirect
github.com/google/gnostic v0.5.7-v3refs // indirect github.com/google/gnostic v0.5.7-v3refs // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.2.0 // indirect github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/imdario/mergo v0.3.15 // indirect github.com/imdario/mergo v0.3.15 // indirect
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/josharian/intern v1.0.0 // indirect github.com/josharian/intern v1.0.0 // indirect
github.com/jpillora/ansi v1.0.2 // indirect github.com/jpillora/ansi v1.0.2 // indirect
@ -116,6 +120,7 @@ require (
github.com/mailru/easyjson v0.7.7 // indirect github.com/mailru/easyjson v0.7.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-sqlite3 v1.14.15 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/spdystream v0.2.0 // indirect github.com/moby/spdystream v0.2.0 // indirect

View file

@ -224,6 +224,10 @@ github.com/imdario/mergo v0.3.15/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+h
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=

View file

@ -5,11 +5,9 @@ import (
"net/http" "net/http"
httperror "github.com/portainer/libhttp/error" httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
portainer "github.com/portainer/portainer/api" portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/dataservices" "github.com/portainer/portainer/api/dataservices"
"github.com/portainer/portainer/api/internal/edge" "github.com/portainer/portainer/api/internal/edge"
"github.com/portainer/portainer/api/internal/endpointutils"
"github.com/portainer/portainer/api/internal/slices" "github.com/portainer/portainer/api/internal/slices"
"github.com/asaskevich/govalidator" "github.com/asaskevich/govalidator"
@ -54,122 +52,123 @@ func (payload *edgeGroupUpdatePayload) Validate(r *http.Request) error {
// @failure 500 // @failure 500
// @router /edge_groups/{id} [put] // @router /edge_groups/{id} [put]
func (handler *Handler) edgeGroupUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { func (handler *Handler) edgeGroupUpdate(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
edgeGroupID, err := request.RetrieveNumericRouteVariableValue(r, "id") // edgeGroupID, err := request.RetrieveNumericRouteVariableValue(r, "id")
if err != nil { // if err != nil {
return httperror.BadRequest("Invalid Edge group identifier route variable", err) // return httperror.BadRequest("Invalid Edge group identifier route variable", err)
} // }
var payload edgeGroupUpdatePayload // var payload edgeGroupUpdatePayload
err = request.DecodeAndValidateJSONPayload(r, &payload) // err = request.DecodeAndValidateJSONPayload(r, &payload)
if err != nil { // if err != nil {
return httperror.BadRequest("Invalid request payload", err) // return httperror.BadRequest("Invalid request payload", err)
} // }
var edgeGroup *portainer.EdgeGroup // var edgeGroup *portainer.EdgeGroup
err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error { // err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
edgeGroup, err = tx.EdgeGroup().EdgeGroup(portainer.EdgeGroupID(edgeGroupID)) // edgeGroup, err = tx.EdgeGroup().EdgeGroup(portainer.EdgeGroupID(edgeGroupID))
if handler.DataStore.IsErrObjectNotFound(err) { // if handler.DataStore.IsErrObjectNotFound(err) {
return httperror.NotFound("Unable to find an Edge group with the specified identifier inside the database", err) // return httperror.NotFound("Unable to find an Edge group with the specified identifier inside the database", err)
} else if err != nil { // } else if err != nil {
return httperror.InternalServerError("Unable to find an Edge group with the specified identifier inside the database", err) // return httperror.InternalServerError("Unable to find an Edge group with the specified identifier inside the database", err)
} // }
if payload.Name != "" { // if payload.Name != "" {
edgeGroups, err := tx.EdgeGroup().EdgeGroups() // edgeGroups, err := tx.EdgeGroup().EdgeGroups()
if err != nil { // if err != nil {
return httperror.InternalServerError("Unable to retrieve Edge groups from the database", err) // return httperror.InternalServerError("Unable to retrieve Edge groups from the database", err)
} // }
for _, edgeGroup := range edgeGroups { // for _, edgeGroup := range edgeGroups {
if edgeGroup.Name == payload.Name && edgeGroup.ID != portainer.EdgeGroupID(edgeGroupID) { // if edgeGroup.Name == payload.Name && edgeGroup.ID != portainer.EdgeGroupID(edgeGroupID) {
return httperror.BadRequest("Edge group name must be unique", errors.New("edge group name must be unique")) // return httperror.BadRequest("Edge group name must be unique", errors.New("edge group name must be unique"))
} // }
} // }
edgeGroup.Name = payload.Name // edgeGroup.Name = payload.Name
} // }
endpoints, err := tx.Endpoint().Endpoints() // endpoints, err := tx.Endpoint().Endpoints()
if err != nil { // if err != nil {
return httperror.InternalServerError("Unable to retrieve environments from database", err) // return httperror.InternalServerError("Unable to retrieve environments from database", err)
} // }
endpointGroups, err := tx.EndpointGroup().EndpointGroups() // endpointGroups, err := tx.EndpointGroup().EndpointGroups()
if err != nil { // if err != nil {
return httperror.InternalServerError("Unable to retrieve environment groups from database", err) // return httperror.InternalServerError("Unable to retrieve environment groups from database", err)
} // }
oldRelatedEndpoints := edge.EdgeGroupRelatedEndpoints(edgeGroup, endpoints, endpointGroups) // oldRelatedEndpoints := edge.EdgeGroupRelatedEndpoints(edgeGroup, endpoints, endpointGroups)
edgeGroup.Dynamic = payload.Dynamic // edgeGroup.Dynamic = payload.Dynamic
if edgeGroup.Dynamic { // if edgeGroup.Dynamic {
edgeGroup.TagIDs = payload.TagIDs // edgeGroup.TagIDs = payload.TagIDs
} else { // } else {
endpointIDs := []portainer.EndpointID{} // endpointIDs := []portainer.EndpointID{}
for _, endpointID := range payload.Endpoints { // for _, endpointID := range payload.Endpoints {
endpoint, err := tx.Endpoint().Endpoint(endpointID) // endpoint, err := tx.Endpoint().Endpoint(endpointID)
if err != nil { // if err != nil {
return httperror.InternalServerError("Unable to retrieve environment from the database", err) // return httperror.InternalServerError("Unable to retrieve environment from the database", err)
} // }
if endpointutils.IsEdgeEndpoint(endpoint) { // if endpointutils.IsEdgeEndpoint(endpoint) {
endpointIDs = append(endpointIDs, endpoint.ID) // endpointIDs = append(endpointIDs, endpoint.ID)
} // }
} // }
edgeGroup.Endpoints = endpointIDs // edgeGroup.Endpoints = endpointIDs
} // }
if payload.PartialMatch != nil { // if payload.PartialMatch != nil {
edgeGroup.PartialMatch = *payload.PartialMatch // edgeGroup.PartialMatch = *payload.PartialMatch
} // }
err = tx.EdgeGroup().UpdateEdgeGroup(edgeGroup.ID, edgeGroup) // err = tx.EdgeGroup().UpdateEdgeGroup(edgeGroup.ID, edgeGroup)
if err != nil { // if err != nil {
return httperror.InternalServerError("Unable to persist Edge group changes inside the database", err) // return httperror.InternalServerError("Unable to persist Edge group changes inside the database", err)
} // }
newRelatedEndpoints := edge.EdgeGroupRelatedEndpoints(edgeGroup, endpoints, endpointGroups) // newRelatedEndpoints := edge.EdgeGroupRelatedEndpoints(edgeGroup, endpoints, endpointGroups)
endpointsToUpdate := append(newRelatedEndpoints, oldRelatedEndpoints...) // endpointsToUpdate := append(newRelatedEndpoints, oldRelatedEndpoints...)
edgeJobs, err := tx.EdgeJob().EdgeJobs() // edgeJobs, err := tx.EdgeJob().EdgeJobs()
if err != nil { // if err != nil {
return httperror.InternalServerError("Unable to fetch Edge jobs", err) // return httperror.InternalServerError("Unable to fetch Edge jobs", err)
} // }
for _, endpointID := range endpointsToUpdate { // for _, endpointID := range endpointsToUpdate {
err = handler.updateEndpointStacks(tx, endpointID) // err = handler.updateEndpointStacks(tx, endpointID)
if err != nil { // if err != nil {
return httperror.InternalServerError("Unable to persist Environment relation changes inside the database", err) // return httperror.InternalServerError("Unable to persist Environment relation changes inside the database", err)
} // }
endpoint, err := tx.Endpoint().Endpoint(endpointID) // endpoint, err := tx.Endpoint().Endpoint(endpointID)
if err != nil { // if err != nil {
return httperror.InternalServerError("Unable to get Environment from database", err) // return httperror.InternalServerError("Unable to get Environment from database", err)
} // }
if !endpointutils.IsEdgeEndpoint(endpoint) { // if !endpointutils.IsEdgeEndpoint(endpoint) {
continue // continue
} // }
var operation string // var operation string
if slices.Contains(newRelatedEndpoints, endpointID) { // if slices.Contains(newRelatedEndpoints, endpointID) {
operation = "add" // operation = "add"
} else if slices.Contains(oldRelatedEndpoints, endpointID) { // } else if slices.Contains(oldRelatedEndpoints, endpointID) {
operation = "remove" // operation = "remove"
} else { // } else {
continue // continue
} // }
err = handler.updateEndpointEdgeJobs(edgeGroup.ID, endpoint, edgeJobs, operation) // err = handler.updateEndpointEdgeJobs(edgeGroup.ID, endpoint, edgeJobs, operation)
if err != nil { // if err != nil {
return httperror.InternalServerError("Unable to persist Environment Edge Jobs changes inside the database", err) // return httperror.InternalServerError("Unable to persist Environment Edge Jobs changes inside the database", err)
} // }
} // }
return nil // return nil
}) // })
return txResponse(w, edgeGroup, err) // return txResponse(w, edgeGroup, err)
return nil
} }
func (handler *Handler) updateEndpointStacks(tx dataservices.DataStoreTx, endpointID portainer.EndpointID) error { func (handler *Handler) updateEndpointStacks(tx dataservices.DataStoreTx, endpointID portainer.EndpointID) error {

View file

@ -95,11 +95,11 @@ func (handler *Handler) createEdgeJobFromFileContent(w http.ResponseWriter, r *h
if featureflags.IsEnabled(portainer.FeatureNoTx) { if featureflags.IsEnabled(portainer.FeatureNoTx) {
edgeJob, err = handler.createEdgeJob(handler.DataStore, &payload.edgeJobBasePayload, []byte(payload.FileContent)) edgeJob, err = handler.createEdgeJob(handler.DataStore, &payload.edgeJobBasePayload, []byte(payload.FileContent))
} else { } else {
err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error { // err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
edgeJob, err = handler.createEdgeJob(tx, &payload.edgeJobBasePayload, []byte(payload.FileContent)) // edgeJob, err = handler.createEdgeJob(tx, &payload.edgeJobBasePayload, []byte(payload.FileContent))
return err // return err
}) // })
} }
return txResponse(w, edgeJob, err) return txResponse(w, edgeJob, err)
@ -204,11 +204,11 @@ func (handler *Handler) createEdgeJobFromFile(w http.ResponseWriter, r *http.Req
if featureflags.IsEnabled(portainer.FeatureNoTx) { if featureflags.IsEnabled(portainer.FeatureNoTx) {
edgeJob, err = handler.createEdgeJob(handler.DataStore, &payload.edgeJobBasePayload, payload.File) edgeJob, err = handler.createEdgeJob(handler.DataStore, &payload.edgeJobBasePayload, payload.File)
} else { } else {
err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error { // err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
edgeJob, err = handler.createEdgeJob(tx, &payload.edgeJobBasePayload, payload.File) // edgeJob, err = handler.createEdgeJob(tx, &payload.edgeJobBasePayload, payload.File)
return err // return err
}) // })
} }
return txResponse(w, edgeJob, err) return txResponse(w, edgeJob, err)
@ -216,7 +216,6 @@ func (handler *Handler) createEdgeJobFromFile(w http.ResponseWriter, r *http.Req
func (handler *Handler) createEdgeJobObjectFromPayload(tx dataservices.DataStoreTx, payload *edgeJobBasePayload) *portainer.EdgeJob { func (handler *Handler) createEdgeJobObjectFromPayload(tx dataservices.DataStoreTx, payload *edgeJobBasePayload) *portainer.EdgeJob {
return &portainer.EdgeJob{ return &portainer.EdgeJob{
ID: portainer.EdgeJobID(tx.EdgeJob().GetNextIdentifier()),
Name: payload.Name, Name: payload.Name,
CronExpression: payload.CronExpression, CronExpression: payload.CronExpression,
Recurring: payload.Recurring, Recurring: payload.Recurring,

View file

@ -37,9 +37,9 @@ func (handler *Handler) edgeJobDelete(w http.ResponseWriter, r *http.Request) *h
if featureflags.IsEnabled(portainer.FeatureNoTx) { if featureflags.IsEnabled(portainer.FeatureNoTx) {
err = handler.deleteEdgeJob(handler.DataStore, portainer.EdgeJobID(edgeJobID)) err = handler.deleteEdgeJob(handler.DataStore, portainer.EdgeJobID(edgeJobID))
} else { } else {
err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error { // err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
return handler.deleteEdgeJob(tx, portainer.EdgeJobID(edgeJobID)) // return handler.deleteEdgeJob(tx, portainer.EdgeJobID(edgeJobID))
}) // })
} }
if err != nil { if err != nil {

View file

@ -64,15 +64,15 @@ func (handler *Handler) edgeJobTasksClear(w http.ResponseWriter, r *http.Request
err = handler.clearEdgeJobTaskLogs(handler.DataStore, portainer.EdgeJobID(edgeJobID), portainer.EndpointID(taskID), updateEdgeJobFn) err = handler.clearEdgeJobTaskLogs(handler.DataStore, portainer.EdgeJobID(edgeJobID), portainer.EndpointID(taskID), updateEdgeJobFn)
} else { } else {
err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error { // err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
updateEdgeJobFn := func(edgeJob *portainer.EdgeJob, endpointID portainer.EndpointID, endpointsFromGroups []portainer.EndpointID) error { // updateEdgeJobFn := func(edgeJob *portainer.EdgeJob, endpointID portainer.EndpointID, endpointsFromGroups []portainer.EndpointID) error {
mutationFn(edgeJob, endpointID, endpointsFromGroups) // mutationFn(edgeJob, endpointID, endpointsFromGroups)
return tx.EdgeJob().UpdateEdgeJob(edgeJob.ID, edgeJob) // return tx.EdgeJob().UpdateEdgeJob(edgeJob.ID, edgeJob)
} // }
return handler.clearEdgeJobTaskLogs(tx, portainer.EdgeJobID(edgeJobID), portainer.EndpointID(taskID), updateEdgeJobFn) // return handler.clearEdgeJobTaskLogs(tx, portainer.EdgeJobID(edgeJobID), portainer.EndpointID(taskID), updateEdgeJobFn)
}) // })
} }
if err != nil { if err != nil {

View file

@ -1,16 +1,10 @@
package edgejobs package edgejobs
import ( import (
"errors"
"net/http" "net/http"
httperror "github.com/portainer/libhttp/error" httperror "github.com/portainer/libhttp/error"
"github.com/portainer/libhttp/request"
"github.com/portainer/libhttp/response" "github.com/portainer/libhttp/response"
portainer "github.com/portainer/portainer/api"
"github.com/portainer/portainer/api/dataservices"
"github.com/portainer/portainer/api/internal/edge"
"github.com/portainer/portainer/api/internal/slices"
) )
// @id EdgeJobTasksCollect // @id EdgeJobTasksCollect
@ -28,69 +22,69 @@ import (
// @failure 503 "Edge compute features are disabled" // @failure 503 "Edge compute features are disabled"
// @router /edge_jobs/{id}/tasks/{taskID}/logs [post] // @router /edge_jobs/{id}/tasks/{taskID}/logs [post]
func (handler *Handler) edgeJobTasksCollect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError { func (handler *Handler) edgeJobTasksCollect(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id") // edgeJobID, err := request.RetrieveNumericRouteVariableValue(r, "id")
if err != nil { // if err != nil {
return httperror.BadRequest("Invalid Edge job identifier route variable", err) // return httperror.BadRequest("Invalid Edge job identifier route variable", err)
} // }
taskID, err := request.RetrieveNumericRouteVariableValue(r, "taskID") // taskID, err := request.RetrieveNumericRouteVariableValue(r, "taskID")
if err != nil { // if err != nil {
return httperror.BadRequest("Invalid Task identifier route variable", err) // return httperror.BadRequest("Invalid Task identifier route variable", err)
} // }
err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error { // err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
edgeJob, err := tx.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID)) // edgeJob, err := tx.EdgeJob().EdgeJob(portainer.EdgeJobID(edgeJobID))
if tx.IsErrObjectNotFound(err) { // if tx.IsErrObjectNotFound(err) {
return httperror.NotFound("Unable to find an Edge job with the specified identifier inside the database", err) // return httperror.NotFound("Unable to find an Edge job with the specified identifier inside the database", err)
} else if err != nil { // } else if err != nil {
return httperror.InternalServerError("Unable to find an Edge job with the specified identifier inside the database", err) // return httperror.InternalServerError("Unable to find an Edge job with the specified identifier inside the database", err)
} // }
endpointID := portainer.EndpointID(taskID) // endpointID := portainer.EndpointID(taskID)
endpointsFromGroups, err := edge.GetEndpointsFromEdgeGroups(edgeJob.EdgeGroups, tx) // endpointsFromGroups, err := edge.GetEndpointsFromEdgeGroups(edgeJob.EdgeGroups, tx)
if err != nil { // if err != nil {
return httperror.InternalServerError("Unable to get Endpoints from EdgeGroups", err) // return httperror.InternalServerError("Unable to get Endpoints from EdgeGroups", err)
} // }
if slices.Contains(endpointsFromGroups, endpointID) { // if slices.Contains(endpointsFromGroups, endpointID) {
edgeJob.GroupLogsCollection[endpointID] = portainer.EdgeJobEndpointMeta{ // edgeJob.GroupLogsCollection[endpointID] = portainer.EdgeJobEndpointMeta{
CollectLogs: true, // CollectLogs: true,
LogsStatus: portainer.EdgeJobLogsStatusPending, // LogsStatus: portainer.EdgeJobLogsStatusPending,
} // }
} else { // } else {
meta := edgeJob.Endpoints[endpointID] // meta := edgeJob.Endpoints[endpointID]
meta.CollectLogs = true // meta.CollectLogs = true
meta.LogsStatus = portainer.EdgeJobLogsStatusPending // meta.LogsStatus = portainer.EdgeJobLogsStatusPending
edgeJob.Endpoints[endpointID] = meta // edgeJob.Endpoints[endpointID] = meta
} // }
err = tx.EdgeJob().UpdateEdgeJob(edgeJob.ID, edgeJob) // err = tx.EdgeJob().UpdateEdgeJob(edgeJob.ID, edgeJob)
if err != nil { // if err != nil {
return httperror.InternalServerError("Unable to persist Edge job changes in the database", err) // return httperror.InternalServerError("Unable to persist Edge job changes in the database", err)
} // }
endpoint, err := tx.Endpoint().Endpoint(endpointID) // endpoint, err := tx.Endpoint().Endpoint(endpointID)
if err != nil { // if err != nil {
return httperror.InternalServerError("Unable to retrieve environment from the database", err) // return httperror.InternalServerError("Unable to retrieve environment from the database", err)
} // }
if endpoint.Edge.AsyncMode { // if endpoint.Edge.AsyncMode {
return httperror.BadRequest("Async Edge Endpoints are not supported in Portainer CE", nil) // return httperror.BadRequest("Async Edge Endpoints are not supported in Portainer CE", nil)
} // }
handler.ReverseTunnelService.AddEdgeJob(endpoint, edgeJob) // handler.ReverseTunnelService.AddEdgeJob(endpoint, edgeJob)
return nil // return nil
}) // })
if err != nil { // if err != nil {
var handlerError *httperror.HandlerError // var handlerError *httperror.HandlerError
if errors.As(err, &handlerError) { // if errors.As(err, &handlerError) {
return handlerError // return handlerError
} // }
return httperror.InternalServerError("Unexpected error", err) // return httperror.InternalServerError("Unexpected error", err)
} // }
return response.Empty(w) return response.Empty(w)
} }

View file

@ -42,10 +42,10 @@ func (handler *Handler) edgeJobTasksList(w http.ResponseWriter, r *http.Request)
if featureflags.IsEnabled(portainer.FeatureNoTx) { if featureflags.IsEnabled(portainer.FeatureNoTx) {
tasks, err = listEdgeJobTasks(handler.DataStore, portainer.EdgeJobID(edgeJobID)) tasks, err = listEdgeJobTasks(handler.DataStore, portainer.EdgeJobID(edgeJobID))
} else { } else {
err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error { // err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
tasks, err = listEdgeJobTasks(tx, portainer.EdgeJobID(edgeJobID)) // tasks, err = listEdgeJobTasks(tx, portainer.EdgeJobID(edgeJobID))
return err // return err
}) // })
} }
return txResponse(w, tasks, err) return txResponse(w, tasks, err)

View file

@ -66,10 +66,10 @@ func (handler *Handler) edgeJobUpdate(w http.ResponseWriter, r *http.Request) *h
if featureflags.IsEnabled(portainer.FeatureNoTx) { if featureflags.IsEnabled(portainer.FeatureNoTx) {
edgeJob, err = handler.updateEdgeJob(handler.DataStore, portainer.EdgeJobID(edgeJobID), payload) edgeJob, err = handler.updateEdgeJob(handler.DataStore, portainer.EdgeJobID(edgeJobID), payload)
} else { } else {
err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error { // err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
edgeJob, err = handler.updateEdgeJob(tx, portainer.EdgeJobID(edgeJobID), payload) // edgeJob, err = handler.updateEdgeJob(tx, portainer.EdgeJobID(edgeJobID), payload)
return err // return err
}) // })
} }
return txResponse(w, edgeJob, err) return txResponse(w, edgeJob, err)

View file

@ -330,9 +330,7 @@ func (handler *Handler) createAzureEndpoint(payload *endpointCreatePayload) (*po
return nil, httperror.InternalServerError("Unable to authenticate against Azure", err) return nil, httperror.InternalServerError("Unable to authenticate against Azure", err)
} }
endpointID := handler.DataStore.Endpoint().GetNextIdentifier()
endpoint := &portainer.Endpoint{ endpoint := &portainer.Endpoint{
ID: portainer.EndpointID(endpointID),
Name: payload.Name, Name: payload.Name,
URL: "https://management.azure.com", URL: "https://management.azure.com",
Type: portainer.AzureEnvironment, Type: portainer.AzureEnvironment,
@ -357,17 +355,14 @@ func (handler *Handler) createAzureEndpoint(payload *endpointCreatePayload) (*po
} }
func (handler *Handler) createEdgeAgentEndpoint(payload *endpointCreatePayload) (*portainer.Endpoint, *httperror.HandlerError) { func (handler *Handler) createEdgeAgentEndpoint(payload *endpointCreatePayload) (*portainer.Endpoint, *httperror.HandlerError) {
endpointID := handler.DataStore.Endpoint().GetNextIdentifier()
portainerHost, err := edge.ParseHostForEdge(payload.URL) portainerHost, err := edge.ParseHostForEdge(payload.URL)
if err != nil { if err != nil {
return nil, httperror.BadRequest("Unable to parse host", err) return nil, httperror.BadRequest("Unable to parse host", err)
} }
edgeKey := handler.ReverseTunnelService.GenerateEdgeKey(payload.URL, portainerHost, endpointID) edgeKey := handler.ReverseTunnelService.GenerateEdgeKey(payload.URL, portainerHost, 0) // TODO: endpoint ID
endpoint := &portainer.Endpoint{ endpoint := &portainer.Endpoint{
ID: portainer.EndpointID(endpointID),
Name: payload.Name, Name: payload.Name,
URL: portainerHost, URL: portainerHost,
Type: portainer.EdgeAgentOnDockerEnvironment, Type: portainer.EdgeAgentOnDockerEnvironment,
@ -419,9 +414,7 @@ func (handler *Handler) createUnsecuredEndpoint(payload *endpointCreatePayload)
} }
} }
endpointID := handler.DataStore.Endpoint().GetNextIdentifier()
endpoint := &portainer.Endpoint{ endpoint := &portainer.Endpoint{
ID: portainer.EndpointID(endpointID),
Name: payload.Name, Name: payload.Name,
URL: payload.URL, URL: payload.URL,
Type: endpointType, Type: endpointType,
@ -452,10 +445,7 @@ func (handler *Handler) createKubernetesEndpoint(payload *endpointCreatePayload)
payload.URL = "https://kubernetes.default.svc" payload.URL = "https://kubernetes.default.svc"
} }
endpointID := handler.DataStore.Endpoint().GetNextIdentifier()
endpoint := &portainer.Endpoint{ endpoint := &portainer.Endpoint{
ID: portainer.EndpointID(endpointID),
Name: payload.Name, Name: payload.Name,
URL: payload.URL, URL: payload.URL,
Type: portainer.KubernetesLocalEnvironment, Type: portainer.KubernetesLocalEnvironment,
@ -483,9 +473,7 @@ func (handler *Handler) createKubernetesEndpoint(payload *endpointCreatePayload)
} }
func (handler *Handler) createTLSSecuredEndpoint(payload *endpointCreatePayload, endpointType portainer.EndpointType, agentVersion string) (*portainer.Endpoint, *httperror.HandlerError) { func (handler *Handler) createTLSSecuredEndpoint(payload *endpointCreatePayload, endpointType portainer.EndpointType, agentVersion string) (*portainer.Endpoint, *httperror.HandlerError) {
endpointID := handler.DataStore.Endpoint().GetNextIdentifier()
endpoint := &portainer.Endpoint{ endpoint := &portainer.Endpoint{
ID: portainer.EndpointID(endpointID),
Name: payload.Name, Name: payload.Name,
URL: payload.URL, URL: payload.URL,
Type: endpointType, Type: endpointType,

View file

@ -115,9 +115,7 @@ func (handler *Handler) fdoConfigure(w http.ResponseWriter, r *http.Request) *ht
} }
func (handler *Handler) addDefaultProfile() error { func (handler *Handler) addDefaultProfile() error {
profileID := handler.DataStore.FDOProfile().GetNextIdentifier()
profile := &portainer.FDOProfile{ profile := &portainer.FDOProfile{
ID: portainer.FDOProfileID(profileID),
Name: "Docker Standalone + Edge", Name: "Docker Standalone + Edge",
} }

View file

@ -72,9 +72,7 @@ func (handler *Handler) createFDOProfileFromFileContent(w http.ResponseWriter, r
return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A profile with the name '%s' already exists", payload.Name), Err: errors.New("a profile already exists with this name")} return &httperror.HandlerError{StatusCode: http.StatusConflict, Message: fmt.Sprintf("A profile with the name '%s' already exists", payload.Name), Err: errors.New("a profile already exists with this name")}
} }
profileID := handler.DataStore.FDOProfile().GetNextIdentifier()
profile := &portainer.FDOProfile{ profile := &portainer.FDOProfile{
ID: portainer.FDOProfileID(profileID),
Name: payload.Name, Name: payload.Name,
} }

View file

@ -43,13 +43,12 @@ func (handler *Handler) duplicateProfile(w http.ResponseWriter, r *http.Request)
return httperror.InternalServerError("Unable to retrieve Profile file content", err) return httperror.InternalServerError("Unable to retrieve Profile file content", err)
} }
profileID := handler.DataStore.FDOProfile().GetNextIdentifier() // TODO: Looks wrong
if err != nil { if err != nil {
return httperror.InternalServerError("Unable to duplicate Profile", err) return httperror.InternalServerError("Unable to duplicate Profile", err)
} }
newProfile := &portainer.FDOProfile{ newProfile := &portainer.FDOProfile{
ID: portainer.FDOProfileID(profileID),
Name: fmt.Sprintf("%s - copy", originalProfile.Name), Name: fmt.Sprintf("%s - copy", originalProfile.Name),
} }

View file

@ -49,10 +49,10 @@ func (handler *Handler) tagCreate(w http.ResponseWriter, r *http.Request) *httpe
if featureflags.IsEnabled(portainer.FeatureNoTx) { if featureflags.IsEnabled(portainer.FeatureNoTx) {
tag, err = createTag(handler.DataStore, payload) tag, err = createTag(handler.DataStore, payload)
} else { } else {
err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error { // err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
tag, err = createTag(tx, payload) // tag, err = createTag(tx, payload)
return err // return err
}) // })
} }
return txResponse(w, tag, err) return txResponse(w, tag, err)

View file

@ -36,9 +36,9 @@ func (handler *Handler) tagDelete(w http.ResponseWriter, r *http.Request) *httpe
if featureflags.IsEnabled(portainer.FeatureNoTx) { if featureflags.IsEnabled(portainer.FeatureNoTx) {
err = deleteTag(handler.DataStore, portainer.TagID(id)) err = deleteTag(handler.DataStore, portainer.TagID(id))
} else { } else {
err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error { // err = handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
return deleteTag(tx, portainer.TagID(id)) // return deleteTag(tx, portainer.TagID(id))
}) // })
} }
if err != nil { if err != nil {

View file

@ -42,9 +42,7 @@ func (service *Service) BuildEdgeStack(
return nil, err return nil, err
} }
stackID := tx.EdgeStack().GetNextIdentifier()
return &portainer.EdgeStack{ return &portainer.EdgeStack{
ID: portainer.EdgeStackID(stackID),
Name: name, Name: name,
DeploymentType: deploymentType, DeploymentType: deploymentType,
CreationDate: time.Now().Unix(), CreationDate: time.Now().Unix(),

View file

@ -27,8 +27,6 @@ type FileContentMethodStackBuilder struct {
} }
func (b *FileContentMethodStackBuilder) SetGeneralInfo(payload *StackPayload, endpoint *portainer.Endpoint) FileContentMethodStackBuildProcess { func (b *FileContentMethodStackBuilder) SetGeneralInfo(payload *StackPayload, endpoint *portainer.Endpoint) FileContentMethodStackBuildProcess {
stackID := b.dataStore.Stack().GetNextIdentifier()
b.stack.ID = portainer.StackID(stackID)
b.stack.EndpointID = endpoint.ID b.stack.EndpointID = endpoint.ID
b.stack.Status = portainer.StackStatusActive b.stack.Status = portainer.StackStatusActive
b.stack.CreationDate = time.Now().Unix() b.stack.CreationDate = time.Now().Unix()

View file

@ -28,8 +28,6 @@ type FileUploadMethodStackBuilder struct {
} }
func (b *FileUploadMethodStackBuilder) SetGeneralInfo(payload *StackPayload, endpoint *portainer.Endpoint) FileUploadMethodStackBuildProcess { func (b *FileUploadMethodStackBuilder) SetGeneralInfo(payload *StackPayload, endpoint *portainer.Endpoint) FileUploadMethodStackBuildProcess {
stackID := b.dataStore.Stack().GetNextIdentifier()
b.stack.ID = portainer.StackID(stackID)
b.stack.EndpointID = endpoint.ID b.stack.EndpointID = endpoint.ID
b.stack.Status = portainer.StackStatusActive b.stack.Status = portainer.StackStatusActive
b.stack.CreationDate = time.Now().Unix() b.stack.CreationDate = time.Now().Unix()

View file

@ -38,8 +38,6 @@ type GitMethodStackBuilder struct {
} }
func (b *GitMethodStackBuilder) SetGeneralInfo(payload *StackPayload, endpoint *portainer.Endpoint) GitMethodStackBuildProcess { func (b *GitMethodStackBuilder) SetGeneralInfo(payload *StackPayload, endpoint *portainer.Endpoint) GitMethodStackBuildProcess {
stackID := b.dataStore.Stack().GetNextIdentifier()
b.stack.ID = portainer.StackID(stackID)
b.stack.EndpointID = endpoint.ID b.stack.EndpointID = endpoint.ID
b.stack.AdditionalFiles = payload.AdditionalFiles b.stack.AdditionalFiles = payload.AdditionalFiles
b.stack.Status = portainer.StackStatusActive b.stack.Status = portainer.StackStatusActive

View file

@ -27,8 +27,6 @@ type UrlMethodStackBuilder struct {
} }
func (b *UrlMethodStackBuilder) SetGeneralInfo(payload *StackPayload, endpoint *portainer.Endpoint) UrlMethodStackBuildProcess { func (b *UrlMethodStackBuilder) SetGeneralInfo(payload *StackPayload, endpoint *portainer.Endpoint) UrlMethodStackBuildProcess {
stackID := b.dataStore.Stack().GetNextIdentifier()
b.stack.ID = portainer.StackID(stackID)
b.stack.EndpointID = endpoint.ID b.stack.EndpointID = endpoint.ID
b.stack.Status = portainer.StackStatusActive b.stack.Status = portainer.StackStatusActive
b.stack.CreationDate = time.Now().Unix() b.stack.CreationDate = time.Now().Unix()

View file

@ -33,7 +33,7 @@ BINARY_VERSION_FILE="../binary-version.json"
echo "$ldflags" echo "$ldflags"
# the build takes 2 seconds # the build takes 2 seconds
GOOS=${1:-$(go env GOOS)} GOARCH=${2:-$(go env GOARCH)} CGO_ENABLED=0 go build \ GOOS=${1:-$(go env GOOS)} GOARCH=${2:-$(go env GOARCH)} CGO_ENABLED=1 go build \
-trimpath \ -trimpath \
--installsuffix cgo \ --installsuffix cgo \
--ldflags "$ldflags" \ --ldflags "$ldflags" \

View file

@ -1,75 +1,75 @@
package featureflags package featureflags
import ( // import (
"os" // "os"
"strings" // "strings"
"testing" // "testing"
"github.com/stretchr/testify/assert" // "github.com/stretchr/testify/assert"
) // )
func Test_enableFeaturesFromFlags(t *testing.T) { // func Test_enableFeaturesFromFlags(t *testing.T) {
is := assert.New(t) // is := assert.New(t)
supportedFeatures := []Feature{"supported", "supported2", "supported3", "supported4", "supported5"} // supportedFeatures := []Feature{"supported", "supported2", "supported3", "supported4", "supported5"}
t.Run("supported features should be supported", func(t *testing.T) { // t.Run("supported features should be supported", func(t *testing.T) {
Init(supportedFeatures) // Init(supportedFeatures)
for _, featureFlag := range supportedFeatures { // for _, featureFlag := range supportedFeatures {
is.True(IsSupported(featureFlag)) // is.True(IsSupported(featureFlag))
} // }
}) // })
t.Run("unsupported features should not be supported", func(t *testing.T) { // t.Run("unsupported features should not be supported", func(t *testing.T) {
Init(supportedFeatures) // Init(supportedFeatures)
is.False(IsSupported("unsupported")) // is.False(IsSupported("unsupported"))
}) // })
tests := []struct { // tests := []struct {
cliFeatureFlags []string // cliFeatureFlags []string
envFeatureFlags []string // envFeatureFlags []string
}{ // }{
{[]string{"supported", "supported2"}, []string{"supported3", "supported4"}}, // {[]string{"supported", "supported2"}, []string{"supported3", "supported4"}},
} // }
for _, test := range tests { // for _, test := range tests {
Init(supportedFeatures) // Init(supportedFeatures)
os.Unsetenv("PORTAINER_FEATURE_FLAGS") // os.Unsetenv("PORTAINER_FEATURE_FLAGS")
os.Setenv("PORTAINER_FEATURE_FLAGS", strings.Join(test.envFeatureFlags, ",")) // os.Setenv("PORTAINER_FEATURE_FLAGS", strings.Join(test.envFeatureFlags, ","))
t.Run("testing", func(t *testing.T) { // t.Run("testing", func(t *testing.T) {
Parse(test.cliFeatureFlags) // Parse(test.cliFeatureFlags)
supported := toFeatureMap(test.cliFeatureFlags, test.envFeatureFlags) // supported := toFeatureMap(test.cliFeatureFlags, test.envFeatureFlags)
// add env flags to supported flags // // add env flags to supported flags
for _, featureFlag := range test.envFeatureFlags { // for _, featureFlag := range test.envFeatureFlags {
supported[Feature(featureFlag)] = true // supported[Feature(featureFlag)] = true
} // }
for _, featureFlag := range supportedFeatures { // for _, featureFlag := range supportedFeatures {
if _, ok := supported[featureFlag]; ok { // if _, ok := supported[featureFlag]; ok {
is.True(IsEnabled(featureFlag)) // is.True(IsEnabled(featureFlag))
} else { // } else {
is.False(IsEnabled(featureFlag)) // is.False(IsEnabled(featureFlag))
} // }
} // }
}) // })
} // }
} // }
// helper // // helper
func toFeatureMap(cliFeatures []string, envFeatures []string) map[Feature]bool { // func toFeatureMap(cliFeatures []string, envFeatures []string) map[Feature]bool {
m := map[Feature]bool{} // m := map[Feature]bool{}
for _, s := range cliFeatures { // for _, s := range cliFeatures {
m[Feature(s)] = true // m[Feature(s)] = true
} // }
for _, s := range envFeatures { // for _, s := range envFeatures {
m[Feature(s)] = true // m[Feature(s)] = true
} // }
return m // return m
} // }