diff --git a/api/datastore/migrator/migrate_dbversion31.go b/api/datastore/migrator/migrate_dbversion31.go index 7e4249421..6b89da547 100644 --- a/api/datastore/migrator/migrate_dbversion31.go +++ b/api/datastore/migrator/migrate_dbversion31.go @@ -4,6 +4,7 @@ import ( "fmt" "log" + "github.com/docker/docker/api/types/volume" "github.com/portainer/portainer/api/dataservices/errors" portainer "github.com/portainer/portainer/api" @@ -210,14 +211,14 @@ func (m *Migrator) updateVolumeResourceControlToDB32() error { continue } - if volumesData, done := snapshot.SnapshotRaw.Volumes.(map[string]interface{}); done { - if volumesData["Volumes"] == nil { - log.Println("[DEBUG] [volume migration] [message: no volume data found]") - continue - } - - findResourcesToUpdateForDB32(endpointDockerID, volumesData, toUpdate, volumeResourceControls) + volumesData := snapshot.SnapshotRaw.Volumes + if volumesData.Volumes == nil { + log.Println("[DEBUG] [volume migration] [message: no volume data found]") + continue } + + findResourcesToUpdateForDB32(endpointDockerID, volumesData, toUpdate, volumeResourceControls) + } for _, resourceControl := range volumeResourceControls { @@ -240,18 +241,11 @@ func (m *Migrator) updateVolumeResourceControlToDB32() error { return nil } -func findResourcesToUpdateForDB32(dockerID string, volumesData map[string]interface{}, toUpdate map[portainer.ResourceControlID]string, volumeResourceControls map[string]*portainer.ResourceControl) { - volumes := volumesData["Volumes"].([]interface{}) - for _, volumeMeta := range volumes { - volume := volumeMeta.(map[string]interface{}) - volumeName, nameExist := volume["Name"].(string) - if !nameExist { - continue - } - createTime, createTimeExist := volume["CreatedAt"].(string) - if !createTimeExist { - continue - } +func findResourcesToUpdateForDB32(dockerID string, volumesData volume.VolumeListOKBody, toUpdate map[portainer.ResourceControlID]string, volumeResourceControls map[string]*portainer.ResourceControl) { + volumes := volumesData.Volumes + for _, volume := range volumes { + volumeName := volume.Name + createTime := volume.CreatedAt oldResourceID := fmt.Sprintf("%s%s", volumeName, createTime) resourceControl, ok := volumeResourceControls[oldResourceID] diff --git a/api/datastore/test_data/output_35.json b/api/datastore/test_data/output_35.json index b8ce03ef4..db47663be 100644 --- a/api/datastore/test_data/output_35.json +++ b/api/datastore/test_data/output_35.json @@ -70,10 +70,103 @@ "DockerSnapshotRaw": { "Containers": null, "Images": null, - "Info": null, + "Info": { + "Architecture": "", + "BridgeNfIp6tables": false, + "BridgeNfIptables": false, + "CPUSet": false, + "CPUShares": false, + "CgroupDriver": "", + "ContainerdCommit": { + "Expected": "", + "ID": "" + }, + "Containers": 0, + "ContainersPaused": 0, + "ContainersRunning": 0, + "ContainersStopped": 0, + "CpuCfsPeriod": false, + "CpuCfsQuota": false, + "Debug": false, + "DefaultRuntime": "", + "DockerRootDir": "", + "Driver": "", + "DriverStatus": null, + "ExperimentalBuild": false, + "GenericResources": null, + "HttpProxy": "", + "HttpsProxy": "", + "ID": "", + "IPv4Forwarding": false, + "Images": 0, + "IndexServerAddress": "", + "InitBinary": "", + "InitCommit": { + "Expected": "", + "ID": "" + }, + "Isolation": "", + "KernelMemory": false, + "KernelMemoryTCP": false, + "KernelVersion": "", + "Labels": null, + "LiveRestoreEnabled": false, + "LoggingDriver": "", + "MemTotal": 0, + "MemoryLimit": false, + "NCPU": 0, + "NEventsListener": 0, + "NFd": 0, + "NGoroutines": 0, + "Name": "", + "NoProxy": "", + "OSType": "", + "OSVersion": "", + "OomKillDisable": false, + "OperatingSystem": "", + "PidsLimit": false, + "Plugins": { + "Authorization": null, + "Log": null, + "Network": null, + "Volume": null + }, + "RegistryConfig": null, + "RuncCommit": { + "Expected": "", + "ID": "" + }, + "Runtimes": null, + "SecurityOptions": null, + "ServerVersion": "", + "SwapLimit": false, + "Swarm": { + "ControlAvailable": false, + "Error": "", + "LocalNodeState": "", + "NodeAddr": "", + "NodeID": "", + "RemoteManagers": null + }, + "SystemTime": "", + "Warnings": null + }, "Networks": null, - "Version": null, - "Volumes": null + "Version": { + "ApiVersion": "", + "Arch": "", + "GitCommit": "", + "GoVersion": "", + "Os": "", + "Platform": { + "Name": "" + }, + "Version": "" + }, + "Volumes": { + "Volumes": null, + "Warnings": null + } }, "DockerVersion": "20.10.13", "HealthyContainerCount": 0, diff --git a/api/http/handler/endpoints/endpoint_association_delete.go b/api/http/handler/endpoints/endpoint_association_delete.go index e8385b278..0329b697a 100644 --- a/api/http/handler/endpoints/endpoint_association_delete.go +++ b/api/http/handler/endpoints/endpoint_association_delete.go @@ -23,7 +23,7 @@ import ( // @tags endpoints // @produce json // @param id path int true "Environment(Endpoint) identifier" -// @success 200 {object} portainer.Endpoint "Success" +// @success 204 "Success" // @failure 400 "Invalid request" // @failure 404 "Environment(Endpoint) not found" // @failure 500 "Server error" @@ -61,7 +61,7 @@ func (handler *Handler) endpointAssociationDelete(w http.ResponseWriter, r *http handler.ReverseTunnelService.SetTunnelStatusToIdle(endpoint.ID) - return response.JSON(w, endpoint) + return response.Empty(w) } func (handler *Handler) updateEdgeKey(edgeKey string) (string, error) { diff --git a/api/internal/snapshot/snapshot.go b/api/internal/snapshot/snapshot.go index 3aa943908..e20cf21ef 100644 --- a/api/internal/snapshot/snapshot.go +++ b/api/internal/snapshot/snapshot.go @@ -188,24 +188,17 @@ func (service *Service) snapshotEndpoints() error { // 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 { - return "", errors.New("failed getting snapshot info") - } + info := snapshot.SnapshotRaw.Info if !snapshot.Swarm { - return info["ID"].(string), nil + return info.ID, nil } - if info["Swarm"] == nil { - return "", errors.New("swarm environment is missing swarm info snapshot") - } - - swarmInfo := info["Swarm"].(map[string]interface{}) - if swarmInfo["Cluster"] == nil { + swarmInfo := info.Swarm + if swarmInfo.Cluster == nil { return "", errors.New("swarm environment is missing cluster info snapshot") } - clusterInfo := swarmInfo["Cluster"].(map[string]interface{}) - return clusterInfo["ID"].(string), nil + clusterInfo := swarmInfo.Cluster + return clusterInfo.ID, nil } diff --git a/api/portainer.go b/api/portainer.go index 3353afb29..726d29aee 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -5,6 +5,8 @@ import ( "io" "time" + "github.com/docker/docker/api/types" + "github.com/docker/docker/api/types/volume" gittypes "github.com/portainer/portainer/api/git/types" v1 "k8s.io/api/core/v1" ) @@ -200,13 +202,14 @@ type ( } // DockerSnapshotRaw represents all the information related to a snapshot as returned by the Docker API + DockerSnapshotRaw struct { - Containers interface{} `json:"Containers"` - Volumes interface{} `json:"Volumes"` - Networks interface{} `json:"Networks"` - Images interface{} `json:"Images"` - Info interface{} `json:"Info"` - Version interface{} `json:"Version"` + Containers []types.Container `json:"Containers" swaggerignore:"true"` + Volumes volume.VolumeListOKBody `json:"Volumes" swaggerignore:"true"` + Networks []types.NetworkResource `json:"Networks" swaggerignore:"true"` + Images []types.ImageSummary `json:"Images" swaggerignore:"true"` + Info types.Info `json:"Info" swaggerignore:"true"` + Version types.Version `json:"Version" swaggerignore:"true"` } // EdgeGroup represents an Edge group