Add arbitrary hosts by docker label

This commit is contained in:
Gábor Egyed 2021-06-29 06:10:31 +02:00
parent 5796a343ec
commit 7e6ab6eb04
No known key found for this signature in database
GPG key ID: 54D2EF7194E6CC79
3 changed files with 59 additions and 1 deletions

View file

@ -39,11 +39,15 @@ Entries are created for each container network with the following names:
Each container will thereforr have up to 4 entries per alias: CONTAINER_ALIAS, CONTAINER_ALIAS.PROJECT, CONTAINER_ALIAS.NETWORK_NAME, CONTAINER_ALIAS.PROJECT.NETWORK_NAME
Arbitrary hosts entries can be added via a custom label (`com.costela.docker-etchosts.add_hosts`) by specifying a single or array of host names.
This means the following `docker-compose.yml` setup for project `someproject`:
```yaml
services:
someservice:
...
labels:
- 'com.costela.docker-etchosts.add_hosts=["a.example.com", "b.example.com"]'
networks:
somenet:
aliases:
@ -51,7 +55,7 @@ services:
```
Would generate the following hosts entry:
```
x.x.x.x someservice someservice.somenet someservice.someproject someservice.someproject.somenet somealias somealias.somenet somealias.someproject somealias.someproject.somenet
x.x.x.x someservice someservice.somenet someservice.someproject someservice.someproject.somenet somealias somealias.somenet somealias.someproject somealias.someproject.somenet a.example.com b.example.com
```
_NOTE_: Docker ensures the uniqueness of containers' IP addresses and names, but does not ensure uniqueness for aliases. This may lead to multiple entries having the same name, especially for the shorter name versions. The longer, more explict, names are there to help in these cases, enabling different workflows with multiple projects.

View file

@ -2,6 +2,7 @@ package main
import (
"context"
"encoding/json"
"fmt"
"strings"
@ -89,6 +90,28 @@ func getIPsToNames(client dockerClienter, id string) (ipsToNamesMap, error) {
names = appendNames(names, name)
}
if label, ok := containerFull.Config.Labels["com.costela.docker-etchosts.add_hosts"]; ok {
if (strings.HasPrefix(label, "[")) {
var parsed []string;
err := json.Unmarshal([]byte(label), &parsed)
if err != nil {
log.Errorf("error parsing JSON: %s", err)
}
names = append(names, parsed...)
} else if (strings.HasPrefix(label, "\"")) {
var parsed string;
err := json.Unmarshal([]byte(label), &parsed)
if err != nil {
log.Errorf("error parsing JSON: %s", err)
}
names = append(names, parsed)
} else if (strings.HasPrefix(label, "{")) {
log.Errorf("JSON objects are not supported: %s", label)
} else {
names = append(names, label)
}
}
ipsToNames[netInfo.IPAddress] = names
}

View file

@ -46,6 +46,12 @@ func (testClient) ContainerList(_ context.Context, _ types.ContainerListOptions)
"/some_nonnetworked_service",
},
},
{
ID: "555",
Names: []string{
"/some_labeled_service",
},
},
}, nil
}
@ -118,6 +124,23 @@ func (testClient) ContainerInspect(_ context.Context, ID string) (types.Containe
},
},
}, nil
case "555":
return types.ContainerJSON{
ContainerJSONBase: &types.ContainerJSONBase{Name: "service5"},
Config: &container.Config{Labels: map[string]string{
"com.costela.docker-etchosts.add_hosts": "[\"a.example.com\", \"b.example.com\"]",
}},
NetworkSettings: &types.NetworkSettings{
Networks: map[string]*network.EndpointSettings{
"bridge": {
IPAddress: "5.6.7.8",
Aliases: []string{
"somealias",
},
},
},
},
}, nil
default:
panic("whaaa?")
}
@ -183,6 +206,11 @@ func Test_getIPsToNames(t *testing.T) {
"somesecondaryalias1", "somesecondaryalias1.somesecondarynetwork", "somesecondaryalias1.someotherproject", "somesecondaryalias1.someotherproject.somesecondarynetwork",
},
}, false},
{"query with label", args{testClient{}, "555"}, ipsToNamesMap{
"5.6.7.8": []string{
"service5", "somealias", "a.example.com", "b.example.com",
},
}, false},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -224,6 +252,9 @@ func Test_getAllIPsToNames(t *testing.T) {
"service3", "service3.somesecondarynetwork", "service3.someotherproject", "service3.someotherproject.somesecondarynetwork",
"somesecondaryalias1", "somesecondaryalias1.somesecondarynetwork", "somesecondaryalias1.someotherproject", "somesecondaryalias1.someotherproject.somesecondarynetwork",
},
"5.6.7.8": []string{
"service5", "somealias", "a.example.com", "b.example.com",
},
}, false},
}
for _, tt := range tests {