go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers/os/resources/discovery/docker_engine/container.go (about) 1 // Copyright (c) Mondoo, Inc. 2 // SPDX-License-Identifier: BUSL-1.1 3 4 package docker_engine 5 6 import ( 7 "context" 8 "strings" 9 10 "github.com/docker/docker/api/types" 11 "github.com/rs/zerolog/log" 12 "go.mondoo.com/cnquery/providers-sdk/v1/inventory" 13 "go.mondoo.com/cnquery/providers/os/id/containerid" 14 ) 15 16 func (e *dockerEngineDiscovery) containerList() ([]types.Container, error) { 17 dc, err := e.client() 18 if err != nil { 19 return nil, err 20 } 21 22 return dc.ContainerList(context.Background(), types.ContainerListOptions{}) 23 } 24 25 func (e *dockerEngineDiscovery) ListContainerShas() ([]string, error) { 26 containers, err := e.containerList() 27 if err != nil { 28 return []string{}, err 29 } 30 31 containerShas := []string{} 32 for i := range containers { 33 containerShas = append(containerShas, containers[i].ID) 34 } 35 36 return containerShas, nil 37 } 38 39 type ContainerInfo struct { 40 ID string 41 Name string 42 PlatformID string 43 Running bool 44 Labels map[string]string 45 Arch string 46 } 47 48 // will resolve name and id to a container id 49 func (e *dockerEngineDiscovery) ContainerInfo(name string) (ContainerInfo, error) { 50 ci := ContainerInfo{} 51 dc, err := e.client() 52 if err != nil { 53 return ci, err 54 } 55 56 cdata, err := dc.ContainerInspect(context.Background(), name) 57 if err != nil { 58 return ci, err 59 } 60 61 cName := cdata.Name 62 cName = strings.TrimPrefix(cName, "/") 63 if len(cName) == 0 { 64 cName = containerid.ShortContainerID(cdata.ID) 65 } 66 67 ci.ID = cdata.ID 68 ci.Name = cName 69 ci.PlatformID = containerid.MondooContainerID(ci.ID) 70 ci.Running = cdata.State.Running 71 72 // fetch docker specific metadata 73 labels := map[string]string{} 74 labels["docker.io/container-id"] = cdata.ID 75 labels["docker.io/image-name"] = cdata.Image 76 labels["docker.io/names"] = cName 77 78 ci.Labels = labels 79 80 return ci, nil 81 } 82 83 type ImageInfo struct { 84 ID string 85 Name string 86 PlatformID string 87 Labels map[string]string 88 Arch string 89 // Size in megabytes 90 Size int64 91 } 92 93 func (e *dockerEngineDiscovery) ImageInfo(name string) (ImageInfo, error) { 94 ii := ImageInfo{} 95 dc, err := e.client() 96 if err != nil { 97 return ii, err 98 } 99 100 res, _, err := dc.ImageInspectWithRaw(context.Background(), name) 101 if err != nil { 102 return ii, err 103 } 104 105 switch res.Architecture { 106 case "amd64": 107 ii.Arch = "x86_64" 108 } 109 110 ii.Size = res.Size / 1024 / 1024 111 112 labels := map[string]string{} 113 labels["mondoo.com/image-id"] = res.ID 114 labels["docker.io/tags"] = strings.Join(res.RepoTags, ",") 115 labels["docker.io/digests"] = strings.Join(res.RepoDigests, ",") 116 117 if len(res.RepoTags) > 0 { 118 ii.Name = res.RepoTags[0] + "@" 119 } 120 ii.Name = ii.Name + containerid.ShortContainerImageID(res.ID) 121 ii.ID = res.ID 122 ii.Labels = labels 123 ii.PlatformID = containerid.MondooContainerImageID(res.ID) 124 return ii, nil 125 } 126 127 func (e *dockerEngineDiscovery) ListContainer() ([]*inventory.Asset, error) { 128 dContainers, err := e.containerList() 129 if err != nil { 130 return nil, err 131 } 132 133 container := make([]*inventory.Asset, len(dContainers)) 134 for i, dContainer := range dContainers { 135 asset := &inventory.Asset{ 136 Connections: []*inventory.Config{ 137 { 138 Type: "docker-container", 139 Host: dContainer.ID, 140 }, 141 }, 142 } 143 log.Debug().Str("container", dContainer.ID).Msg("discovered container") 144 145 container[i] = asset 146 } 147 return container, nil 148 } 149 150 func mapContainerState(state string) inventory.State { 151 switch state { 152 case "running": 153 return inventory.State_STATE_RUNNING 154 case "created": 155 return inventory.State_STATE_PENDING 156 case "paused": 157 return inventory.State_STATE_STOPPED 158 case "exited": 159 return inventory.State_STATE_TERMINATED 160 case "restarting": 161 return inventory.State_STATE_PENDING 162 case "dead": 163 return inventory.State_STATE_ERROR 164 default: 165 log.Warn().Str("state", state).Msg("unknown container state") 166 return inventory.State_STATE_UNKNOWN 167 } 168 } 169 170 // DockerDisplayNames removes the leading slash of the internal docker name 171 // @see https://github.com/moby/moby/issues/6705 172 func DockerDisplayNames(names []string) []string { 173 if names == nil { 174 return nil 175 } 176 177 displayNames := make([]string, len(names)) 178 for i := range names { 179 displayNames[i] = strings.TrimLeft(names[i], "/") 180 } 181 182 return displayNames 183 }