2016-12-14 15:41:48 +00:00
// Package cmd is an interface for parsing the command line
2015-02-14 23:33:21 +00:00
package cmd
import (
2020-07-08 08:50:08 +01:00
"crypto/tls"
"crypto/x509"
2020-06-24 11:46:51 +01:00
"fmt"
2020-07-08 08:50:08 +01:00
"io/ioutil"
2015-12-05 19:25:36 +00:00
"math/rand"
2015-05-16 00:34:02 +01:00
"strings"
2015-12-05 19:25:36 +00:00
"time"
2015-02-14 23:33:21 +00:00
2020-02-03 08:16:02 +00:00
"github.com/micro/go-micro/v2/auth"
2020-03-12 18:13:03 +00:00
"github.com/micro/go-micro/v2/auth/provider"
2020-01-30 14:39:00 +03:00
"github.com/micro/go-micro/v2/broker"
"github.com/micro/go-micro/v2/client"
2020-05-14 11:25:19 +01:00
"github.com/micro/go-micro/v2/client/grpc"
2020-03-12 18:13:03 +00:00
"github.com/micro/go-micro/v2/config"
2020-05-11 17:57:39 +01:00
configSrc "github.com/micro/go-micro/v2/config/source"
2020-03-12 18:13:03 +00:00
configSrv "github.com/micro/go-micro/v2/config/source/service"
2020-02-26 00:42:43 +08:00
"github.com/micro/go-micro/v2/debug/profile"
"github.com/micro/go-micro/v2/debug/profile/http"
"github.com/micro/go-micro/v2/debug/profile/pprof"
2020-01-30 14:39:00 +03:00
"github.com/micro/go-micro/v2/debug/trace"
2020-03-11 20:55:39 +03:00
"github.com/micro/go-micro/v2/logger"
2020-01-30 14:39:00 +03:00
"github.com/micro/go-micro/v2/registry"
2020-05-14 11:06:22 +01:00
registrySrv "github.com/micro/go-micro/v2/registry/service"
2020-06-24 11:46:51 +01:00
"github.com/micro/go-micro/v2/router"
2020-01-30 14:39:00 +03:00
"github.com/micro/go-micro/v2/runtime"
2020-07-01 17:06:59 +01:00
"github.com/micro/go-micro/v2/selector"
2020-01-30 14:39:00 +03:00
"github.com/micro/go-micro/v2/server"
"github.com/micro/go-micro/v2/store"
"github.com/micro/go-micro/v2/transport"
2020-06-03 09:43:20 +01:00
authutil "github.com/micro/go-micro/v2/util/auth"
2020-05-14 11:25:19 +01:00
"github.com/micro/go-micro/v2/util/wrapper"
2020-01-19 00:55:01 +00:00
// clients
2020-01-30 14:39:00 +03:00
cgrpc "github.com/micro/go-micro/v2/client/grpc"
cmucp "github.com/micro/go-micro/v2/client/mucp"
2020-01-19 00:55:01 +00:00
// servers
2020-01-29 15:45:11 +00:00
"github.com/micro/cli/v2"
2020-02-26 00:42:43 +08:00
2020-01-30 14:39:00 +03:00
sgrpc "github.com/micro/go-micro/v2/server/grpc"
smucp "github.com/micro/go-micro/v2/server/mucp"
2016-04-26 18:49:02 +01:00
// brokers
2020-04-11 03:46:54 +03:00
brokerHttp "github.com/micro/go-micro/v2/broker/http"
2020-01-30 14:39:00 +03:00
"github.com/micro/go-micro/v2/broker/memory"
"github.com/micro/go-micro/v2/broker/nats"
brokerSrv "github.com/micro/go-micro/v2/broker/service"
2016-04-26 18:49:02 +01:00
// registries
2020-01-30 14:39:00 +03:00
"github.com/micro/go-micro/v2/registry/etcd"
"github.com/micro/go-micro/v2/registry/mdns"
rmem "github.com/micro/go-micro/v2/registry/memory"
regSrv "github.com/micro/go-micro/v2/registry/service"
2016-04-26 18:49:02 +01:00
2020-06-24 11:46:51 +01:00
// routers
dnsRouter "github.com/micro/go-micro/v2/router/dns"
regRouter "github.com/micro/go-micro/v2/router/registry"
srvRouter "github.com/micro/go-micro/v2/router/service"
staticRouter "github.com/micro/go-micro/v2/router/static"
2020-02-05 13:59:35 +00:00
// runtimes
kRuntime "github.com/micro/go-micro/v2/runtime/kubernetes"
lRuntime "github.com/micro/go-micro/v2/runtime/local"
srvRuntime "github.com/micro/go-micro/v2/runtime/service"
2016-04-26 18:49:02 +01:00
// selectors
2020-07-01 17:06:59 +01:00
randSelector "github.com/micro/go-micro/v2/selector/random"
roundSelector "github.com/micro/go-micro/v2/selector/roundrobin"
2016-04-26 18:49:02 +01:00
// transports
2020-01-30 14:39:00 +03:00
thttp "github.com/micro/go-micro/v2/transport/http"
tmem "github.com/micro/go-micro/v2/transport/memory"
2019-11-02 13:25:10 +00:00
2020-01-06 17:44:32 +00:00
// stores
2020-01-30 14:39:00 +03:00
memStore "github.com/micro/go-micro/v2/store/memory"
svcStore "github.com/micro/go-micro/v2/store/service"
2020-01-29 15:45:11 +00:00
// tracers
2020-01-30 14:39:00 +03:00
// jTracer "github.com/micro/go-micro/v2/debug/trace/jaeger"
memTracer "github.com/micro/go-micro/v2/debug/trace/memory"
2020-02-03 08:16:02 +00:00
// auth
2020-04-29 09:21:17 +01:00
jwtAuth "github.com/micro/go-micro/v2/auth/jwt"
2020-03-23 16:19:30 +00:00
svcAuth "github.com/micro/go-micro/v2/auth/service"
2020-03-07 11:06:57 +00:00
// auth providers
"github.com/micro/go-micro/v2/auth/provider/basic"
"github.com/micro/go-micro/v2/auth/provider/oauth"
2015-02-14 23:33:21 +00:00
)
2016-01-01 01:16:21 +00:00
type Cmd interface {
// The cli app within this cmd
App ( ) * cli . App
// Adds options, parses flags and initialise
// exits on error
2016-01-02 19:12:17 +00:00
Init ( opts ... Option ) error
2016-01-01 01:16:21 +00:00
// Options set within this command
Options ( ) Options
}
type cmd struct {
opts Options
app * cli . App
}
type Option func ( o * Options )
2015-02-14 23:33:21 +00:00
var (
2016-01-01 01:16:21 +00:00
DefaultCmd = newCmd ( )
2015-12-23 22:45:40 +00:00
2016-01-01 01:16:21 +00:00
DefaultFlags = [ ] cli . Flag {
2020-07-08 08:50:08 +01:00
& cli . StringFlag {
Name : "certificate_authorities" ,
EnvVars : [ ] string { "MICRO_CERTIFICATE_AUTHORITIES" } ,
Usage : "Commar-seperated list of certificate authorities, e.g. '/certs/ca.crt'" ,
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "client" ,
EnvVars : [ ] string { "MICRO_CLIENT" } ,
Usage : "Client for go-micro; rpc" ,
2016-11-18 17:29:26 +00:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "client_request_timeout" ,
EnvVars : [ ] string { "MICRO_CLIENT_REQUEST_TIMEOUT" } ,
Usage : "Sets the client request timeout. e.g 500ms, 5s, 1m. Default: 5s" ,
2016-03-29 17:18:39 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . IntFlag {
Name : "client_retries" ,
EnvVars : [ ] string { "MICRO_CLIENT_RETRIES" } ,
Value : client . DefaultRetries ,
Usage : "Sets the client retries. Default: 1" ,
2016-03-29 17:18:39 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . IntFlag {
Name : "client_pool_size" ,
EnvVars : [ ] string { "MICRO_CLIENT_POOL_SIZE" } ,
Usage : "Sets the client connection pool size. Default: 1" ,
2016-06-07 00:46:14 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "client_pool_ttl" ,
EnvVars : [ ] string { "MICRO_CLIENT_POOL_TTL" } ,
Usage : "Sets the client connection pool ttl. e.g 500ms, 5s, 1m. Default: 1m" ,
2016-06-07 00:46:14 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . IntFlag {
Name : "register_ttl" ,
EnvVars : [ ] string { "MICRO_REGISTER_TTL" } ,
Value : 60 ,
Usage : "Register TTL in seconds" ,
2018-04-06 14:03:39 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . IntFlag {
Name : "register_interval" ,
EnvVars : [ ] string { "MICRO_REGISTER_INTERVAL" } ,
Value : 30 ,
Usage : "Register interval in seconds" ,
2018-04-06 14:03:39 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "server" ,
EnvVars : [ ] string { "MICRO_SERVER" } ,
Usage : "Server for go-micro; rpc" ,
2018-09-13 19:02:08 +03:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "server_name" ,
EnvVars : [ ] string { "MICRO_SERVER_NAME" } ,
Usage : "Name of the server. go.micro.srv.example" ,
2015-05-26 22:39:48 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "server_version" ,
EnvVars : [ ] string { "MICRO_SERVER_VERSION" } ,
Usage : "Version of the server. 1.1.0" ,
2015-11-08 01:48:48 +00:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "server_id" ,
EnvVars : [ ] string { "MICRO_SERVER_ID" } ,
Usage : "Id of the server. Auto-generated if not specified" ,
2015-05-26 22:39:48 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "server_address" ,
EnvVars : [ ] string { "MICRO_SERVER_ADDRESS" } ,
Usage : "Bind address for the server. 127.0.0.1:8080" ,
2015-05-16 00:34:02 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "server_advertise" ,
EnvVars : [ ] string { "MICRO_SERVER_ADVERTISE" } ,
Usage : "Used instead of the server_address when registering with discovery. 127.0.0.1:8080" ,
2015-11-11 18:22:04 +00:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringSliceFlag {
Name : "server_metadata" ,
EnvVars : [ ] string { "MICRO_SERVER_METADATA" } ,
Value : & cli . StringSlice { } ,
Usage : "A list of key-value pairs defining metadata. version=1.0.0" ,
2015-05-26 22:39:48 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "broker" ,
EnvVars : [ ] string { "MICRO_BROKER" } ,
Usage : "Broker for pub/sub. http, nats, rabbitmq" ,
2015-05-16 00:34:02 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "broker_address" ,
EnvVars : [ ] string { "MICRO_BROKER_ADDRESS" } ,
Usage : "Comma-separated list of broker addresses" ,
2015-05-16 00:34:02 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "profile" ,
Usage : "Debug profiler for cpu and memory stats" ,
EnvVars : [ ] string { "MICRO_DEBUG_PROFILE" } ,
2019-11-06 19:36:04 +00:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "registry" ,
EnvVars : [ ] string { "MICRO_REGISTRY" } ,
Usage : "Registry for discovery. etcd, mdns" ,
2015-05-16 00:34:02 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "registry_address" ,
EnvVars : [ ] string { "MICRO_REGISTRY_ADDRESS" } ,
Usage : "Comma-separated list of registry addresses" ,
2015-05-16 00:34:02 +01:00
} ,
2020-07-08 08:50:08 +01:00
& cli . BoolFlag {
Name : "registry_secure" ,
Usage : "Secure connection to registry" ,
EnvVars : [ ] string { "MICRO_REGISTRY_SECURE" } ,
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "runtime" ,
Usage : "Runtime for building and running services e.g local, kubernetes" ,
EnvVars : [ ] string { "MICRO_RUNTIME" } ,
Value : "local" ,
2019-11-06 19:36:04 +00:00
} ,
2020-02-05 13:59:35 +00:00
& cli . StringFlag {
Name : "runtime_source" ,
Usage : "Runtime source for building and running services e.g github.com/micro/service" ,
EnvVars : [ ] string { "MICRO_RUNTIME_SOURCE" } ,
Value : "github.com/micro/services" ,
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "selector" ,
EnvVars : [ ] string { "MICRO_SELECTOR" } ,
Usage : "Selector used to pick nodes for querying" ,
2015-12-09 19:32:10 +00:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "store" ,
EnvVars : [ ] string { "MICRO_STORE" } ,
Usage : "Store used for key-value storage" ,
2020-01-08 12:11:31 +00:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "store_address" ,
EnvVars : [ ] string { "MICRO_STORE_ADDRESS" } ,
Usage : "Comma-separated list of store addresses" ,
2020-01-08 12:11:31 +00:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
2020-04-06 16:45:55 +01:00
Name : "store_database" ,
EnvVars : [ ] string { "MICRO_STORE_DATABASE" } ,
Usage : "Database option for the underlying store" ,
} ,
& cli . StringFlag {
Name : "store_table" ,
2020-04-08 19:44:49 +01:00
EnvVars : [ ] string { "MICRO_STORE_TABLE" } ,
2020-04-06 16:45:55 +01:00
Usage : "Table option for the underlying store" ,
2020-01-08 12:11:31 +00:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "transport" ,
EnvVars : [ ] string { "MICRO_TRANSPORT" } ,
Usage : "Transport mechanism used; http" ,
2015-05-20 22:57:19 +01:00
} ,
2020-01-25 13:41:25 +03:00
& cli . StringFlag {
Name : "transport_address" ,
EnvVars : [ ] string { "MICRO_TRANSPORT_ADDRESS" } ,
Usage : "Comma-separated list of transport addresses" ,
2015-05-20 22:57:19 +01:00
} ,
2020-01-29 15:45:11 +00:00
& cli . StringFlag {
Name : "tracer" ,
EnvVars : [ ] string { "MICRO_TRACER" } ,
Usage : "Tracer for distributed tracing, e.g. memory, jaeger" ,
} ,
& cli . StringFlag {
Name : "tracer_address" ,
EnvVars : [ ] string { "MICRO_TRACER_ADDRESS" } ,
Usage : "Comma-separated list of tracer addresses" ,
} ,
2020-02-03 08:16:02 +00:00
& cli . StringFlag {
Name : "auth" ,
EnvVars : [ ] string { "MICRO_AUTH" } ,
Usage : "Auth for role based access control, e.g. service" ,
} ,
2020-06-24 13:47:43 +01:00
& cli . StringFlag {
Name : "auth_address" ,
EnvVars : [ ] string { "MICRO_AUTH_ADDRESS" } ,
Usage : "Comma-separated list of auth addresses" ,
} ,
2020-02-25 22:15:44 +00:00
& cli . StringFlag {
2020-03-31 12:44:34 +01:00
Name : "auth_id" ,
EnvVars : [ ] string { "MICRO_AUTH_ID" } ,
Usage : "Account ID used for client authentication" ,
} ,
& cli . StringFlag {
Name : "auth_secret" ,
EnvVars : [ ] string { "MICRO_AUTH_SECRET" } ,
Usage : "Account secret used for client authentication" ,
2020-02-25 22:15:44 +00:00
} ,
2020-05-12 16:41:29 +01:00
& cli . StringFlag {
2020-06-17 12:26:27 +01:00
Name : "service_namespace" ,
EnvVars : [ ] string { "MICRO_NAMESPACE" } ,
Usage : "Namespace the service is operating in" ,
2020-06-19 09:24:32 +01:00
Value : "micro" ,
2020-05-12 16:41:29 +01:00
} ,
2020-02-03 08:16:02 +00:00
& cli . StringFlag {
Name : "auth_public_key" ,
EnvVars : [ ] string { "MICRO_AUTH_PUBLIC_KEY" } ,
Usage : "Public key for JWT auth (base64 encoded PEM)" ,
} ,
& cli . StringFlag {
Name : "auth_private_key" ,
EnvVars : [ ] string { "MICRO_AUTH_PRIVATE_KEY" } ,
Usage : "Private key for JWT auth (base64 encoded PEM)" ,
} ,
2020-03-07 11:06:57 +00:00
& cli . StringFlag {
Name : "auth_provider" ,
EnvVars : [ ] string { "MICRO_AUTH_PROVIDER" } ,
Usage : "Auth provider used to login user" ,
} ,
& cli . StringFlag {
Name : "auth_provider_client_id" ,
EnvVars : [ ] string { "MICRO_AUTH_PROVIDER_CLIENT_ID" } ,
Usage : "The client id to be used for oauth" ,
} ,
& cli . StringFlag {
Name : "auth_provider_client_secret" ,
EnvVars : [ ] string { "MICRO_AUTH_PROVIDER_CLIENT_SECRET" } ,
Usage : "The client secret to be used for oauth" ,
} ,
& cli . StringFlag {
Name : "auth_provider_endpoint" ,
EnvVars : [ ] string { "MICRO_AUTH_PROVIDER_ENDPOINT" } ,
Usage : "The enpoint to be used for oauth" ,
} ,
& cli . StringFlag {
Name : "auth_provider_redirect" ,
EnvVars : [ ] string { "MICRO_AUTH_PROVIDER_REDIRECT" } ,
Usage : "The redirect to be used for oauth" ,
} ,
& cli . StringFlag {
Name : "auth_provider_scope" ,
EnvVars : [ ] string { "MICRO_AUTH_PROVIDER_SCOPE" } ,
Usage : "The scope to be used for oauth" ,
} ,
2020-03-12 18:13:03 +00:00
& cli . StringFlag {
Name : "config" ,
EnvVars : [ ] string { "MICRO_CONFIG" } ,
Usage : "The source of the config to be used to get configuration" ,
} ,
2020-06-24 11:46:51 +01:00
& cli . StringFlag {
Name : "router" ,
EnvVars : [ ] string { "MICRO_ROUTER" } ,
Usage : "Router used for client requests" ,
} ,
2020-06-26 10:38:11 +01:00
& cli . StringFlag {
Name : "router_address" ,
Usage : "Comma-separated list of router addresses" ,
EnvVars : [ ] string { "MICRO_ROUTER_ADDRESS" } ,
} ,
2015-04-27 22:21:56 +01:00
}
2015-02-14 23:33:21 +00:00
2016-03-15 22:12:28 +00:00
DefaultBrokers = map [ string ] func ( ... broker . Option ) broker . Broker {
2019-12-10 18:12:29 +00:00
"service" : brokerSrv . NewBroker ,
"memory" : memory . NewBroker ,
"nats" : nats . NewBroker ,
2020-04-11 03:46:54 +03:00
"http" : brokerHttp . NewBroker ,
2015-06-01 18:55:27 +01:00
}
2015-05-16 00:34:02 +01:00
2016-11-18 17:29:26 +00:00
DefaultClients = map [ string ] func ( ... client . Option ) client . Client {
2019-06-08 19:40:44 +01:00
"mucp" : cmucp . NewClient ,
"grpc" : cgrpc . NewClient ,
2016-11-18 17:29:26 +00:00
}
2016-03-15 22:20:21 +00:00
DefaultRegistries = map [ string ] func ( ... registry . Option ) registry . Registry {
2020-04-10 17:15:20 +01:00
"service" : regSrv . NewRegistry ,
"etcd" : etcd . NewRegistry ,
"mdns" : mdns . NewRegistry ,
"memory" : rmem . NewRegistry ,
2015-05-16 00:34:02 +01:00
}
2020-06-24 11:46:51 +01:00
DefaultRouters = map [ string ] func ( ... router . Option ) router . Router {
"dns" : dnsRouter . NewRouter ,
"registry" : regRouter . NewRouter ,
"static" : staticRouter . NewRouter ,
"service" : srvRouter . NewRouter ,
}
2016-01-01 01:16:21 +00:00
DefaultSelectors = map [ string ] func ( ... selector . Option ) selector . Selector {
2020-07-01 17:06:59 +01:00
"random" : randSelector . NewSelector ,
"roundrobin" : roundSelector . NewSelector ,
2015-12-09 19:32:10 +00:00
}
2016-11-18 17:29:26 +00:00
DefaultServers = map [ string ] func ( ... server . Option ) server . Server {
2019-06-08 19:40:44 +01:00
"mucp" : smucp . NewServer ,
"grpc" : sgrpc . NewServer ,
2016-11-18 17:29:26 +00:00
}
2016-03-15 22:25:32 +00:00
DefaultTransports = map [ string ] func ( ... transport . Option ) transport . Transport {
2019-01-14 15:27:25 +00:00
"memory" : tmem . NewTransport ,
"http" : thttp . NewTransport ,
2015-06-01 18:55:27 +01:00
}
2016-01-27 01:13:31 +00:00
2019-11-02 13:25:10 +00:00
DefaultRuntimes = map [ string ] func ( ... runtime . Option ) runtime . Runtime {
2020-02-05 13:59:35 +00:00
"local" : lRuntime . NewRuntime ,
"service" : srvRuntime . NewRuntime ,
"kubernetes" : kRuntime . NewRuntime ,
2019-11-02 13:25:10 +00:00
}
2020-01-06 17:44:32 +00:00
DefaultStores = map [ string ] func ( ... store . Option ) store . Store {
2020-01-24 21:31:57 +00:00
"memory" : memStore . NewStore ,
"service" : svcStore . NewStore ,
2020-01-06 17:44:32 +00:00
}
2020-01-29 15:45:11 +00:00
DefaultTracers = map [ string ] func ( ... trace . Option ) trace . Tracer {
"memory" : memTracer . NewTracer ,
// "jaeger": jTracer.NewTracer,
}
2020-02-03 08:16:02 +00:00
DefaultAuths = map [ string ] func ( ... auth . Option ) auth . Auth {
2020-03-23 16:19:30 +00:00
"service" : svcAuth . NewAuth ,
2020-04-29 09:21:17 +01:00
"jwt" : jwtAuth . NewAuth ,
2020-02-03 08:16:02 +00:00
}
2020-02-26 00:42:43 +08:00
2020-03-07 11:06:57 +00:00
DefaultAuthProviders = map [ string ] func ( ... provider . Option ) provider . Provider {
"oauth" : oauth . NewProvider ,
"basic" : basic . NewProvider ,
}
2020-02-26 00:42:43 +08:00
DefaultProfiles = map [ string ] func ( ... profile . Option ) profile . Profile {
"http" : http . NewProfile ,
"pprof" : pprof . NewProfile ,
}
2020-03-12 18:13:03 +00:00
DefaultConfigs = map [ string ] func ( ... config . Option ) ( config . Config , error ) {
"service" : config . NewConfig ,
}
2015-06-01 18:55:27 +01:00
)
2015-02-14 23:33:21 +00:00
2015-12-05 19:25:36 +00:00
func init ( ) {
rand . Seed ( time . Now ( ) . Unix ( ) )
}
2016-01-01 01:16:21 +00:00
func newCmd ( opts ... Option ) Cmd {
options := Options {
2020-02-10 08:26:28 +00:00
Auth : & auth . DefaultAuth ,
2016-01-02 00:38:57 +00:00
Broker : & broker . DefaultBroker ,
Client : & client . DefaultClient ,
Registry : & registry . DefaultRegistry ,
Server : & server . DefaultServer ,
Selector : & selector . DefaultSelector ,
Transport : & transport . DefaultTransport ,
2020-06-24 11:46:51 +01:00
Router : & router . DefaultRouter ,
2019-11-02 13:25:10 +00:00
Runtime : & runtime . DefaultRuntime ,
2020-01-06 17:44:32 +00:00
Store : & store . DefaultStore ,
2020-01-29 15:45:11 +00:00
Tracer : & trace . DefaultTracer ,
2020-02-26 00:42:43 +08:00
Profile : & profile . DefaultProfile ,
2020-03-12 18:13:03 +00:00
Config : & config . DefaultConfig ,
2016-01-02 00:38:57 +00:00
2016-01-01 01:16:21 +00:00
Brokers : DefaultBrokers ,
2016-11-18 17:29:26 +00:00
Clients : DefaultClients ,
2016-01-01 01:16:21 +00:00
Registries : DefaultRegistries ,
Selectors : DefaultSelectors ,
2016-11-18 17:29:26 +00:00
Servers : DefaultServers ,
2016-01-01 01:16:21 +00:00
Transports : DefaultTransports ,
2020-06-24 11:46:51 +01:00
Routers : DefaultRouters ,
2019-11-02 13:25:10 +00:00
Runtimes : DefaultRuntimes ,
2020-01-06 17:44:32 +00:00
Stores : DefaultStores ,
2020-01-29 15:45:11 +00:00
Tracers : DefaultTracers ,
2020-02-03 08:16:02 +00:00
Auths : DefaultAuths ,
2020-02-26 00:42:43 +08:00
Profiles : DefaultProfiles ,
2020-03-12 18:13:03 +00:00
Configs : DefaultConfigs ,
2016-01-01 01:16:21 +00:00
}
2015-10-18 00:01:43 +01:00
2016-01-01 01:16:21 +00:00
for _ , o := range opts {
o ( & options )
}
2015-10-18 00:01:43 +01:00
2016-01-01 02:45:15 +00:00
if len ( options . Description ) == 0 {
options . Description = "a go-micro service"
}
2016-01-01 01:16:21 +00:00
cmd := new ( cmd )
cmd . opts = options
cmd . app = cli . NewApp ( )
cmd . app . Name = cmd . opts . Name
cmd . app . Version = cmd . opts . Version
cmd . app . Usage = cmd . opts . Description
cmd . app . Before = cmd . Before
cmd . app . Flags = DefaultFlags
2020-01-25 13:41:25 +03:00
cmd . app . Action = func ( c * cli . Context ) error {
return nil
}
2016-01-01 02:45:15 +00:00
if len ( options . Version ) == 0 {
cmd . app . HideVersion = true
}
2016-01-01 01:16:21 +00:00
return cmd
}
func ( c * cmd ) App ( ) * cli . App {
return c . app
}
func ( c * cmd ) Options ( ) Options {
return c . opts
}
func ( c * cmd ) Before ( ctx * cli . Context ) error {
2020-07-08 08:50:08 +01:00
// Setup custom certificate authorities
caCertPool := x509 . NewCertPool ( )
if len ( ctx . String ( "certificate_authorities" ) ) > 0 {
for _ , ca := range strings . Split ( ctx . String ( "certificate_authorities" ) , "," ) {
crt , err := ioutil . ReadFile ( ca )
if err != nil {
logger . Fatalf ( "Error loading registry certificate authority: %v" , err )
}
caCertPool . AppendCertsFromPEM ( crt )
}
}
2020-06-18 10:14:04 +01:00
// Setup client options
2016-01-02 00:38:57 +00:00
var clientOpts [ ] client . Option
2020-06-18 10:14:04 +01:00
if r := ctx . Int ( "client_retries" ) ; r >= 0 {
clientOpts = append ( clientOpts , client . Retries ( r ) )
}
if t := ctx . String ( "client_request_timeout" ) ; len ( t ) > 0 {
d , err := time . ParseDuration ( t )
if err != nil {
logger . Fatalf ( "failed to parse client_request_timeout: %v" , t )
}
clientOpts = append ( clientOpts , client . RequestTimeout ( d ) )
}
if r := ctx . Int ( "client_pool_size" ) ; r > 0 {
clientOpts = append ( clientOpts , client . PoolSize ( r ) )
}
if t := ctx . String ( "client_pool_ttl" ) ; len ( t ) > 0 {
d , err := time . ParseDuration ( t )
if err != nil {
logger . Fatalf ( "failed to parse client_pool_ttl: %v" , t )
}
clientOpts = append ( clientOpts , client . PoolTTL ( d ) )
}
// Setup server options
var serverOpts [ ] server . Option
metadata := make ( map [ string ] string )
for _ , d := range ctx . StringSlice ( "server_metadata" ) {
var key , val string
parts := strings . Split ( d , "=" )
key = parts [ 0 ]
if len ( parts ) > 1 {
val = strings . Join ( parts [ 1 : ] , "=" )
}
metadata [ key ] = val
}
if len ( metadata ) > 0 {
serverOpts = append ( serverOpts , server . Metadata ( metadata ) )
}
if len ( ctx . String ( "server_name" ) ) > 0 {
serverOpts = append ( serverOpts , server . Name ( ctx . String ( "server_name" ) ) )
}
if len ( ctx . String ( "server_version" ) ) > 0 {
serverOpts = append ( serverOpts , server . Version ( ctx . String ( "server_version" ) ) )
}
if len ( ctx . String ( "server_id" ) ) > 0 {
serverOpts = append ( serverOpts , server . Id ( ctx . String ( "server_id" ) ) )
}
if len ( ctx . String ( "server_address" ) ) > 0 {
serverOpts = append ( serverOpts , server . Address ( ctx . String ( "server_address" ) ) )
}
if len ( ctx . String ( "server_advertise" ) ) > 0 {
serverOpts = append ( serverOpts , server . Advertise ( ctx . String ( "server_advertise" ) ) )
}
if ttl := time . Duration ( ctx . Int ( "register_ttl" ) ) ; ttl >= 0 {
serverOpts = append ( serverOpts , server . RegisterTTL ( ttl * time . Second ) )
}
if val := time . Duration ( ctx . Int ( "register_interval" ) ) ; val >= 0 {
serverOpts = append ( serverOpts , server . RegisterInterval ( val * time . Second ) )
}
2020-05-22 16:52:24 +01:00
// setup a client to use when calling the runtime. It is important the auth client is wrapped
// after the cache client since the wrappers are applied in reverse order and the cache will use
// some of the headers set by the auth client.
2020-05-14 11:25:19 +01:00
authFn := func ( ) auth . Auth { return * c . opts . Auth }
2020-05-24 18:45:57 +01:00
cacheFn := func ( ) * client . Cache { return ( * c . opts . Client ) . Options ( ) . Cache }
microClient := wrapper . CacheClient ( cacheFn , grpc . NewClient ( ) )
2020-05-22 16:52:24 +01:00
microClient = wrapper . AuthClient ( authFn , microClient )
2020-05-14 11:06:22 +01:00
2020-06-24 13:47:43 +01:00
// Setup auth options
authOpts := [ ] auth . Option { auth . WithClient ( microClient ) }
if len ( ctx . String ( "auth_address" ) ) > 0 {
authOpts = append ( authOpts , auth . Addrs ( ctx . String ( "auth_address" ) ) )
}
if len ( ctx . String ( "auth_id" ) ) > 0 || len ( ctx . String ( "auth_secret" ) ) > 0 {
authOpts = append ( authOpts , auth . Credentials (
ctx . String ( "auth_id" ) , ctx . String ( "auth_secret" ) ,
) )
}
if len ( ctx . String ( "auth_public_key" ) ) > 0 {
authOpts = append ( authOpts , auth . PublicKey ( ctx . String ( "auth_public_key" ) ) )
}
if len ( ctx . String ( "auth_private_key" ) ) > 0 {
authOpts = append ( authOpts , auth . PrivateKey ( ctx . String ( "auth_private_key" ) ) )
}
if ns := ctx . String ( "service_namespace" ) ; len ( ns ) > 0 {
serverOpts = append ( serverOpts , server . Namespace ( ns ) )
authOpts = append ( authOpts , auth . Issuer ( ns ) )
}
if name := ctx . String ( "auth_provider" ) ; len ( name ) > 0 {
p , ok := DefaultAuthProviders [ name ]
if ! ok {
logger . Fatalf ( "AuthProvider %s not found" , name )
}
var provOpts [ ] provider . Option
clientID := ctx . String ( "auth_provider_client_id" )
clientSecret := ctx . String ( "auth_provider_client_secret" )
if len ( clientID ) > 0 || len ( clientSecret ) > 0 {
provOpts = append ( provOpts , provider . Credentials ( clientID , clientSecret ) )
}
if e := ctx . String ( "auth_provider_endpoint" ) ; len ( e ) > 0 {
provOpts = append ( provOpts , provider . Endpoint ( e ) )
}
if r := ctx . String ( "auth_provider_redirect" ) ; len ( r ) > 0 {
provOpts = append ( provOpts , provider . Redirect ( r ) )
}
if s := ctx . String ( "auth_provider_scope" ) ; len ( s ) > 0 {
provOpts = append ( provOpts , provider . Scope ( s ) )
}
authOpts = append ( authOpts , auth . Provider ( p ( provOpts ... ) ) )
}
// Set the auth
if name := ctx . String ( "auth" ) ; len ( name ) > 0 {
a , ok := c . opts . Auths [ name ]
if ! ok {
logger . Fatalf ( "Unsupported auth: %s" , name )
}
* c . opts . Auth = a ( authOpts ... )
serverOpts = append ( serverOpts , server . Auth ( * c . opts . Auth ) )
} else if len ( authOpts ) > 0 {
( * c . opts . Auth ) . Init ( authOpts ... )
}
2020-06-25 15:24:31 +01:00
// generate the services auth account.
// todo: move this so it only runs for new services
serverID := ( * c . opts . Server ) . Options ( ) . Id
if err := authutil . Generate ( serverID , c . App ( ) . Name , ( * c . opts . Auth ) ) ; err != nil {
return err
}
// Setup broker options.
2020-07-02 17:54:53 +01:00
brokerOpts := [ ] broker . Option { brokerSrv . Client ( microClient ) }
2020-06-25 15:24:31 +01:00
if len ( ctx . String ( "broker_address" ) ) > 0 {
brokerOpts = append ( brokerOpts , broker . Addrs ( ctx . String ( "broker_address" ) ) )
}
// Setup registry options
registryOpts := [ ] registry . Option { registrySrv . WithClient ( microClient ) }
2020-07-08 08:50:08 +01:00
// Parse registry TLS certs
if ctx . Bool ( "registry_secure" ) {
cert , err := tls . LoadX509KeyPair ( "/certs/registry/cert.pem" , "/certs/registry/key.pem" )
if err != nil {
logger . Fatalf ( "Error loading x509 key pair: %v" , err )
}
cfg := & tls . Config { Certificates : [ ] tls . Certificate { cert } , RootCAs : caCertPool }
registryOpts = append ( registryOpts , registry . TLSConfig ( cfg ) )
}
2020-06-25 15:24:31 +01:00
if len ( ctx . String ( "registry_address" ) ) > 0 {
addresses := strings . Split ( ctx . String ( "registry_address" ) , "," )
registryOpts = append ( registryOpts , registry . Addrs ( addresses ... ) )
}
// Set the registry
if name := ctx . String ( "registry" ) ; len ( name ) > 0 && ( * c . opts . Registry ) . String ( ) != name {
r , ok := c . opts . Registries [ name ]
if ! ok {
logger . Fatalf ( "Registry %s not found" , name )
}
* c . opts . Registry = r ( registryOpts ... )
serverOpts = append ( serverOpts , server . Registry ( * c . opts . Registry ) )
brokerOpts = append ( brokerOpts , broker . Registry ( * c . opts . Registry ) )
} else if len ( registryOpts ) > 0 {
if err := ( * c . opts . Registry ) . Init ( registryOpts ... ) ; err != nil {
logger . Fatalf ( "Error configuring registry: %v" , err )
}
}
2020-07-01 17:06:59 +01:00
// Add support for legacy selectors until v3.
if ctx . String ( "selector" ) == "static" {
ctx . Set ( "router" , "static" )
ctx . Set ( "selector" , "" )
logger . Warnf ( "DEPRECATION WARNING: router/static now provides static routing, use '--router=static'. Support for the static selector flag will be removed in v3." )
}
if ctx . String ( "selector" ) == "dns" {
ctx . Set ( "router" , "dns" )
ctx . Set ( "selector" , "" )
logger . Warnf ( "DEPRECATION WARNING: router/dns now provides dns routing, use '--router=dns'. Support for the dns selector flag will be removed in v3." )
}
2020-06-25 15:24:31 +01:00
// Set the selector
if name := ctx . String ( "selector" ) ; len ( name ) > 0 && ( * c . opts . Selector ) . String ( ) != name {
s , ok := c . opts . Selectors [ name ]
if ! ok {
logger . Fatalf ( "Selector %s not found" , name )
}
2020-07-01 17:06:59 +01:00
* c . opts . Selector = s ( )
2020-06-25 15:24:31 +01:00
clientOpts = append ( clientOpts , client . Selector ( * c . opts . Selector ) )
}
2020-06-24 11:46:51 +01:00
// Set the router, this must happen before the rest of the server as it'll route server requests
// such as go.micro.config if no address is specified
routerOpts := [ ] router . Option {
2020-06-26 10:38:11 +01:00
srvRouter . Client ( microClient ) ,
2020-06-24 11:46:51 +01:00
router . Network ( ctx . String ( "service_namespace" ) ) ,
router . Registry ( * c . opts . Registry ) ,
2020-06-26 10:38:11 +01:00
router . Id ( ( * c . opts . Server ) . Options ( ) . Id ) ,
}
if len ( ctx . String ( "router_address" ) ) > 0 {
routerOpts = append ( routerOpts , router . Address ( ctx . String ( "router_address" ) ) )
2020-06-24 11:46:51 +01:00
}
if name := ctx . String ( "router" ) ; len ( name ) > 0 && ( * c . opts . Router ) . String ( ) != name {
r , ok := c . opts . Routers [ name ]
if ! ok {
return fmt . Errorf ( "Router %s not found" , name )
2020-06-26 10:38:11 +01:00
}
// close the default router before replacing it
if err := ( * c . opts . Router ) . Close ( ) ; err != nil {
logger . Fatalf ( "Error closing default router: %s" , name )
2020-06-24 11:46:51 +01:00
}
* c . opts . Router = r ( routerOpts ... )
2020-07-01 17:06:59 +01:00
clientOpts = append ( clientOpts , client . Router ( * c . opts . Router ) )
2020-06-24 11:46:51 +01:00
} else if len ( routerOpts ) > 0 {
if err := ( * c . opts . Router ) . Init ( routerOpts ... ) ; err != nil {
logger . Fatalf ( "Error configuring router: %v" , err )
}
}
2020-06-18 10:14:04 +01:00
// Setup store options
storeOpts := [ ] store . Option { store . WithClient ( microClient ) }
if len ( ctx . String ( "store_address" ) ) > 0 {
storeOpts = append ( storeOpts , store . Nodes ( strings . Split ( ctx . String ( "store_address" ) , "," ) ... ) )
}
if len ( ctx . String ( "store_database" ) ) > 0 {
storeOpts = append ( storeOpts , store . Database ( ctx . String ( "store_database" ) ) )
}
if len ( ctx . String ( "store_table" ) ) > 0 {
storeOpts = append ( storeOpts , store . Table ( ctx . String ( "store_table" ) ) )
}
2020-01-29 15:45:11 +00:00
// Set the store
2020-01-06 17:44:32 +00:00
if name := ctx . String ( "store" ) ; len ( name ) > 0 {
s , ok := c . opts . Stores [ name ]
if ! ok {
2020-06-18 10:14:04 +01:00
logger . Fatalf ( "Unsupported store: %s" , name )
2020-01-06 17:44:32 +00:00
}
2020-06-18 10:14:04 +01:00
* c . opts . Store = s ( storeOpts ... )
} else if len ( storeOpts ) > 0 {
if err := ( * c . opts . Store ) . Init ( storeOpts ... ) ; err != nil {
logger . Fatalf ( "Error configuring store: %v" , err )
}
}
// Setup the runtime options
runtimeOpts := [ ] runtime . Option { runtime . WithClient ( microClient ) }
if len ( ctx . String ( "runtime_source" ) ) > 0 {
runtimeOpts = append ( runtimeOpts , runtime . WithSource ( ctx . String ( "runtime_source" ) ) )
2020-01-06 17:44:32 +00:00
}
2019-11-02 13:25:10 +00:00
// Set the runtime
if name := ctx . String ( "runtime" ) ; len ( name ) > 0 {
r , ok := c . opts . Runtimes [ name ]
if ! ok {
2020-06-18 10:14:04 +01:00
logger . Fatalf ( "Unsupported runtime: %s" , name )
2019-11-02 13:25:10 +00:00
}
2020-06-18 10:14:04 +01:00
* c . opts . Runtime = r ( runtimeOpts ... )
} else if len ( runtimeOpts ) > 0 {
if err := ( * c . opts . Runtime ) . Init ( runtimeOpts ... ) ; err != nil {
logger . Fatalf ( "Error configuring runtime: %v" , err )
}
2019-11-02 13:25:10 +00:00
}
2020-01-29 15:45:11 +00:00
// Set the tracer
if name := ctx . String ( "tracer" ) ; len ( name ) > 0 {
r , ok := c . opts . Tracers [ name ]
if ! ok {
2020-06-18 10:14:04 +01:00
logger . Fatalf ( "Unsupported tracer: %s" , name )
2020-01-29 15:45:11 +00:00
}
* c . opts . Tracer = r ( )
}
2020-02-26 00:42:43 +08:00
// Set the profile
if name := ctx . String ( "profile" ) ; len ( name ) > 0 {
p , ok := c . opts . Profiles [ name ]
if ! ok {
2020-06-18 10:14:04 +01:00
logger . Fatalf ( "Unsupported profile: %s" , name )
2020-02-26 00:42:43 +08:00
}
* c . opts . Profile = p ( )
}
2016-01-02 00:38:57 +00:00
// Set the broker
2018-08-08 18:57:29 +01:00
if name := ctx . String ( "broker" ) ; len ( name ) > 0 && ( * c . opts . Broker ) . String ( ) != name {
b , ok := c . opts . Brokers [ name ]
if ! ok {
2020-06-18 10:14:04 +01:00
logger . Fatalf ( "Broker %s not found" , name )
2016-01-02 00:38:57 +00:00
}
2020-06-18 10:14:04 +01:00
* c . opts . Broker = b ( brokerOpts ... )
2016-01-02 00:38:57 +00:00
serverOpts = append ( serverOpts , server . Broker ( * c . opts . Broker ) )
clientOpts = append ( clientOpts , client . Broker ( * c . opts . Broker ) )
2020-06-18 10:14:04 +01:00
} else if len ( brokerOpts ) > 0 {
if err := ( * c . opts . Broker ) . Init ( brokerOpts ... ) ; err != nil {
logger . Fatalf ( "Error configuring broker: %v" , err )
}
2015-02-14 23:33:21 +00:00
}
2020-06-18 10:14:04 +01:00
// Setup the transport options
var transportOpts [ ] transport . Option
if len ( ctx . String ( "transport_address" ) ) > 0 {
addresses := strings . Split ( ctx . String ( "transport_address" ) , "," )
transportOpts = append ( transportOpts , transport . Addrs ( addresses ... ) )
2015-12-09 19:32:10 +00:00
}
2016-01-02 00:38:57 +00:00
// Set the transport
2018-08-08 18:57:29 +01:00
if name := ctx . String ( "transport" ) ; len ( name ) > 0 && ( * c . opts . Transport ) . String ( ) != name {
t , ok := c . opts . Transports [ name ]
if ! ok {
2020-06-18 10:14:04 +01:00
logger . Fatalf ( "Transport %s not found" , name )
2016-01-02 00:38:57 +00:00
}
2020-06-18 10:14:04 +01:00
* c . opts . Transport = t ( transportOpts ... )
2016-01-02 00:38:57 +00:00
serverOpts = append ( serverOpts , server . Transport ( * c . opts . Transport ) )
clientOpts = append ( clientOpts , client . Transport ( * c . opts . Transport ) )
2020-06-18 10:14:04 +01:00
} else if len ( transportOpts ) > 0 {
if err := ( * c . opts . Transport ) . Init ( transportOpts ... ) ; err != nil {
2020-03-11 20:55:39 +03:00
logger . Fatalf ( "Error configuring transport: %v" , err )
2018-12-06 18:19:05 +00:00
}
2018-08-08 18:57:29 +01:00
}
2020-06-18 10:14:04 +01:00
// Setup config sources
2020-03-12 18:13:03 +00:00
if ctx . String ( "config" ) == "service" {
2020-07-02 14:07:58 +01:00
opt := config . WithSource ( configSrv . NewSource (
configSrc . WithClient ( microClient ) ,
configSrv . Namespace ( ctx . String ( "service_namespace" ) ) ,
) )
2020-03-12 18:13:03 +00:00
if err := ( * c . opts . Config ) . Init ( opt ) ; err != nil {
logger . Fatalf ( "Error configuring config: %v" , err )
}
}
2020-06-18 10:14:04 +01:00
// Set the client
if name := ctx . String ( "client" ) ; len ( name ) > 0 && ( * c . opts . Client ) . String ( ) != name {
cl , ok := c . opts . Clients [ name ]
if ! ok {
logger . Fatalf ( "Client %s not found" , name )
2016-03-29 17:18:39 +01:00
}
2020-06-18 10:14:04 +01:00
* c . opts . Client = cl ( clientOpts ... )
} else if len ( clientOpts ) > 0 {
if err := ( * c . opts . Client ) . Init ( clientOpts ... ) ; err != nil {
logger . Fatalf ( "Error configuring client: %v" , err )
}
2016-06-07 00:46:14 +01:00
}
2020-06-18 10:14:04 +01:00
// Set the server
if name := ctx . String ( "server" ) ; len ( name ) > 0 && ( * c . opts . Server ) . String ( ) != name {
s , ok := c . opts . Servers [ name ]
if ! ok {
logger . Fatalf ( "Server %s not found" , name )
2016-06-07 00:46:14 +01:00
}
2020-06-18 10:14:04 +01:00
* c . opts . Server = s ( serverOpts ... )
} else if len ( serverOpts ) > 0 {
2018-12-06 18:19:05 +00:00
if err := ( * c . opts . Server ) . Init ( serverOpts ... ) ; err != nil {
2020-03-11 20:55:39 +03:00
logger . Fatalf ( "Error configuring server: %v" , err )
2018-12-06 18:19:05 +00:00
}
2016-01-02 00:38:57 +00:00
}
2015-04-27 22:21:56 +01:00
return nil
}
2016-01-02 19:12:17 +00:00
func ( c * cmd ) Init ( opts ... Option ) error {
2016-01-01 01:16:21 +00:00
for _ , o := range opts {
o ( & c . opts )
2015-04-27 22:21:56 +01:00
}
2020-01-19 00:55:01 +00:00
if len ( c . opts . Name ) > 0 {
c . app . Name = c . opts . Name
}
if len ( c . opts . Version ) > 0 {
c . app . Version = c . opts . Version
}
2017-05-09 15:49:59 +08:00
c . app . HideVersion = len ( c . opts . Version ) == 0
2016-01-01 01:16:21 +00:00
c . app . Usage = c . opts . Description
c . app . RunAndExitOnError ( )
2016-01-02 19:12:17 +00:00
return nil
2016-01-01 01:16:21 +00:00
}
2015-04-27 22:21:56 +01:00
2016-01-04 11:25:58 +00:00
func DefaultOptions ( ) Options {
return DefaultCmd . Options ( )
}
func App ( ) * cli . App {
return DefaultCmd . App ( )
}
2016-01-02 19:12:17 +00:00
func Init ( opts ... Option ) error {
return DefaultCmd . Init ( opts ... )
2016-01-01 01:16:21 +00:00
}
func NewCmd ( opts ... Option ) Cmd {
return newCmd ( opts ... )
2015-02-14 23:33:21 +00:00
}