Skip to content

Commit 18452c9

Browse files
authored
Merge pull request #127 from lucaslorentz/126-skip-network-validation
Allow skip network validation
2 parents add5f83 + d5f2764 commit 18452c9

File tree

5 files changed

+123
-23
lines changed

5 files changed

+123
-23
lines changed

README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,9 @@ This plugin provides these flags:
287287
-docker-polling-interval duration
288288
Interval caddy should manually check docker for a new caddyfile (default 30s)
289289
-proxy-service-tasks
290-
Proxy to service tasks instead of VIP
290+
Proxy to service tasks instead of VIP (default false)
291+
-docker-validate-network
292+
Validates if caddy container and target are in same network (default true)
291293
```
292294

293295
Those flags can also be set via environment variables:
@@ -297,6 +299,7 @@ CADDY_DOCKER_LABEL_PREFIX=<string>
297299
CADDY_DOCKER_CADDYFILE_PATH=<string>
298300
CADDY_DOCKER_POLLING_INTERVAL=<duration>
299301
CADDY_DOCKER_PROXY_SERVICE_TASKS=<bool>
302+
CADDY_DOCKER_VALIDATE_NETWORK=<bool>
300303
```
301304

302305
## Caddy Telemetry

plugin/generator.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ type CaddyfileGenerator struct {
2828
labelPrefix string
2929
labelRegex *regexp.Regexp
3030
proxyServiceTasks bool
31+
validateNetwork bool
3132
dockerClient DockerClient
3233
dockerUtils DockerUtils
3334
caddyNetworks map[string]bool
@@ -41,18 +42,21 @@ var suffixRegex = regexp.MustCompile("_\\d+$")
4142
var labelPrefixFlag string
4243
var caddyFilePath string
4344
var proxyServiceTasksFlag bool
45+
var validateNetworkFlag bool
4446

4547
func init() {
4648
flag.StringVar(&labelPrefixFlag, "docker-label-prefix", defaultLabelPrefix, "Prefix for Docker labels")
4749
flag.StringVar(&caddyFilePath, "docker-caddyfile-path", "", "Path to a default CaddyFile")
4850
flag.BoolVar(&proxyServiceTasksFlag, "proxy-service-tasks", false, "Proxy to service tasks instead of VIP")
51+
flag.BoolVar(&validateNetworkFlag, "docker-validate-network", true, "Validates if caddy container and target are in same network")
4952
}
5053

5154
// GeneratorOptions are the options for generator
5255
type GeneratorOptions struct {
5356
caddyFilePath string
5457
labelPrefix string
5558
proxyServiceTasks bool
59+
validateNetwork bool
5660
}
5761

5862
// GetGeneratorOptions creates generator options from cli flags and environment variables
@@ -77,6 +81,12 @@ func GetGeneratorOptions() *GeneratorOptions {
7781
options.proxyServiceTasks = proxyServiceTasksFlag
7882
}
7983

84+
if validateNetworkEnv := os.Getenv("CADDY_DOCKER_VALIDATE_NETWORK"); validateNetworkEnv != "" {
85+
options.validateNetwork = isTrue.MatchString(validateNetworkEnv)
86+
} else {
87+
options.validateNetwork = validateNetworkFlag
88+
}
89+
8090
return &options
8191
}
8292

@@ -91,6 +101,7 @@ func CreateGenerator(dockerClient DockerClient, dockerUtils DockerUtils, options
91101
labelPrefix: options.labelPrefix,
92102
labelRegex: regexp.MustCompile(labelRegexString),
93103
proxyServiceTasks: options.proxyServiceTasks,
104+
validateNetwork: options.validateNetwork,
94105
}
95106
}
96107

@@ -99,7 +110,7 @@ func (g *CaddyfileGenerator) GenerateCaddyFile() ([]byte, string) {
99110
var caddyfileBuffer bytes.Buffer
100111
var logsBuffer bytes.Buffer
101112

102-
if g.caddyNetworks == nil {
113+
if g.validateNetwork && g.caddyNetworks == nil {
103114
networks, err := g.getCaddyNetworks()
104115
if err == nil {
105116
g.caddyNetworks = map[string]bool{}
@@ -266,6 +277,13 @@ func (g *CaddyfileGenerator) getContainerDirectives(container *types.Container)
266277
}
267278

268279
func (g *CaddyfileGenerator) getContainerIPAddress(container *types.Container) (string, error) {
280+
if !g.validateNetwork {
281+
for _, network := range container.NetworkSettings.Networks {
282+
return network.IPAddress, nil
283+
}
284+
return "", fmt.Errorf("Container %v doesn't have any network", container.ID)
285+
}
286+
269287
for _, network := range container.NetworkSettings.Networks {
270288
if _, isCaddyNetwork := g.caddyNetworks[network.NetworkID]; isCaddyNetwork {
271289
return network.IPAddress, nil
@@ -294,6 +312,13 @@ func (g *CaddyfileGenerator) getServiceProxyTarget(service *swarm.Service) (stri
294312
}
295313

296314
func (g *CaddyfileGenerator) getServiceIPAddress(service *swarm.Service) (string, error) {
315+
if !g.validateNetwork {
316+
for _, virtualIP := range service.Endpoint.VirtualIPs {
317+
return virtualIP.Addr, nil
318+
}
319+
return "", fmt.Errorf("Service %v doesn't have any virtual IP", service.ID)
320+
}
321+
297322
for _, virtualIP := range service.Endpoint.VirtualIPs {
298323
if _, isCaddyNetwork := g.caddyNetworks[virtualIP.NetworkID]; isCaddyNetwork {
299324
return virtualIP.Addr, nil

plugin/generator_test.go

Lines changed: 83 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func TestAddContainerWithTemplates(t *testing.T) {
5252
" proxy / 172.17.0.2:5000/api\n" +
5353
"}\n"
5454

55-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
55+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
5656
}
5757

5858
func TestAddContainerPicksRightNetwork(t *testing.T) {
@@ -81,7 +81,7 @@ func TestAddContainerPicksRightNetwork(t *testing.T) {
8181
" proxy / 172.17.0.2\n" +
8282
"}\n"
8383

84-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
84+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
8585
}
8686

8787
func TestAddContainerWithMinimumBasicLabels(t *testing.T) {
@@ -106,7 +106,7 @@ func TestAddContainerWithMinimumBasicLabels(t *testing.T) {
106106
" proxy / 172.17.0.2\n" +
107107
"}\n"
108108

109-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
109+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
110110
}
111111

112112
func TestAddContainerWithAllBasicLabels(t *testing.T) {
@@ -134,7 +134,7 @@ func TestAddContainerWithAllBasicLabels(t *testing.T) {
134134
" proxy / https://172.17.0.2:5000/api\n" +
135135
"}\n"
136136

137-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
137+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
138138
}
139139

140140
func TestAddContainerFromDifferentNetwork(t *testing.T) {
@@ -161,7 +161,35 @@ func TestAddContainerFromDifferentNetwork(t *testing.T) {
161161
const expectedLogs = skipCaddyfileText +
162162
"[ERROR] Container CONTAINER-ID and caddy are not in same network\n"
163163

164-
testGeneration(t, dockerClient, false, expectedCaddyfile, expectedLogs)
164+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, expectedLogs)
165+
}
166+
167+
func TestAddContainerFromDifferentNetworkSkipValidation(t *testing.T) {
168+
dockerClient := createBasicDockerClientMock()
169+
dockerClient.ContainersData = []types.Container{
170+
types.Container{
171+
ID: "CONTAINER-ID",
172+
NetworkSettings: &types.SummaryNetworkSettings{
173+
Networks: map[string]*network.EndpointSettings{
174+
"other-network": &network.EndpointSettings{
175+
IPAddress: "10.0.0.1",
176+
NetworkID: "other-network-id",
177+
},
178+
},
179+
},
180+
Labels: map[string]string{
181+
fmtLabel("%s.address"): "service.testdomain.com",
182+
},
183+
},
184+
}
185+
186+
const expectedCaddyfile = "service.testdomain.com {\n" +
187+
" proxy / 10.0.0.1\n" +
188+
"}\n"
189+
190+
const expectedLogs = skipCaddyfileText
191+
192+
testGeneration(t, dockerClient, false, false, expectedCaddyfile, expectedLogs)
165193
}
166194

167195
func TestAddContainerWithMultipleConfigs(t *testing.T) {
@@ -201,7 +229,7 @@ func TestAddContainerWithMultipleConfigs(t *testing.T) {
201229
" }\n" +
202230
"}\n"
203231

204-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
232+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
205233
}
206234

207235
func TestAddContainerWithReplicas(t *testing.T) {
@@ -239,7 +267,7 @@ func TestAddContainerWithReplicas(t *testing.T) {
239267
" proxy / 172.17.0.2 172.17.0.3\n" +
240268
"}\n"
241269

242-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
270+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
243271
}
244272

245273
func TestDoNotMergeProxiesWithDifferentLabelKey(t *testing.T) {
@@ -280,7 +308,7 @@ func TestDoNotMergeProxiesWithDifferentLabelKey(t *testing.T) {
280308
" proxy /b service-b\n" +
281309
"}\n"
282310

283-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
311+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
284312
}
285313

286314
func TestAddContainersWithSnippets(t *testing.T) {
@@ -329,7 +357,7 @@ func TestAddContainersWithSnippets(t *testing.T) {
329357
" proxy / 172.17.0.3\n" +
330358
"}\n"
331359

332-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
360+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
333361
}
334362

335363
func TestAddServiceWithTemplates(t *testing.T) {
@@ -386,7 +414,7 @@ func TestAddServiceWithTemplates(t *testing.T) {
386414
" }\n" +
387415
"}\n"
388416

389-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
417+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
390418
}
391419

392420
func TestUseTemplatesToGenerateEmptyValues(t *testing.T) {
@@ -423,7 +451,7 @@ func TestUseTemplatesToGenerateEmptyValues(t *testing.T) {
423451
" }\n" +
424452
"}\n"
425453

426-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
454+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
427455
}
428456

429457
func TestAddServiceWithMinimumBasicLabels(t *testing.T) {
@@ -452,7 +480,7 @@ func TestAddServiceWithMinimumBasicLabels(t *testing.T) {
452480
" proxy / service\n" +
453481
"}\n"
454482

455-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
483+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
456484
}
457485

458486
func TestAddServiceWithAllBasicLabels(t *testing.T) {
@@ -484,7 +512,7 @@ func TestAddServiceWithAllBasicLabels(t *testing.T) {
484512
" proxy / https://service:5000/api\n" +
485513
"}\n"
486514

487-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
515+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
488516
}
489517

490518
func TestAddServiceWithMultipleConfigs(t *testing.T) {
@@ -537,7 +565,7 @@ func TestAddServiceWithMultipleConfigs(t *testing.T) {
537565
" }\n" +
538566
"}\n"
539567

540-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
568+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
541569
}
542570

543571
func TestAddServiceProxyServiceTasks(t *testing.T) {
@@ -567,7 +595,7 @@ func TestAddServiceProxyServiceTasks(t *testing.T) {
567595
" proxy / tasks.service:5000\n" +
568596
"}\n"
569597

570-
testGeneration(t, dockerClient, true, expectedCaddyfile, skipCaddyfileText)
598+
testGeneration(t, dockerClient, true, true, expectedCaddyfile, skipCaddyfileText)
571599
}
572600

573601
func TestAddServiceMultipleAddresses(t *testing.T) {
@@ -596,7 +624,7 @@ func TestAddServiceMultipleAddresses(t *testing.T) {
596624
" proxy / service\n" +
597625
"}\n"
598626

599-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
627+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
600628
}
601629

602630
func TestAutomaticProxyDoesntOverrideCustomWithSameKey(t *testing.T) {
@@ -628,7 +656,7 @@ func TestAutomaticProxyDoesntOverrideCustomWithSameKey(t *testing.T) {
628656
" proxy /api external-api\n" +
629657
"}\n"
630658

631-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
659+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
632660
}
633661

634662
func TestAddServiceFromDifferentNetwork(t *testing.T) {
@@ -659,7 +687,39 @@ func TestAddServiceFromDifferentNetwork(t *testing.T) {
659687
const expectedLogs = skipCaddyfileText +
660688
"[ERROR] Service SERVICE-ID and caddy are not in same network\n"
661689

662-
testGeneration(t, dockerClient, false, expectedCaddyfile, expectedLogs)
690+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, expectedLogs)
691+
}
692+
693+
func TestAddServiceFromDifferentNetworkSkipValidation(t *testing.T) {
694+
dockerClient := createBasicDockerClientMock()
695+
dockerClient.ServicesData = []swarm.Service{
696+
swarm.Service{
697+
ID: "SERVICE-ID",
698+
Spec: swarm.ServiceSpec{
699+
Annotations: swarm.Annotations{
700+
Name: "service",
701+
Labels: map[string]string{
702+
fmtLabel("%s.address"): "service.testdomain.com",
703+
},
704+
},
705+
},
706+
Endpoint: swarm.Endpoint{
707+
VirtualIPs: []swarm.EndpointVirtualIP{
708+
swarm.EndpointVirtualIP{
709+
NetworkID: "other-network-id",
710+
},
711+
},
712+
},
713+
},
714+
}
715+
716+
const expectedCaddyfile = "service.testdomain.com {\n" +
717+
" proxy / service\n" +
718+
"}\n"
719+
720+
const expectedLogs = skipCaddyfileText
721+
722+
testGeneration(t, dockerClient, false, false, expectedCaddyfile, expectedLogs)
663723
}
664724

665725
func TestAddServiceSwarmDisable(t *testing.T) {
@@ -696,7 +756,7 @@ func TestAddServiceSwarmDisable(t *testing.T) {
696756
"[INFO] Skipping services because swarm is not available\n" +
697757
"[INFO] Skipping configs because swarm is not available\n"
698758

699-
testGeneration(t, dockerClient, false, expectedCaddyfile, expectedLogs)
759+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, expectedLogs)
700760
}
701761

702762
func TestAddDockerConfigContent(t *testing.T) {
@@ -723,7 +783,7 @@ func TestAddDockerConfigContent(t *testing.T) {
723783
" tls off+\n" +
724784
"}\n"
725785

726-
testGeneration(t, dockerClient, false, expectedCaddyfile, skipCaddyfileText)
786+
testGeneration(t, dockerClient, false, true, expectedCaddyfile, skipCaddyfileText)
727787
}
728788

729789
func TestIgnoreLabelsWithoutCaddyPrefix(t *testing.T) {
@@ -753,13 +813,14 @@ func TestIgnoreLabelsWithoutCaddyPrefix(t *testing.T) {
753813

754814
const expectedCaddyfile = ""
755815

756-
testGeneration(t, dockerClient, true, expectedCaddyfile, skipCaddyfileText)
816+
testGeneration(t, dockerClient, true, true, expectedCaddyfile, skipCaddyfileText)
757817
}
758818

759819
func testGeneration(
760820
t *testing.T,
761821
dockerClient DockerClient,
762822
proxyServiceTasks bool,
823+
validateNetwork bool,
763824
expectedCaddyfile string,
764825
expectedLogs string,
765826
) {
@@ -768,6 +829,7 @@ func testGeneration(
768829
generator := CreateGenerator(dockerClient, dockerUtils, &GeneratorOptions{
769830
labelPrefix: defaultLabelPrefix,
770831
proxyServiceTasks: proxyServiceTasks,
832+
validateNetwork: validateNetwork,
771833
})
772834

773835
caddyfileBytes, logs := generator.GenerateCaddyFile()

plugin/go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ require (
1313
github.com/gogo/protobuf v1.2.1 // indirect
1414
github.com/opencontainers/go-digest v1.0.0-rc1 // indirect
1515
github.com/opencontainers/image-spec v1.0.1 // indirect
16+
github.com/stretchr/testify v1.3.0
1617
google.golang.org/grpc v1.23.0 // indirect
1718
)

0 commit comments

Comments
 (0)