mirror of
https://github.com/yusing/godoxy.git
synced 2025-07-22 12:24:02 +02:00
feat: predefined docker image blacklist, avoid proxing service backends, refactor
This commit is contained in:
parent
c6f65ba69f
commit
3c515b0258
6 changed files with 166 additions and 141 deletions
|
@ -1,75 +0,0 @@
|
||||||
package common
|
|
||||||
|
|
||||||
var (
|
|
||||||
WellKnownHTTPPorts = map[string]bool{
|
|
||||||
"80": true,
|
|
||||||
"8000": true,
|
|
||||||
"8008": true,
|
|
||||||
"8080": true,
|
|
||||||
"3000": true,
|
|
||||||
}
|
|
||||||
|
|
||||||
ServiceNamePortMapTCP = map[string]int{
|
|
||||||
"mssql": 1433,
|
|
||||||
"mysql": 3306,
|
|
||||||
"mariadb": 3306,
|
|
||||||
"postgres": 5432,
|
|
||||||
"rabbitmq": 5672,
|
|
||||||
"redis": 6379,
|
|
||||||
"memcached": 11211,
|
|
||||||
"mongo": 27017,
|
|
||||||
"minecraft-server": 25565,
|
|
||||||
|
|
||||||
"ssh": 22,
|
|
||||||
"ftp": 21,
|
|
||||||
"smtp": 25,
|
|
||||||
"dns": 53,
|
|
||||||
"pop3": 110,
|
|
||||||
"imap": 143,
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageNamePortMap = func() (m map[string]int) {
|
|
||||||
m = make(map[string]int, len(ServiceNamePortMapTCP)+len(imageNamePortMap))
|
|
||||||
for k, v := range ServiceNamePortMapTCP {
|
|
||||||
m[k] = v
|
|
||||||
}
|
|
||||||
for k, v := range imageNamePortMap {
|
|
||||||
m[k] = v
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}()
|
|
||||||
|
|
||||||
imageNamePortMap = map[string]int{
|
|
||||||
"adguardhome": 3000,
|
|
||||||
"bazarr": 6767,
|
|
||||||
"calibre-web": 8083,
|
|
||||||
"changedetection.io": 3000,
|
|
||||||
"dockge": 5001,
|
|
||||||
"gitea": 3000,
|
|
||||||
"gogs": 3000,
|
|
||||||
"grafana": 3000,
|
|
||||||
"home-assistant": 8123,
|
|
||||||
"homebridge": 8581,
|
|
||||||
"httpd": 80,
|
|
||||||
"immich": 3001,
|
|
||||||
"jellyfin": 8096,
|
|
||||||
"lidarr": 8686,
|
|
||||||
"microbin": 8080,
|
|
||||||
"nginx": 80,
|
|
||||||
"nginx-proxy-manager": 81,
|
|
||||||
"open-webui": 8080,
|
|
||||||
"plex": 32400,
|
|
||||||
"portainer-be": 9443,
|
|
||||||
"portainer-ce": 9443,
|
|
||||||
"prometheus": 9090,
|
|
||||||
"prowlarr": 9696,
|
|
||||||
"radarr": 7878,
|
|
||||||
"radarr-sma": 7878,
|
|
||||||
"rsshub": 1200,
|
|
||||||
"rss-bridge": 80,
|
|
||||||
"sonarr": 8989,
|
|
||||||
"sonarr-sma": 8989,
|
|
||||||
"uptime-kuma": 3001,
|
|
||||||
"whisparr": 6969,
|
|
||||||
}
|
|
||||||
)
|
|
|
@ -5,34 +5,39 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types/container"
|
||||||
|
"github.com/docker/go-connections/nat"
|
||||||
|
"github.com/yusing/go-proxy/agent/pkg/agent"
|
||||||
|
config "github.com/yusing/go-proxy/internal/config/types"
|
||||||
"github.com/yusing/go-proxy/internal/logging"
|
"github.com/yusing/go-proxy/internal/logging"
|
||||||
U "github.com/yusing/go-proxy/internal/utils"
|
U "github.com/yusing/go-proxy/internal/utils"
|
||||||
"github.com/yusing/go-proxy/internal/utils/strutils"
|
"github.com/yusing/go-proxy/internal/utils/strutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
PortMapping = map[int]types.Port
|
PortMapping = map[int]container.Port
|
||||||
Container struct {
|
Container struct {
|
||||||
_ U.NoCopy
|
_ U.NoCopy
|
||||||
|
|
||||||
DockerHost string `json:"docker_host"`
|
DockerHost string `json:"docker_host"`
|
||||||
ContainerName string `json:"container_name"`
|
Image *ContainerImage `json:"image"`
|
||||||
ContainerID string `json:"container_id"`
|
ContainerName string `json:"container_name"`
|
||||||
ImageName string `json:"image_name"`
|
ContainerID string `json:"container_id"`
|
||||||
|
|
||||||
|
Agent *agent.AgentConfig `json:"agent"`
|
||||||
|
|
||||||
Labels map[string]string `json:"-"`
|
Labels map[string]string `json:"-"`
|
||||||
|
|
||||||
|
Mounts []string `json:"mounts"`
|
||||||
|
|
||||||
PublicPortMapping PortMapping `json:"public_ports"` // non-zero publicPort:types.Port
|
PublicPortMapping PortMapping `json:"public_ports"` // non-zero publicPort:types.Port
|
||||||
PrivatePortMapping PortMapping `json:"private_ports"` // privatePort:types.Port
|
PrivatePortMapping PortMapping `json:"private_ports"` // privatePort:types.Port
|
||||||
PublicIP string `json:"public_ip"`
|
PublicHostname string `json:"public_hostname"`
|
||||||
PrivateIP string `json:"private_ip"`
|
PrivateHostname string `json:"private_hostname"`
|
||||||
NetworkMode string `json:"network_mode"`
|
|
||||||
|
|
||||||
Aliases []string `json:"aliases"`
|
Aliases []string `json:"aliases"`
|
||||||
IsExcluded bool `json:"is_excluded"`
|
IsExcluded bool `json:"is_excluded"`
|
||||||
IsExplicit bool `json:"is_explicit"`
|
IsExplicit bool `json:"is_explicit"`
|
||||||
IsDatabase bool `json:"is_database"`
|
|
||||||
IdleTimeout string `json:"idle_timeout,omitempty"`
|
IdleTimeout string `json:"idle_timeout,omitempty"`
|
||||||
WakeTimeout string `json:"wake_timeout,omitempty"`
|
WakeTimeout string `json:"wake_timeout,omitempty"`
|
||||||
StopMethod string `json:"stop_method,omitempty"`
|
StopMethod string `json:"stop_method,omitempty"`
|
||||||
|
@ -41,35 +46,41 @@ type (
|
||||||
StartEndpoint string `json:"start_endpoint,omitempty"`
|
StartEndpoint string `json:"start_endpoint,omitempty"`
|
||||||
Running bool `json:"running"`
|
Running bool `json:"running"`
|
||||||
}
|
}
|
||||||
|
ContainerImage struct {
|
||||||
|
Author string `json:"author,omitempty"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Tag string `json:"tag,omitempty"`
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
var DummyContainer = new(Container)
|
var DummyContainer = new(Container)
|
||||||
|
|
||||||
func FromDocker(c *types.Container, dockerHost string) (res *Container) {
|
func FromDocker(c *container.Summary, dockerHost string) (res *Container) {
|
||||||
isExplicit := false
|
isExplicit := false
|
||||||
helper := containerHelper{c}
|
helper := containerHelper{c}
|
||||||
for lbl := range c.Labels {
|
for lbl := range c.Labels {
|
||||||
if strings.HasPrefix(lbl, NSProxy+".") {
|
if strings.HasPrefix(lbl, NSProxy+".") {
|
||||||
isExplicit = true
|
isExplicit = true
|
||||||
break
|
} else {
|
||||||
|
delete(c.Labels, lbl)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res = &Container{
|
res = &Container{
|
||||||
DockerHost: dockerHost,
|
DockerHost: dockerHost,
|
||||||
|
Image: helper.parseImage(),
|
||||||
ContainerName: helper.getName(),
|
ContainerName: helper.getName(),
|
||||||
ContainerID: c.ID,
|
ContainerID: c.ID,
|
||||||
ImageName: helper.getImageName(),
|
|
||||||
|
|
||||||
Labels: c.Labels,
|
Labels: c.Labels,
|
||||||
|
|
||||||
|
Mounts: helper.getMounts(),
|
||||||
|
|
||||||
PublicPortMapping: helper.getPublicPortMapping(),
|
PublicPortMapping: helper.getPublicPortMapping(),
|
||||||
PrivatePortMapping: helper.getPrivatePortMapping(),
|
PrivatePortMapping: helper.getPrivatePortMapping(),
|
||||||
NetworkMode: c.HostConfig.NetworkMode,
|
|
||||||
|
|
||||||
Aliases: helper.getAliases(),
|
Aliases: helper.getAliases(),
|
||||||
IsExcluded: strutils.ParseBool(helper.getDeleteLabel(LabelExclude)),
|
IsExcluded: strutils.ParseBool(helper.getDeleteLabel(LabelExclude)),
|
||||||
IsExplicit: isExplicit,
|
IsExplicit: isExplicit,
|
||||||
IsDatabase: helper.isDatabase(),
|
|
||||||
IdleTimeout: helper.getDeleteLabel(LabelIdleTimeout),
|
IdleTimeout: helper.getDeleteLabel(LabelIdleTimeout),
|
||||||
WakeTimeout: helper.getDeleteLabel(LabelWakeTimeout),
|
WakeTimeout: helper.getDeleteLabel(LabelWakeTimeout),
|
||||||
StopMethod: helper.getDeleteLabel(LabelStopMethod),
|
StopMethod: helper.getDeleteLabel(LabelStopMethod),
|
||||||
|
@ -78,23 +89,32 @@ func FromDocker(c *types.Container, dockerHost string) (res *Container) {
|
||||||
StartEndpoint: helper.getDeleteLabel(LabelStartEndpoint),
|
StartEndpoint: helper.getDeleteLabel(LabelStartEndpoint),
|
||||||
Running: c.Status == "running" || c.State == "running",
|
Running: c.Status == "running" || c.State == "running",
|
||||||
}
|
}
|
||||||
res.setPrivateIP(helper)
|
|
||||||
res.setPublicIP()
|
if agent.IsDockerHostAgent(dockerHost) {
|
||||||
|
var ok bool
|
||||||
|
res.Agent, ok = config.GetInstance().GetAgent(dockerHost)
|
||||||
|
if !ok {
|
||||||
|
logging.Error().Msgf("agent %q not found", dockerHost)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res.setPrivateHostname(helper)
|
||||||
|
res.setPublicHostname()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func FromJSON(json types.ContainerJSON, dockerHost string) *Container {
|
func FromInspectResponse(json container.InspectResponse, dockerHost string) *Container {
|
||||||
ports := make([]types.Port, 0)
|
ports := make([]container.Port, 0)
|
||||||
for k, bindings := range json.NetworkSettings.Ports {
|
for k, bindings := range json.NetworkSettings.Ports {
|
||||||
privPortStr, proto := k.Port(), k.Proto()
|
proto, privPortStr := nat.SplitProtoPort(string(k))
|
||||||
privPort, _ := strconv.ParseUint(privPortStr, 10, 16)
|
privPort, _ := strconv.ParseUint(privPortStr, 10, 16)
|
||||||
ports = append(ports, types.Port{
|
ports = append(ports, container.Port{
|
||||||
PrivatePort: uint16(privPort),
|
PrivatePort: uint16(privPort),
|
||||||
Type: proto,
|
Type: proto,
|
||||||
})
|
})
|
||||||
for _, v := range bindings {
|
for _, v := range bindings {
|
||||||
pubPort, _ := strconv.ParseUint(v.HostPort, 10, 16)
|
pubPort, _ := strconv.ParseUint(v.HostPort, 10, 16)
|
||||||
ports = append(ports, types.Port{
|
ports = append(ports, container.Port{
|
||||||
IP: v.HostIP,
|
IP: v.HostIP,
|
||||||
PublicPort: uint16(pubPort),
|
PublicPort: uint16(pubPort),
|
||||||
PrivatePort: uint16(privPort),
|
PrivatePort: uint16(privPort),
|
||||||
|
@ -102,7 +122,7 @@ func FromJSON(json types.ContainerJSON, dockerHost string) *Container {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cont := FromDocker(&types.Container{
|
cont := FromDocker(&container.Summary{
|
||||||
ID: json.ID,
|
ID: json.ID,
|
||||||
Names: []string{strings.TrimPrefix(json.Name, "/")},
|
Names: []string{strings.TrimPrefix(json.Name, "/")},
|
||||||
Image: json.Image,
|
Image: json.Image,
|
||||||
|
@ -111,33 +131,62 @@ func FromJSON(json types.ContainerJSON, dockerHost string) *Container {
|
||||||
State: json.State.Status,
|
State: json.State.Status,
|
||||||
Status: json.State.Status,
|
Status: json.State.Status,
|
||||||
Mounts: json.Mounts,
|
Mounts: json.Mounts,
|
||||||
NetworkSettings: &types.SummaryNetworkSettings{
|
NetworkSettings: &container.NetworkSettingsSummary{
|
||||||
Networks: json.NetworkSettings.Networks,
|
Networks: json.NetworkSettings.Networks,
|
||||||
},
|
},
|
||||||
}, dockerHost)
|
}, dockerHost)
|
||||||
cont.NetworkMode = string(json.HostConfig.NetworkMode)
|
|
||||||
return cont
|
return cont
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) setPublicIP() {
|
func (c *Container) IsBlacklisted() bool {
|
||||||
|
return c.Image.IsBlacklisted() || c.isDatabase()
|
||||||
|
}
|
||||||
|
|
||||||
|
var databaseMPs = map[string]struct{}{
|
||||||
|
"/var/lib/postgresql/data": {},
|
||||||
|
"/var/lib/mysql": {},
|
||||||
|
"/var/lib/mongodb": {},
|
||||||
|
"/var/lib/mariadb": {},
|
||||||
|
"/var/lib/memcached": {},
|
||||||
|
"/var/lib/rabbitmq": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Container) isDatabase() bool {
|
||||||
|
for _, m := range c.Mounts {
|
||||||
|
if _, ok := databaseMPs[m]; ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range c.PrivatePortMapping {
|
||||||
|
switch v.PrivatePort {
|
||||||
|
// postgres, mysql or mariadb, redis, memcached, mongodb
|
||||||
|
case 5432, 3306, 6379, 11211, 27017:
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Container) setPublicHostname() {
|
||||||
if !c.Running {
|
if !c.Running {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(c.DockerHost, "unix://") {
|
if strings.HasPrefix(c.DockerHost, "unix://") {
|
||||||
c.PublicIP = "127.0.0.1"
|
c.PublicHostname = "127.0.0.1"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
url, err := url.Parse(c.DockerHost)
|
url, err := url.Parse(c.DockerHost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logging.Err(err).Msgf("invalid docker host %q, falling back to 127.0.0.1", c.DockerHost)
|
logging.Err(err).Msgf("invalid docker host %q, falling back to 127.0.0.1", c.DockerHost)
|
||||||
c.PublicIP = "127.0.0.1"
|
c.PublicHostname = "127.0.0.1"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
c.PublicIP = url.Hostname()
|
c.PublicHostname = url.Hostname()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) setPrivateIP(helper containerHelper) {
|
func (c *Container) setPrivateHostname(helper containerHelper) {
|
||||||
if !strings.HasPrefix(c.DockerHost, "unix://") {
|
if !strings.HasPrefix(c.DockerHost, "unix://") && c.Agent == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if helper.NetworkSettings == nil {
|
if helper.NetworkSettings == nil {
|
||||||
|
@ -147,7 +196,7 @@ func (c *Container) setPrivateIP(helper containerHelper) {
|
||||||
if v.IPAddress == "" {
|
if v.IPAddress == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
c.PrivateIP = v.IPAddress
|
c.PrivateHostname = v.IPAddress
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,12 @@ package docker
|
||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types/container"
|
||||||
"github.com/yusing/go-proxy/internal/utils/strutils"
|
"github.com/yusing/go-proxy/internal/utils/strutils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type containerHelper struct {
|
type containerHelper struct {
|
||||||
*types.Container
|
*container.Summary
|
||||||
}
|
}
|
||||||
|
|
||||||
// getDeleteLabel gets the value of a label and then deletes it from the container.
|
// getDeleteLabel gets the value of a label and then deletes it from the container.
|
||||||
|
@ -32,10 +32,28 @@ func (c containerHelper) getName() string {
|
||||||
return strings.TrimPrefix(c.Names[0], "/")
|
return strings.TrimPrefix(c.Names[0], "/")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c containerHelper) getImageName() string {
|
func (c containerHelper) getMounts() []string {
|
||||||
|
m := make([]string, len(c.Mounts))
|
||||||
|
for i, v := range c.Mounts {
|
||||||
|
m[i] = v.Destination
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c containerHelper) parseImage() *ContainerImage {
|
||||||
colonSep := strutils.SplitRune(c.Image, ':')
|
colonSep := strutils.SplitRune(c.Image, ':')
|
||||||
slashSep := strutils.SplitRune(colonSep[0], '/')
|
slashSep := strutils.SplitRune(colonSep[0], '/')
|
||||||
return slashSep[len(slashSep)-1]
|
im := new(ContainerImage)
|
||||||
|
if len(slashSep) > 1 {
|
||||||
|
im.Author = strings.Join(slashSep[:len(slashSep)-1], "/")
|
||||||
|
im.Name = slashSep[len(slashSep)-1]
|
||||||
|
} else {
|
||||||
|
im.Name = slashSep[0]
|
||||||
|
}
|
||||||
|
if len(colonSep) > 1 {
|
||||||
|
im.Tag = colonSep[1]
|
||||||
|
}
|
||||||
|
return im
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c containerHelper) getPublicPortMapping() PortMapping {
|
func (c containerHelper) getPublicPortMapping() PortMapping {
|
||||||
|
@ -56,29 +74,3 @@ func (c containerHelper) getPrivatePortMapping() PortMapping {
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
var databaseMPs = map[string]struct{}{
|
|
||||||
"/var/lib/postgresql/data": {},
|
|
||||||
"/var/lib/mysql": {},
|
|
||||||
"/var/lib/mongodb": {},
|
|
||||||
"/var/lib/mariadb": {},
|
|
||||||
"/var/lib/memcached": {},
|
|
||||||
"/var/lib/rabbitmq": {},
|
|
||||||
}
|
|
||||||
|
|
||||||
func (c containerHelper) isDatabase() bool {
|
|
||||||
for _, m := range c.Mounts {
|
|
||||||
if _, ok := databaseMPs[m.Destination]; ok {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range c.Ports {
|
|
||||||
switch v.PrivatePort {
|
|
||||||
// postgres, mysql or mariadb, redis, memcached, mongodb
|
|
||||||
case 5432, 3306, 6379, 11211, 27017:
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ package docker
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types/container"
|
||||||
. "github.com/yusing/go-proxy/internal/utils/testing"
|
. "github.com/yusing/go-proxy/internal/utils/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ func TestContainerExplicit(t *testing.T) {
|
||||||
|
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
c := FromDocker(&types.Container{Names: []string{"test"}, State: "test", Labels: tt.labels}, "")
|
c := FromDocker(&container.Summary{Names: []string{"test"}, State: "test", Labels: tt.labels}, "")
|
||||||
ExpectEqual(t, c.IsExplicit, tt.isExplicit)
|
ExpectEqual(t, c.IsExplicit, tt.isExplicit)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
59
internal/docker/image_blacklist.go
Normal file
59
internal/docker/image_blacklist.go
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
package docker
|
||||||
|
|
||||||
|
var imageBlacklist = map[string]struct{}{
|
||||||
|
// pure databases without UI
|
||||||
|
"postgres": {},
|
||||||
|
"mysql": {},
|
||||||
|
"mariadb": {},
|
||||||
|
"redis": {},
|
||||||
|
"memcached": {},
|
||||||
|
"mongo": {},
|
||||||
|
"rabbitmq": {},
|
||||||
|
"couchdb": {},
|
||||||
|
"neo4j": {},
|
||||||
|
"telegraf": {},
|
||||||
|
|
||||||
|
// search engines, usually used for internal services
|
||||||
|
"elasticsearch": {},
|
||||||
|
"meilisearch": {},
|
||||||
|
"kibana": {},
|
||||||
|
"solr": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
var imageBlacklistFullname = map[string]struct{}{
|
||||||
|
// headless browsers
|
||||||
|
"gcr.io/zenika-hub/alpine-chrome": {},
|
||||||
|
"eu.gcr.io/zenika-hub/alpine-chrome": {},
|
||||||
|
"us.gcr.io/zenika-hub/alpine-chrome": {},
|
||||||
|
"asia.gcr.io/zenika-hub/alpine-chrome": {},
|
||||||
|
|
||||||
|
// image update watchers
|
||||||
|
"watchtower": {},
|
||||||
|
"getwud/wud": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
var authorBlacklist = map[string]struct{}{
|
||||||
|
// headless browsers
|
||||||
|
"selenium": {},
|
||||||
|
"browserless": {},
|
||||||
|
"zenika": {},
|
||||||
|
|
||||||
|
"zabbix": {},
|
||||||
|
|
||||||
|
// docker
|
||||||
|
"moby": {},
|
||||||
|
"docker": {},
|
||||||
|
}
|
||||||
|
|
||||||
|
func (image *ContainerImage) IsBlacklisted() bool {
|
||||||
|
_, ok := imageBlacklist[image.Name]
|
||||||
|
if ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
_, ok = imageBlacklistFullname[image.Author+":"+image.Name]
|
||||||
|
if ok {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
_, ok = authorBlacklist[image.Author]
|
||||||
|
return ok
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Inspect(dockerHost string, containerID string) (*Container, error) {
|
func Inspect(dockerHost string, containerID string) (*Container, error) {
|
||||||
client, err := ConnectClient(dockerHost)
|
client, err := NewClient(dockerHost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -24,5 +24,5 @@ func (c *SharedClient) Inspect(containerID string) (*Container, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return FromJSON(json, c.key), nil
|
return FromInspectResponse(json, c.key), nil
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue