|
@@ -0,0 +1,127 @@
|
|
|
|
+package options
|
|
|
|
+
|
|
|
|
+import (
|
|
|
|
+ "fmt"
|
|
|
|
+ "path"
|
|
|
|
+
|
|
|
|
+ "github.com/spf13/pflag"
|
|
|
|
+)
|
|
|
|
+
|
|
|
|
+// SecureServingOptions 安全的服务配置
|
|
|
|
+type SecureServingOptions struct {
|
|
|
|
+ BindAddress string `json:"bind-address" mapstructure:"bind-address"`
|
|
|
|
+ BindPort int `json:"bind-port" mapstructure:"bind-port"`
|
|
|
|
+ // Required set to true means that BindPort cannot be zero.
|
|
|
|
+ Required bool
|
|
|
|
+ ServerCert GeneratableKeyCert `json:"tls" mapstructure:"tls"`
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// CertKey 证书文件结构
|
|
|
|
+type CertKey struct {
|
|
|
|
+ // CertFile is a file containing a PEM-encoded certificate, and possibly the complete certificate chain
|
|
|
|
+ CertFile string `json:"cert-file" mapstructure:"cert-file"`
|
|
|
|
+ // KeyFile is a file containing a PEM-encoded private key for the certificate specified by CertFile
|
|
|
|
+ KeyFile string `json:"private-key-file" mapstructure:"private-key-file"`
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// GeneratableKeyCert 证书相关配置项
|
|
|
|
+type GeneratableKeyCert struct {
|
|
|
|
+ // CertKey allows setting an explicit cert/key file to use.
|
|
|
|
+ CertKey CertKey `json:"cert-key" mapstructure:"cert-key"`
|
|
|
|
+
|
|
|
|
+ // CertDirectory specifies a directory to write generated certificates to if CertFile/KeyFile aren't explicitly set.
|
|
|
|
+ // PairName is used to determine the filenames within CertDirectory.
|
|
|
|
+ // If CertDirectory and PairName are not set, an in-memory certificate will be generated.
|
|
|
|
+ CertDirectory string `json:"cert-dir" mapstructure:"cert-dir"`
|
|
|
|
+ // PairName is the name which will be used with CertDirectory to make a cert and key filenames.
|
|
|
|
+ // It becomes CertDirectory/PairName.crt and CertDirectory/PairName.key
|
|
|
|
+ PairName string `json:"pair-name" mapstructure:"pair-name"`
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// NewSecureServingOptions creates a SecureServingOptions object with default parameters.
|
|
|
|
+func NewSecureServingOptions() *SecureServingOptions {
|
|
|
|
+ return &SecureServingOptions{
|
|
|
|
+ BindAddress: "0.0.0.0",
|
|
|
|
+ BindPort: 8443,
|
|
|
|
+ Required: true,
|
|
|
|
+ ServerCert: GeneratableKeyCert{
|
|
|
|
+ PairName: "dy-admin",
|
|
|
|
+ CertDirectory: "/var/run/dy-admin",
|
|
|
|
+ },
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *SecureServingOptions) Validate() []error {
|
|
|
|
+ if s == nil {
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ var errors []error
|
|
|
|
+
|
|
|
|
+ if s.Required && s.BindPort < 1 || s.BindPort > 65535 {
|
|
|
|
+ errors = append(
|
|
|
|
+ errors,
|
|
|
|
+ fmt.Errorf(
|
|
|
|
+ "--secure.bind-port %v must be between 1 and 65535, inclusive. It cannot be turned off with 0",
|
|
|
|
+ s.BindPort,
|
|
|
|
+ ),
|
|
|
|
+ )
|
|
|
|
+ } else if s.BindPort < 0 || s.BindPort > 65535 {
|
|
|
|
+ errors = append(errors, fmt.Errorf("--secure.bind-port %v must be between 0 and 65535, inclusive. 0 for turning off secure port", s.BindPort))
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return errors
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+func (s *SecureServingOptions) AddFlags(fs *pflag.FlagSet) {
|
|
|
|
+ fs.StringVar(&s.BindAddress, "secure.bind-address", s.BindAddress, ""+
|
|
|
|
+ "The IP address on which to listen for the --secure.bind-port port. The "+
|
|
|
|
+ "associated interface(s) must be reachable by the rest of the engine, and by CLI/web "+
|
|
|
|
+ "clients. If blank, all interfaces will be used (0.0.0.0 for all IPv4 interfaces and :: for all IPv6 interfaces).")
|
|
|
|
+ desc := "The port on which to serve HTTPS with authentication and authorization."
|
|
|
|
+ if s.Required {
|
|
|
|
+ desc += " It cannot be switched off with 0."
|
|
|
|
+ } else {
|
|
|
|
+ desc += " If 0, don't serve HTTPS at all."
|
|
|
|
+ }
|
|
|
|
+ fs.IntVar(&s.BindPort, "secure.bind-port", s.BindPort, desc)
|
|
|
|
+
|
|
|
|
+ fs.StringVar(&s.ServerCert.CertDirectory, "secure.tls.cert-dir", s.ServerCert.CertDirectory, ""+
|
|
|
|
+ "The directory where the TLS certs are located. "+
|
|
|
|
+ "If --secure.tls.cert-key.cert-file and --secure.tls.cert-key.private-key-file are provided, "+
|
|
|
|
+ "this flag will be ignored.")
|
|
|
|
+
|
|
|
|
+ fs.StringVar(&s.ServerCert.PairName, "secure.tls.pair-name", s.ServerCert.PairName, ""+
|
|
|
|
+ "The name which will be used with --secure.tls.cert-dir to make a cert and key filenames. "+
|
|
|
|
+ "It becomes <cert-dir>/<pair-name>.crt and <cert-dir>/<pair-name>.key")
|
|
|
|
+
|
|
|
|
+ fs.StringVar(&s.ServerCert.CertKey.CertFile, "secure.tls.cert-key.cert-file", s.ServerCert.CertKey.CertFile, ""+
|
|
|
|
+ "File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated "+
|
|
|
|
+ "after server cert).")
|
|
|
|
+
|
|
|
|
+ fs.StringVar(&s.ServerCert.CertKey.KeyFile, "secure.tls.cert-key.private-key-file",
|
|
|
|
+ s.ServerCert.CertKey.KeyFile, ""+
|
|
|
|
+ "File containing the default x509 private key matching --secure.tls.cert-key.cert-file.")
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Complete fills in any fields not set that are required to have valid data.
|
|
|
|
+func (s *SecureServingOptions) Complete() error {
|
|
|
|
+ if s == nil || s.BindPort == 0 {
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ keyCert := &s.ServerCert.CertKey
|
|
|
|
+ if len(keyCert.CertFile) != 0 || len(keyCert.KeyFile) != 0 {
|
|
|
|
+ return nil
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if len(s.ServerCert.CertDirectory) > 0 {
|
|
|
|
+ if len(s.ServerCert.PairName) == 0 {
|
|
|
|
+ return fmt.Errorf("--secure.tls.pair-name is required if --secure.tls.cert-dir is set")
|
|
|
|
+ }
|
|
|
|
+ keyCert.CertFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".crt")
|
|
|
|
+ keyCert.KeyFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".key")
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return nil
|
|
|
|
+}
|