diff --git a/README.md b/README.md index 70a3c509..fef8d4ec 100644 --- a/README.md +++ b/README.md @@ -149,22 +149,28 @@ A simple way to generate and manage local certificates is using `mkcert`, as it To generate a certificate pair for use with HAProxy, you typically use the default domain `*.docker.amazee.io`, but you can substitute any domain as needed for your local development environment: -1. **Install mkcert** - Follow instructions at [mkcert GitHub](https://github.com/FiloSottile/mkcert). - Example for macOS: +### 1. Install mkcert and nss + + **Linux**: + + Follow instructions at [mkcert GitHub](https://github.com/FiloSottile/mkcert) and [nss GitHub](https://github.com/nss-dev/nss). + + **macOS**: ```shell - brew install mkcert + brew install mkcert nss mkcert -install # generates and installs the local CA ``` -2. **Generate a wildcard certificate and key** - Run: +### 2. Generate a wildcard certificate and key + + Run: ```shell mkcert "*.docker.amazee.io" ``` This creates `_wildcard.docker.amazee.io.pem` (certificate) and `_wildcard.docker.amazee.io-key.pem` (private key). -3. **Combine certificate and key for HAProxy** +### 3. Combine certificate and key for HAProxy + Run: ```shell mkdir -p ~/pygmy/ @@ -175,7 +181,7 @@ To generate a certificate pair for use with HAProxy, you typically use the defau ``` pygmy up --tls-cert=/location_to/haproxy.pem ``` - or can be stored in the default location of `~/pygmy/server.pem`. + or can be stored in the default location of `~/pygmy/server.pem` - which will attempt to load every time pygmy is started. **Notes:** diff --git a/external/docker/setup/setup.go b/external/docker/setup/setup.go index 5ad65741..6f153e2c 100644 --- a/external/docker/setup/setup.go +++ b/external/docker/setup/setup.go @@ -138,8 +138,8 @@ func Setup(ctx context.Context, cli *client.Client, c *Config) { ImportDefaults(ctx, cli, c, "amazeeio-ssh-agent", agent.New()) ImportDefaults(ctx, cli, c, "amazeeio-ssh-agent-add-key", key.NewAdder()) ImportDefaults(ctx, cli, c, "amazeeio-dnsmasq", dnsmasq.New(&dockerruntime.Params{Domain: c.Domain})) - ImportDefaults(ctx, cli, c, "amazeeio-haproxy", haproxy.New(&dockerruntime.Params{Domain: c.Domain}, c.TLSCertPath)) - ImportDefaults(ctx, cli, c, "amazeeio-mailhog", mailhog.New(&dockerruntime.Params{Domain: c.Domain})) + ImportDefaults(ctx, cli, c, "amazeeio-haproxy", haproxy.New(&dockerruntime.Params{Domain: c.Domain, TLSCertPath: c.TLSCertPath})) + ImportDefaults(ctx, cli, c, "amazeeio-mailhog", mailhog.New(&dockerruntime.Params{Domain: c.Domain, TLSCertPath: c.TLSCertPath})) // Disable Resolvers if needed. if c.ResolversDisabled { diff --git a/internal/runtime/docker/types.go b/internal/runtime/docker/types.go index 5a63a294..765fb41d 100644 --- a/internal/runtime/docker/types.go +++ b/internal/runtime/docker/types.go @@ -18,4 +18,6 @@ type Service struct { type Params struct { // Domain is the target domain for Pygmy to use. Domain string + // TLSCertPath is the TLS Certificate Path. + TLSCertPath string } diff --git a/internal/service/docker/haproxy/haproxy.go b/internal/service/docker/haproxy/haproxy.go index b88cf102..a063d70b 100644 --- a/internal/service/docker/haproxy/haproxy.go +++ b/internal/service/docker/haproxy/haproxy.go @@ -11,10 +11,10 @@ import ( ) // New will provide the standard object for the haproxy container. -func New(c *docker.Params, tlsCertPath string) docker.Service { +func New(c *docker.Params) docker.Service { binds := []string{"/var/run/docker.sock:/tmp/docker.sock"} - if tlsCertPath != "" { - binds = append(binds, fmt.Sprintf("%s:/app/server.pem:ro", tlsCertPath)) + if c.TLSCertPath != "" { + binds = append(binds, fmt.Sprintf("%s:/app/server.pem:ro", c.TLSCertPath)) } return docker.Service{ Config: container.Config{ @@ -28,7 +28,8 @@ func New(c *docker.Params, tlsCertPath string) docker.Service { "pygmy.weight": "14", }, Env: []string{ - fmt.Sprintf("AMAZEEIO_URL=%s", c.Domain), + "LAGOON_ROUTE=http://docker.amazee.io/stats", + fmt.Sprintf("AMAZEEIO_URL=http://%s", c.Domain), }, }, HostConfig: container.HostConfig{ diff --git a/internal/service/docker/haproxy/haproxy_test.go b/internal/service/docker/haproxy/haproxy_test.go index 1be670cf..302021bb 100644 --- a/internal/service/docker/haproxy/haproxy_test.go +++ b/internal/service/docker/haproxy/haproxy_test.go @@ -13,13 +13,13 @@ import ( ) func Example() { - haproxy.New(&docker.Params{}, "") + haproxy.New(&docker.Params{}) haproxy.NewDefaultPorts() } func Test(t *testing.T) { Convey("HAProxy: Field equality tests...", t, func() { - obj := haproxy.New(&docker.Params{Domain: "docker.amazee.io"}, "/path/to/ssl/cert.pem") + obj := haproxy.New(&docker.Params{Domain: "docker.amazee.io", TLSCertPath: "/path/to/ssl/cert.pem"}) objPorts := haproxy.NewDefaultPorts() So(obj.Config.Image, ShouldContainSubstring, "pygmystack/haproxy") So(obj.Config.Labels["pygmy.defaults"], ShouldEqual, "true") diff --git a/internal/service/docker/mailhog/mailhog.go b/internal/service/docker/mailhog/mailhog.go index dbd75d20..b084d7d8 100644 --- a/internal/service/docker/mailhog/mailhog.go +++ b/internal/service/docker/mailhog/mailhog.go @@ -14,7 +14,7 @@ import ( // New will provide the standard object for the mailhog container. func New(c *docker.Params) docker.Service { - return docker.Service{ + serviceSpec := docker.Service{ Config: container.Config{ User: "0", ExposedPorts: nat.PortSet{ @@ -34,7 +34,6 @@ func New(c *docker.Params) docker.Service { "pygmy.enable": "true", "pygmy.name": "amazeeio-mailhog", "pygmy.network": "amazeeio-network", - "pygmy.url": fmt.Sprintf("http://mailhog.%s", c.Domain), "pygmy.weight": "15", }, }, @@ -48,6 +47,15 @@ func New(c *docker.Params) docker.Service { NetworkConfig: network.NetworkingConfig{}, } + if c.TLSCertPath != "" { + serviceSpec.Config.Env = append(serviceSpec.Config.Env, "LAGOON_ROUTE=https://mailhog.docker.amazee.io") + serviceSpec.Config.Labels["pygmy.url"] = fmt.Sprintf("https://mailhog.%s", c.Domain) + } else { + serviceSpec.Config.Env = append(serviceSpec.Config.Env, "LAGOON_ROUTE=http://mailhog.docker.amazee.io") + serviceSpec.Config.Labels["pygmy.url"] = fmt.Sprintf("http://mailhog.%s", c.Domain) + } + + return serviceSpec } // NewDefaultPorts will provide the standard ports used for merging into the diff --git a/internal/service/docker/mailhog/mailhog_test.go b/internal/service/docker/mailhog/mailhog_test.go index 1b2e703f..6323924a 100644 --- a/internal/service/docker/mailhog/mailhog_test.go +++ b/internal/service/docker/mailhog/mailhog_test.go @@ -20,12 +20,12 @@ func Example() { func Test(t *testing.T) { Convey("MailHog: Field equality tests...", t, func() { - obj := mailhog.New(&docker.Params{Domain: "docker.amazee.io"}) + obj := mailhog.New(&docker.Params{Domain: "docker.amazee.io", TLSCertPath: ""}) objPorts := mailhog.NewDefaultPorts() So(obj.Config.User, ShouldEqual, "0") So(obj.Config.Image, ShouldContainSubstring, "pygmystack/mailhog") So(fmt.Sprint(obj.Config.ExposedPorts), ShouldEqual, fmt.Sprint(nat.PortSet{"80/tcp": struct{}{}, "1025/tcp": struct{}{}, "8025/tcp": struct{}{}})) - So(fmt.Sprint(obj.Config.Env), ShouldEqual, fmt.Sprint([]string{"MH_UI_BIND_ADDR=0.0.0.0:80", "MH_API_BIND_ADDR=0.0.0.0:80", "AMAZEEIO=AMAZEEIO", "AMAZEEIO_URL=mailhog.docker.amazee.io"})) + So(fmt.Sprint(obj.Config.Env), ShouldEqual, fmt.Sprint([]string{"MH_UI_BIND_ADDR=0.0.0.0:80", "MH_API_BIND_ADDR=0.0.0.0:80", "AMAZEEIO=AMAZEEIO", "AMAZEEIO_URL=mailhog.docker.amazee.io", "LAGOON_ROUTE=http://mailhog.docker.amazee.io"})) So(obj.Config.Labels["pygmy.defaults"], ShouldEqual, "true") So(obj.Config.Labels["pygmy.enable"], ShouldEqual, "true") So(obj.Config.Labels["pygmy.name"], ShouldEqual, "amazeeio-mailhog") diff --git a/internal/utils/endpoint/endpoint.go b/internal/utils/endpoint/endpoint.go index 46c126cf..b48f3a89 100644 --- a/internal/utils/endpoint/endpoint.go +++ b/internal/utils/endpoint/endpoint.go @@ -6,6 +6,7 @@ import ( "context" "crypto/tls" "net/http" + "strings" "time" ) @@ -19,13 +20,20 @@ func Validate(url string) bool { defer cancel() client := &http.Client{ - Timeout: 5 * time.Second, + Timeout: 2 * time.Second, Transport: &http.Transport{ TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, DisableKeepAlives: true, }, } + if strings.HasPrefix(url, "https://") { + client.Transport = &http.Transport{ + TLSClientConfig: &tls.Config{InsecureSkipVerify: false}, + DisableKeepAlives: true, + } + } + // Create a web request using HEAD for faster response req, err := http.NewRequestWithContext(ctx, "HEAD", url, nil) if err != nil { diff --git a/main_test.go b/main_test.go index 5fd77bc2..1407f86a 100644 --- a/main_test.go +++ b/main_test.go @@ -2,7 +2,6 @@ package main_test import ( "fmt" - "github.com/pygmystack/pygmy/internal/runtime/docker/internals" "os" "testing" "time" @@ -11,6 +10,7 @@ import ( "github.com/docker/docker/api/types/network" . "github.com/smartystreets/goconvey/convey" + "github.com/pygmystack/pygmy/internal/runtime/docker/internals" "github.com/pygmystack/pygmy/internal/runtime/docker/internals/containers" "github.com/pygmystack/pygmy/internal/runtime/docker/internals/images" ) @@ -194,7 +194,7 @@ func TestDefault(t *testing.T) { configuration := &config{ name: "default", configpath: "/examples/pygmy.basic.yml", - endpoints: []string{"http://docker.amazee.io/stats", "http://mailhog.docker.amazee.io"}, + endpoints: []string{"docker.amazee.io/stats", "mailhog.docker.amazee.io"}, images: []string{"pygmystack/haproxy", "pygmystack/dnsmasq", "pygmystack/mailhog"}, services: []string{"amazeeio-haproxy", "amazeeio-dnsmasq", "amazeeio-mailhog"}, servicewithports: []string{"amazeeio-haproxy", "amazeeio-mailhog"}, @@ -208,7 +208,7 @@ func TestCustom(t *testing.T) { configuration := &config{ name: "custom", configpath: "/examples/pygmy.complex.yml", - endpoints: []string{"http://traefik.docker.amazee.io", "http://mailhog.docker.amazee.io", "http://phpmyadmin.docker.amazee.io"}, + endpoints: []string{"traefik.docker.amazee.io", "mailhog.docker.amazee.io", "http://phpmyadmin.docker.amazee.io"}, images: []string{"pygmystack/ssh-agent", "pygmystack/mailhog", "phpmyadmin/phpmyadmin", "library/traefik:v2.1.3"}, services: []string{"unofficial-traefik-2", "unofficial-phpmyadmin", "amazeeio-mailhog"}, servicewithports: []string{"amazeeio-mailhog", "unofficial-phpmyadmin", "unofficial-traefik-2"},