mirror of
https://github.com/micromdm/micromdm/
synced 2026-08-05 08:55:51 +08:00
Added micromdm/go4 as a dependency. (#229)
Improves http debug logging by also logging the sent response. Converts regular http logs to key-value format. Changes the http server options to httputil.ListenAndServe, which is antended to be a standard ListenAndServe method for all micromdm project. Adds environment variables as configuration options for sensitive values. Closes #196
This commit is contained in:
@@ -1,3 +1,8 @@
|
||||
# TBD
|
||||
|
||||
* Added ENV variables for sensitive flags: `MICROMDM_APNS_KEY_PASSWORD`,`MICROMDM_API_KEY`
|
||||
* Removed the `-redir-addr` flag. Redirect to HTTPS is only enabled when the 443 port is used.
|
||||
|
||||
# v1.1.0 June 05 2017
|
||||
|
||||
* Import and sign pkgs, generate appmanifest on import.
|
||||
|
||||
46
Gopkg.lock
generated
46
Gopkg.lock
generated
@@ -10,8 +10,8 @@
|
||||
[[projects]]
|
||||
name = "github.com/boltdb/bolt"
|
||||
packages = ["."]
|
||||
revision = "583e8937c61f1af6513608ccc75c97b6abdf4ff9"
|
||||
version = "v1.3.0"
|
||||
revision = "2f1ce7a837dcb8da3ec595b1dac9d0632f0f99e8"
|
||||
version = "v1.3.1"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
@@ -23,11 +23,11 @@
|
||||
branch = "master"
|
||||
name = "github.com/garyburd/go-oauth"
|
||||
packages = ["oauth"]
|
||||
revision = "d9dbc37b1a7acf4923050e614fc7861e3fbf42f9"
|
||||
revision = "166ce8d672783fbb5a72247c3cf459267717e1ec"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/go-kit/kit"
|
||||
packages = ["endpoint","log","metrics","transport/http"]
|
||||
packages = ["endpoint","log","log/level","metrics","transport/http"]
|
||||
revision = "fadad6fffe0466b19df9efd9acde5c9a52df5fa4"
|
||||
version = "v0.4.0"
|
||||
|
||||
@@ -40,8 +40,8 @@
|
||||
[[projects]]
|
||||
name = "github.com/go-stack/stack"
|
||||
packages = ["."]
|
||||
revision = "7a2f19628aabfe68f0766b59e74d6315f8347d22"
|
||||
version = "v1.5.3"
|
||||
revision = "817915b46b97fd7bb80e8ab6b69f01a53ac3eebf"
|
||||
version = "v1.6.0"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gogo/protobuf"
|
||||
@@ -53,7 +53,7 @@
|
||||
branch = "master"
|
||||
name = "github.com/golang/protobuf"
|
||||
packages = ["proto"]
|
||||
revision = "e325f446bebc2998605911c0a2650d9920361d4a"
|
||||
revision = "17ce1425424ab154092bbb43af630bd647f3bb0d"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/context"
|
||||
@@ -61,18 +61,18 @@
|
||||
revision = "1ea25387ff6f684839d82767c1733ff4d4d15d0a"
|
||||
version = "v1.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/handlers"
|
||||
packages = ["."]
|
||||
revision = "a4043c62cc2329bacda331d33fc908ab11ef0ec3"
|
||||
version = "v1.2.1"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/gorilla/mux"
|
||||
packages = ["."]
|
||||
revision = "bcd8bc72b08df0f70df986b97f95590779502d31"
|
||||
version = "v1.4.0"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/groob/finalizer"
|
||||
packages = [".","logutil"]
|
||||
revision = "4c2ed49aabdaa038f247d72d183e410757cdbe9c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/groob/plist"
|
||||
@@ -91,11 +91,17 @@
|
||||
packages = ["."]
|
||||
revision = "3e565f89e59266df10c92da54118bf13ec312905"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/micromdm/go4"
|
||||
packages = ["httputil","version"]
|
||||
revision = "486ea5f130c78a9c058374eb159df08296caea9d"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "github.com/micromdm/mdm"
|
||||
packages = ["."]
|
||||
revision = "1b8ad711b42f5510344c657a195d7eede8479728"
|
||||
revision = "97c19c7edf3498cf43b378042317d9d9caa84dc6"
|
||||
|
||||
[[projects]]
|
||||
name = "github.com/micromdm/scep"
|
||||
@@ -119,35 +125,35 @@
|
||||
branch = "master"
|
||||
name = "golang.org/x/crypto"
|
||||
packages = ["acme","acme/autocert","pkcs12","pkcs12/internal/rc2"]
|
||||
revision = "850760c427c516be930bc91280636328f1a62286"
|
||||
revision = "9ba3862cf6a5452ae579de98f9364dd2e544844c"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/net"
|
||||
packages = ["context","context/ctxhttp","http2","http2/hpack","idna","lex/httplex"]
|
||||
revision = "dfe83d419c9403b40b19d08cdba2afec27b002f7"
|
||||
revision = "66aacef3dd8a676686c7ae3716979581e8b03c47"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/sys"
|
||||
packages = ["unix"]
|
||||
revision = "0b25a408a50076fbbcae6b7ac0ea5fbb0b085e79"
|
||||
revision = "a5054c7c1385fd50d9394475365355a87a7873ec"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/text"
|
||||
packages = ["internal/gen","internal/triegen","internal/ucd","secure/bidirule","transform","unicode/bidi","unicode/cldr","unicode/norm","unicode/rangetable"]
|
||||
revision = "3491b61b9edc56653ad4333e605e2908e46a036b"
|
||||
revision = "bd91bbf73e9a4a801adbfb97133c992678533126"
|
||||
|
||||
[[projects]]
|
||||
branch = "master"
|
||||
name = "golang.org/x/tools"
|
||||
packages = ["go/ast/astutil","imports"]
|
||||
revision = "b4e0c5ecfb3125b1fbb235b1d381898d2b2a16d6"
|
||||
revision = "3b1faeda9afbcba128c2d794b38ffe7982141139"
|
||||
|
||||
[solve-meta]
|
||||
analyzer-name = "dep"
|
||||
analyzer-version = 1
|
||||
inputs-digest = "9502148927d630aed51089b18e46395f56995ed144a986d44a960379d1bff4b8"
|
||||
inputs-digest = "6ef27b152096e36c87702ca8c72c8fe0121399d323dc59d8b539dd4bc3ba4e9a"
|
||||
solver-name = "gps-cdcl"
|
||||
solver-version = 1
|
||||
|
||||
32
Makefile
32
Makefile
@@ -18,13 +18,13 @@ SHELL = /bin/bash
|
||||
|
||||
|
||||
BUILD_VERSION = "\
|
||||
-X github.com/micromdm/micromdm/version.appName=${APP_NAME} \
|
||||
-X github.com/micromdm/micromdm/version.version=${VERSION} \
|
||||
-X github.com/micromdm/micromdm/version.branch=${BRANCH} \
|
||||
-X github.com/micromdm/micromdm/version.buildUser=${USER} \
|
||||
-X github.com/micromdm/micromdm/version.buildDate=${NOW} \
|
||||
-X github.com/micromdm/micromdm/version.revision=${REVISION} \
|
||||
-X github.com/micromdm/micromdm/version.goVersion=${GOVERSION}"
|
||||
-X github.com/micromdm/micromdm/vendor/github.com/micromdm/go4/version.appName=${APP_NAME} \
|
||||
-X github.com/micromdm/micromdm/vendor/github.com/micromdm/go4/version.version=${VERSION} \
|
||||
-X github.com/micromdm/micromdm/vendor/github.com/micromdm/go4/version.branch=${BRANCH} \
|
||||
-X github.com/micromdm/micromdm/vendor/github.com/micromdm/go4/version.buildUser=${USER} \
|
||||
-X github.com/micromdm/micromdm/vendor/github.com/micromdm/go4/version.buildDate=${NOW} \
|
||||
-X github.com/micromdm/micromdm/vendor/github.com/micromdm/go4/version.revision=${REVISION} \
|
||||
-X github.com/micromdm/micromdm/vendor/github.com/micromdm/go4/version.goVersion=${GOVERSION}"
|
||||
|
||||
WORKSPACE = ${GOPATH}/src/github.com/micromdm/micromdm
|
||||
check-deps:
|
||||
@@ -63,21 +63,27 @@ INSTALL_STEPS := \
|
||||
|
||||
install-local: $(INSTALL_STEPS)
|
||||
|
||||
APP_NAME = mdmctl
|
||||
mdmctl: .pre-build
|
||||
.pre-mdmctl:
|
||||
$(eval APP_NAME = mdmctl)
|
||||
|
||||
mdmctl: .pre-build .pre-mdmctl
|
||||
go build -i -o build/darwin/mdmctl -ldflags ${BUILD_VERSION} ./cmd/mdmctl
|
||||
|
||||
install-mdmctl:
|
||||
install-mdmctl: .pre-mdmctl
|
||||
go install -ldflags ${BUILD_VERSION} ./cmd/mdmctl
|
||||
|
||||
APP_NAME = micromdm
|
||||
micromdm: .pre-build
|
||||
|
||||
.pre-micromdm:
|
||||
$(eval APP_NAME = micromdm)
|
||||
|
||||
micromdm: .pre-build .pre-micromdm
|
||||
go build -i -o build/darwin/micromdm -ldflags ${BUILD_VERSION} ./cmd/mdmctl
|
||||
|
||||
install-micromdm:
|
||||
install-micromdm: .pre-micromdm
|
||||
go install -ldflags ${BUILD_VERSION}
|
||||
|
||||
xp-micromdm: .pre-build
|
||||
xp-micromdm: .pre-build .pre-micromdm
|
||||
GOOS=darwin go build -i -o build/darwin/micromdm -ldflags ${BUILD_VERSION}
|
||||
GOOS=linux CGO_ENABLED=0 go build -i -o build/linux/micromdm -ldflags ${BUILD_VERSION}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"strings"
|
||||
"text/tabwriter"
|
||||
|
||||
"github.com/micromdm/micromdm/version"
|
||||
"github.com/micromdm/go4/version"
|
||||
)
|
||||
|
||||
func main() {
|
||||
|
||||
2
main.go
2
main.go
@@ -9,7 +9,7 @@ import (
|
||||
"text/tabwriter"
|
||||
"time"
|
||||
|
||||
"github.com/micromdm/micromdm/version"
|
||||
"github.com/micromdm/go4/version"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
177
serve.go
177
serve.go
@@ -14,16 +14,14 @@ import (
|
||||
"io/ioutil"
|
||||
stdlog "log"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
"github.com/fullsailor/pkcs7"
|
||||
"github.com/groob/finalizer/logutil"
|
||||
"github.com/micromdm/go4/env"
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
"golang.org/x/crypto/pkcs12"
|
||||
|
||||
@@ -32,11 +30,11 @@ import (
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
"github.com/go-kit/kit/log"
|
||||
httptransport "github.com/go-kit/kit/transport/http"
|
||||
"github.com/gorilla/handlers"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/micromdm/dep"
|
||||
"github.com/micromdm/go4/httputil"
|
||||
boltdepot "github.com/micromdm/scep/depot/bolt"
|
||||
scep "github.com/micromdm/scep/server"
|
||||
|
||||
@@ -84,15 +82,14 @@ func serve(args []string) error {
|
||||
var (
|
||||
flConfigPath = flagset.String("config-path", "/var/db/micromdm", "path to configuration directory")
|
||||
flServerURL = flagset.String("server-url", "", "public HTTPS url of your server")
|
||||
flAPIKey = flagset.String("api-key", "", "API Token for mdmctl command")
|
||||
flAPIKey = flagset.String("api-key", env.String("MICROMDM_API_KEY", ""), "API Token for mdmctl command")
|
||||
flAPNSCertPath = flagset.String("apns-cert", "", "path to APNS certificate")
|
||||
flAPNSKeyPass = flagset.String("apns-password", "", "password for your p12 APNS cert file (if using)")
|
||||
flAPNSKeyPass = flagset.String("apns-password", env.String("MICROMDM_APNS_KEY_PASSWORD", ""), "password for your p12 APNS cert file (if using)")
|
||||
flAPNSKeyPath = flagset.String("apns-key", "", "path to key file if using .pem push cert")
|
||||
flTLS = flagset.Bool("tls", true, "use https")
|
||||
flTLSCert = flagset.String("tls-cert", "", "path to TLS certificate")
|
||||
flTLSKey = flagset.String("tls-key", "", "path to TLS private key")
|
||||
flHTTPAddr = flagset.String("http-addr", ":https", "http(s) listen address of mdm server. defaults to :8080 if tls is false")
|
||||
flRedirAddr = flagset.String("redir-addr", ":http", "http redirect to https listen address")
|
||||
flHTTPDebug = flagset.Bool("http-debug", false, "enable debug for http(dumps full request)")
|
||||
flRepoPath = flagset.String("filerepo", "", "path to http file repo")
|
||||
flDepSim = flagset.Bool("depsim", false, "use depsim config")
|
||||
@@ -348,67 +345,61 @@ func serve(args []string) error {
|
||||
|
||||
var handler http.Handler
|
||||
if *flHTTPDebug {
|
||||
handler = debugHTTPmiddleware(r)
|
||||
handler = httputil.HTTPDebugMiddleware(os.Stdout, true, logger.Log)(r)
|
||||
} else {
|
||||
handler = r
|
||||
}
|
||||
handler = handlers.CombinedLoggingHandler(os.Stdout, handler)
|
||||
srv := &http.Server{
|
||||
Addr: *flHTTPAddr,
|
||||
Handler: handler,
|
||||
ReadTimeout: 60 * time.Second,
|
||||
WriteTimeout: 60 * time.Second,
|
||||
ReadHeaderTimeout: 10 * time.Second,
|
||||
IdleTimeout: 10 * time.Minute,
|
||||
MaxHeaderBytes: 1 << 18, // 0.25 MB
|
||||
TLSConfig: tlsConfig(),
|
||||
}
|
||||
handler = logutil.NewHTTPLogger(httpLogger).Middleware(handler)
|
||||
|
||||
srvURL, err := url.Parse(sm.ServerPublicURL)
|
||||
if err != nil {
|
||||
stdlog.Fatal(err)
|
||||
return errors.Wrapf(err, "parsing serverURL %q", sm.ServerPublicURL)
|
||||
}
|
||||
|
||||
errs := make(chan error, 2)
|
||||
go func() {
|
||||
sig := make(chan os.Signal)
|
||||
signal.Notify(sig, syscall.SIGINT, syscall.SIGTERM)
|
||||
<-sig // block on signal then gracefully shutdown.
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second)
|
||||
defer cancel()
|
||||
errs <- srv.Shutdown(ctx)
|
||||
}()
|
||||
serveOpts := serveOptions(
|
||||
handler,
|
||||
*flHTTPAddr,
|
||||
srvURL.Hostname(),
|
||||
logger,
|
||||
*flTLSCert,
|
||||
*flTLSKey,
|
||||
sm.configPath,
|
||||
*flTLS,
|
||||
)
|
||||
err = httputil.ListenAndServe(serveOpts...)
|
||||
return errors.Wrap(err, "calling ListenAndServe")
|
||||
}
|
||||
|
||||
go func() {
|
||||
logger := log.With(logger, "transport", "HTTP")
|
||||
if !*flTLS {
|
||||
var httpAddr string
|
||||
if *flHTTPAddr == ":https" {
|
||||
httpAddr = ":8080"
|
||||
} else {
|
||||
httpAddr = *flHTTPAddr
|
||||
}
|
||||
logger.Log("addr", httpAddr)
|
||||
errs <- http.ListenAndServe(httpAddr, handler)
|
||||
return
|
||||
}
|
||||
|
||||
tlsFromFile := (*flTLSCert != "" && *flTLSKey != "")
|
||||
if tlsFromFile {
|
||||
logger.Log("addr", srv.Addr)
|
||||
redirectTLS(*flRedirAddr, sm.ServerPublicURL)
|
||||
errs <- serveTLS(srv, *flTLSCert, *flTLSKey)
|
||||
return
|
||||
} else {
|
||||
logger.Log("addr", srv.Addr)
|
||||
redirectTLS(*flRedirAddr, sm.ServerPublicURL)
|
||||
errs <- serveACME(srv, srvURL.Hostname(), filepath.Join(sm.configPath, "le-certificates"))
|
||||
return
|
||||
}
|
||||
}()
|
||||
|
||||
mainLogger.Log("terminated", <-errs)
|
||||
return nil
|
||||
// serveOptions configures the []httputil.Options for ListenAndServe
|
||||
func serveOptions(
|
||||
handler http.Handler,
|
||||
addr string,
|
||||
hostname string,
|
||||
logger log.Logger,
|
||||
certPath string,
|
||||
keyPath string,
|
||||
configPath string,
|
||||
tls bool,
|
||||
) []httputil.Option {
|
||||
tlsFromFile := (certPath != "" && keyPath != "")
|
||||
serveOpts := []httputil.Option{
|
||||
httputil.WithACMEHosts([]string{hostname}),
|
||||
httputil.WithLogger(logger),
|
||||
httputil.WithHTTPHandler(handler),
|
||||
}
|
||||
if tlsFromFile {
|
||||
serveOpts = append(serveOpts, httputil.WithKeyPair(certPath, keyPath))
|
||||
}
|
||||
if !tls && addr == ":https" {
|
||||
serveOpts = append(serveOpts, httputil.WithAddress(":8080"))
|
||||
}
|
||||
if tls {
|
||||
serveOpts = append(serveOpts, httputil.WithAutocertCache(autocert.DirCache(filepath.Join(configPath, "le-certificates"))))
|
||||
}
|
||||
if addr != ":https" {
|
||||
serveOpts = append(serveOpts, httputil.WithAddress(addr))
|
||||
}
|
||||
return serveOpts
|
||||
}
|
||||
|
||||
func printExamples() {
|
||||
@@ -424,57 +415,6 @@ func printExamples() {
|
||||
fmt.Println(exampleText)
|
||||
}
|
||||
|
||||
func serveTLS(server *http.Server, certPath, keyPath string) error {
|
||||
err := server.ListenAndServeTLS(certPath, keyPath)
|
||||
return err
|
||||
}
|
||||
|
||||
func serveACME(server *http.Server, domain, cachePath string) error {
|
||||
m := autocert.Manager{
|
||||
Prompt: autocert.AcceptTOS,
|
||||
HostPolicy: autocert.HostWhitelist(domain),
|
||||
Cache: autocert.DirCache(cachePath),
|
||||
}
|
||||
server.TLSConfig.GetCertificate = m.GetCertificate
|
||||
err := server.ListenAndServeTLS("", "")
|
||||
return err
|
||||
}
|
||||
|
||||
// redirects port 80 to port 443
|
||||
func redirectTLS(addr, serverUrl string) {
|
||||
srv := &http.Server{
|
||||
Addr: addr,
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 5 * time.Second,
|
||||
Handler: http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
w.Header().Set("Connection", "close")
|
||||
url := serverUrl + req.URL.String()
|
||||
http.Redirect(w, req, url, http.StatusMovedPermanently)
|
||||
}),
|
||||
}
|
||||
go func() { stdlog.Fatal(srv.ListenAndServe()) }()
|
||||
}
|
||||
|
||||
func tlsConfig() *tls.Config {
|
||||
cfg := &tls.Config{
|
||||
PreferServerCipherSuites: true,
|
||||
CurvePreferences: []tls.CurveID{
|
||||
tls.CurveP256,
|
||||
tls.X25519,
|
||||
},
|
||||
MinVersion: tls.VersionTLS12,
|
||||
CipherSuites: []uint16{
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,
|
||||
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
||||
tls.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,
|
||||
},
|
||||
}
|
||||
return cfg
|
||||
}
|
||||
|
||||
type config struct {
|
||||
configPath string
|
||||
depsim bool
|
||||
@@ -792,21 +732,6 @@ func (c *config) setupSCEP(logger log.Logger) {
|
||||
}
|
||||
}
|
||||
|
||||
func debugHTTPmiddleware(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
body := io.TeeReader(r.Body, os.Stderr)
|
||||
r.Body = ioutil.NopCloser(body)
|
||||
out, err := httputil.DumpRequest(r, true)
|
||||
if err != nil {
|
||||
stdlog.Println(err)
|
||||
}
|
||||
fmt.Println("")
|
||||
fmt.Println(string(out))
|
||||
fmt.Println("")
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// TODO: move to separate package/library
|
||||
func mdmAuthSignMessageMiddleware(db *boltdepot.Depot, next http.Handler) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
// Package version provides utilities for displaying version information.
|
||||
package version
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// go build -ldflags "-X github.com/micromdm/micromdm/version.version=1.0.0"
|
||||
var (
|
||||
version = "unknown"
|
||||
branch = "unknown"
|
||||
revision = "unknown"
|
||||
goVersion = "unknown"
|
||||
buildDate = "unknown"
|
||||
buildUser = "unknown"
|
||||
appName = "micromdm"
|
||||
)
|
||||
|
||||
// Info holds version and build info about the app.
|
||||
type Info struct {
|
||||
Version string `json:"version"`
|
||||
Branch string `json:"branch"`
|
||||
Revision string `json:"revision"`
|
||||
GoVersion string `json:"go_version"`
|
||||
BuildDate string `json:"build_date"`
|
||||
BuildUser string `json:"build_user"`
|
||||
}
|
||||
|
||||
// Version returns a struct with the current version information.
|
||||
func Version() Info {
|
||||
return Info{
|
||||
Version: version,
|
||||
Branch: branch,
|
||||
Revision: revision,
|
||||
GoVersion: goVersion,
|
||||
BuildDate: buildDate,
|
||||
BuildUser: buildUser,
|
||||
}
|
||||
}
|
||||
|
||||
// Print outputs the app name and version string.
|
||||
func Print() {
|
||||
v := Version()
|
||||
fmt.Printf("%s version %s\n", appName, v.Version)
|
||||
}
|
||||
|
||||
// PrintFull outputs the app name and detailed version information.
|
||||
func PrintFull() {
|
||||
v := Version()
|
||||
fmt.Printf("%s - version %s\n", appName, v.Version)
|
||||
fmt.Printf(" branch: \t%s\n", v.Branch)
|
||||
fmt.Printf(" revision: \t%s\n", v.Revision)
|
||||
fmt.Printf(" build date: \t%s\n", v.BuildDate)
|
||||
fmt.Printf(" build user: \t%s\n", v.BuildUser)
|
||||
fmt.Printf(" go version: \t%s\n", v.GoVersion)
|
||||
}
|
||||
|
||||
// Handler provides an HTTP Handler which returns JSON formatted version info.
|
||||
func Handler() http.Handler {
|
||||
v := Version()
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
enc := json.NewEncoder(w)
|
||||
enc.SetIndent("", " ")
|
||||
enc.Encode(v)
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user