1+ package com.eficode.devstack.container.impl
2+
3+ import de.gesellix.docker.client.DockerClientImpl
4+ import de.gesellix.docker.engine.DockerClientConfig
5+ import de.gesellix.docker.engine.DockerEnv
6+ import de.gesellix.docker.remote.api.ContainerInspectResponse
7+ import kong.unirest.Unirest
8+ import org.apache.commons.io.FileUtils
9+ import org.apache.commons.io.filefilter.FileFileFilter
10+ import org.slf4j.Logger
11+ import org.slf4j.LoggerFactory
12+ import spock.lang.Shared
13+ import spock.lang.Specification
14+
15+
16+ class NginxContainerTest extends Specification {
17+
18+ @Shared
19+ static Logger log = LoggerFactory . getLogger(NginxContainerTest . class)
20+
21+ @Shared
22+ DockerClientImpl dockerClient
23+
24+ @Shared
25+ File localNginxRoot = new File (" examples" )
26+
27+
28+ @Shared
29+ String dockerRemoteHost // = "https://docker.domain.se:2376"
30+ @Shared
31+ String dockerCertPath // = "resources/dockerCert"
32+ @Shared
33+ String nginxUrl = " http://localhost"
34+
35+
36+ def setupSpec () {
37+ dockerClient = resolveDockerClient()
38+ dockerClient. stop(" Nginx" )
39+ dockerClient. rm(" Nginx" )
40+
41+ assert localNginxRoot. listFiles(). findAll{it. isFile()}. size() > 0 : " localNginxRoot must contain at least one file"
42+
43+ }
44+
45+
46+ def " test default setup" () {
47+
48+ setup :
49+ NginxContainer nginxC = new NginxContainer ()
50+
51+ expect :
52+ nginxC. createContainer()
53+ nginxC. startContainer()
54+
55+ cleanup :
56+ nginxC. stopAndRemoveContainer()
57+
58+ }
59+
60+ def " test setting nginx root bind dir" () {
61+
62+ setup :
63+ log. info(" Testing setting nginx root dir" )
64+ log. info(" \t Will use dir:" + localNginxRoot. absolutePath)
65+
66+ NginxContainer nginxC = new NginxContainer ()
67+
68+ when : " bindHtmlRoot should add a mount to the mounts array"
69+ nginxC. bindHtmlRoot(localNginxRoot. absolutePath, true )
70+
71+ then :
72+ nginxC. mounts. size() == 1
73+
74+ when : " After creating the container, the inspect result should confirm the mount"
75+ nginxC. createContainer()
76+ nginxC. startContainer()
77+ ContainerInspectResponse inspectResponse = dockerClient. inspectContainer(nginxC. id). getContent()
78+ log. info(" \t Container created" )
79+
80+ then :
81+ inspectResponse. mounts. find {it. source == localNginxRoot. absolutePath}
82+ log. info(" \t Docker API confirms mount was created" )
83+
84+ expect : " Nginx should return the expected files"
85+ log. info(" \t Confirming Nginx returns files found in the bind directory" )
86+ localNginxRoot. listFiles(). findAll {it. isFile()}. every {file ->
87+ log. debug(" \t " * 2 + " Requesting file:" + file. name)
88+ int status = Unirest . get(nginxUrl + " /" + file. name). asEmpty(). status
89+ log. debug(" \t " * 3 + " HTTP Status:" + status)
90+ return status == 200
91+ }
92+
93+ Unirest . get(nginxUrl + " /MISSINGFILE" ). asEmpty(). status == 404
94+
95+
96+
97+
98+ }
99+
100+
101+ DockerClientImpl resolveDockerClient () {
102+
103+ if (this . dockerClient) {
104+ return this . dockerClient
105+ }
106+
107+ log. info(" Getting Docker client" )
108+
109+ if (! dockerRemoteHost) {
110+ log. info(" \t No remote host configured, returning local docker connection" )
111+ return new DockerClientImpl ()
112+ }
113+
114+ File certDir = new File (dockerCertPath)
115+
116+ if (! certDir. isDirectory()) {
117+ log. info(" \t No valid Docker Cert Path given, returning local docker connection" )
118+ return new DockerClientImpl ()
119+ }
120+ log. info(" \t Looking for docker certs in:" + certDir. absolutePath)
121+ ArrayList<File > pemFiles = FileUtils . listFiles(certDir, [" pem" ] as String [], false )
122+ log. debug(" \t\t Found pem files:" + pemFiles. name. join(" ," ))
123+
124+
125+ if (! pemFiles. empty && pemFiles. every { pemFile -> [" ca.pem" , " cert.pem" , " key.pem" ]. find { it == pemFile. name } }) {
126+ log. info(" \t Found Docker certs, returning Secure remote Docker connection" )
127+ try {
128+ DockerClientImpl dockerClient = setupSecureRemoteConnection(dockerRemoteHost, dockerCertPath)
129+ assert dockerClient. ping(). content as String == " OK" : " Error pinging remote Docker engine"
130+ return dockerClient
131+ } catch (ex) {
132+ log. error(" \t Error setting up connection to remote Docker engine:" + ex. message)
133+ log. info(" \t Returning local Docker connection" )
134+ return new DockerClientImpl ()
135+ }
136+
137+ }
138+
139+ log. info(" \t Missing Docker certs, returning local docker connection" )
140+
141+ return new DockerClientImpl ()
142+
143+ }
144+
145+ /**
146+ * Replaced the default docker connection (local) with a remote, secure one
147+ * @param host ex: "https://docker.domain.se:2376"
148+ * @param certPath folder containing ca.pem, cert.pem, key.pem
149+ */
150+ static DockerClientImpl setupSecureRemoteConnection (String host , String certPath ) {
151+
152+ DockerClientConfig dockerConfig = new DockerClientConfig (host)
153+ DockerEnv dockerEnv = new DockerEnv (host)
154+ dockerEnv. setCertPath(certPath)
155+ dockerEnv. setTlsVerify(" 1" )
156+ dockerConfig. apply(dockerEnv)
157+
158+ return new DockerClientImpl (dockerConfig)
159+
160+ }
161+
162+ }
0 commit comments