secure_serving.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. package options
  2. import (
  3. "fmt"
  4. "path"
  5. "github.com/spf13/pflag"
  6. )
  7. // SecureServingOptions 安全的服务配置
  8. type SecureServingOptions struct {
  9. BindAddress string `json:"bind-address" mapstructure:"bind-address"`
  10. BindPort int `json:"bind-port" mapstructure:"bind-port"`
  11. // Required set to true means that BindPort cannot be zero.
  12. Required bool
  13. ServerCert GeneratableKeyCert `json:"tls" mapstructure:"tls"`
  14. }
  15. // CertKey 证书文件结构
  16. type CertKey struct {
  17. // CertFile is a file containing a PEM-encoded certificate, and possibly the complete certificate chain
  18. CertFile string `json:"cert-file" mapstructure:"cert-file"`
  19. // KeyFile is a file containing a PEM-encoded private key for the certificate specified by CertFile
  20. KeyFile string `json:"private-key-file" mapstructure:"private-key-file"`
  21. }
  22. // GeneratableKeyCert 证书相关配置项
  23. type GeneratableKeyCert struct {
  24. // CertKey allows setting an explicit cert/key file to use.
  25. CertKey CertKey `json:"cert-key" mapstructure:"cert-key"`
  26. // CertDirectory specifies a directory to write generated certificates to if CertFile/KeyFile aren't explicitly set.
  27. // PairName is used to determine the filenames within CertDirectory.
  28. // If CertDirectory and PairName are not set, an in-memory certificate will be generated.
  29. CertDirectory string `json:"cert-dir" mapstructure:"cert-dir"`
  30. // PairName is the name which will be used with CertDirectory to make a cert and key filenames.
  31. // It becomes CertDirectory/PairName.crt and CertDirectory/PairName.key
  32. PairName string `json:"pair-name" mapstructure:"pair-name"`
  33. }
  34. // NewSecureServingOptions creates a SecureServingOptions object with default parameters.
  35. func NewSecureServingOptions() *SecureServingOptions {
  36. return &SecureServingOptions{
  37. BindAddress: "0.0.0.0",
  38. BindPort: 8443,
  39. Required: true,
  40. ServerCert: GeneratableKeyCert{
  41. PairName: "dy-admin",
  42. CertDirectory: "/var/run/dy-admin",
  43. },
  44. }
  45. }
  46. func (s *SecureServingOptions) Validate() []error {
  47. if s == nil {
  48. return nil
  49. }
  50. var errors []error
  51. if s.Required && s.BindPort < 1 || s.BindPort > 65535 {
  52. errors = append(
  53. errors,
  54. fmt.Errorf(
  55. "--secure.bind-port %v must be between 1 and 65535, inclusive. It cannot be turned off with 0",
  56. s.BindPort,
  57. ),
  58. )
  59. } else if s.BindPort < 0 || s.BindPort > 65535 {
  60. errors = append(errors, fmt.Errorf("--secure.bind-port %v must be between 0 and 65535, inclusive. 0 for turning off secure port", s.BindPort))
  61. }
  62. return errors
  63. }
  64. func (s *SecureServingOptions) AddFlags(fs *pflag.FlagSet) {
  65. fs.StringVar(&s.BindAddress, "secure.bind-address", s.BindAddress, ""+
  66. "The IP address on which to listen for the --secure.bind-port port. The "+
  67. "associated interface(s) must be reachable by the rest of the engine, and by CLI/web "+
  68. "clients. If blank, all interfaces will be used (0.0.0.0 for all IPv4 interfaces and :: for all IPv6 interfaces).")
  69. desc := "The port on which to serve HTTPS with authentication and authorization."
  70. if s.Required {
  71. desc += " It cannot be switched off with 0."
  72. } else {
  73. desc += " If 0, don't serve HTTPS at all."
  74. }
  75. fs.IntVar(&s.BindPort, "secure.bind-port", s.BindPort, desc)
  76. fs.StringVar(&s.ServerCert.CertDirectory, "secure.tls.cert-dir", s.ServerCert.CertDirectory, ""+
  77. "The directory where the TLS certs are located. "+
  78. "If --secure.tls.cert-key.cert-file and --secure.tls.cert-key.private-key-file are provided, "+
  79. "this flag will be ignored.")
  80. fs.StringVar(&s.ServerCert.PairName, "secure.tls.pair-name", s.ServerCert.PairName, ""+
  81. "The name which will be used with --secure.tls.cert-dir to make a cert and key filenames. "+
  82. "It becomes <cert-dir>/<pair-name>.crt and <cert-dir>/<pair-name>.key")
  83. fs.StringVar(&s.ServerCert.CertKey.CertFile, "secure.tls.cert-key.cert-file", s.ServerCert.CertKey.CertFile, ""+
  84. "File containing the default x509 Certificate for HTTPS. (CA cert, if any, concatenated "+
  85. "after server cert).")
  86. fs.StringVar(&s.ServerCert.CertKey.KeyFile, "secure.tls.cert-key.private-key-file",
  87. s.ServerCert.CertKey.KeyFile, ""+
  88. "File containing the default x509 private key matching --secure.tls.cert-key.cert-file.")
  89. }
  90. // Complete fills in any fields not set that are required to have valid data.
  91. func (s *SecureServingOptions) Complete() error {
  92. if s == nil || s.BindPort == 0 {
  93. return nil
  94. }
  95. keyCert := &s.ServerCert.CertKey
  96. if len(keyCert.CertFile) != 0 || len(keyCert.KeyFile) != 0 {
  97. return nil
  98. }
  99. if len(s.ServerCert.CertDirectory) > 0 {
  100. if len(s.ServerCert.PairName) == 0 {
  101. return fmt.Errorf("--secure.tls.pair-name is required if --secure.tls.cert-dir is set")
  102. }
  103. keyCert.CertFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".crt")
  104. keyCert.KeyFile = path.Join(s.ServerCert.CertDirectory, s.ServerCert.PairName+".key")
  105. }
  106. return nil
  107. }