| ... | ... |
@@ -11,8 +11,9 @@ import ( |
| 11 | 11 |
|
| 12 | 12 |
kapi "k8s.io/kubernetes/pkg/api" |
| 13 | 13 |
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" |
| 14 |
- "k8s.io/kubernetes/pkg/util/crypto" |
|
| 14 |
+ kcrypto "k8s.io/kubernetes/pkg/util/crypto" |
|
| 15 | 15 |
|
| 16 |
+ "github.com/openshift/origin/pkg/cmd/server/crypto" |
|
| 16 | 17 |
"github.com/openshift/origin/pkg/cmd/templates" |
| 17 | 18 |
) |
| 18 | 19 |
|
| ... | ... |
@@ -24,6 +25,8 @@ type CreateClientOptions struct {
|
| 24 | 24 |
ClientDir string |
| 25 | 25 |
BaseName string |
| 26 | 26 |
|
| 27 |
+ ExpireDays int |
|
| 28 |
+ |
|
| 27 | 29 |
User string |
| 28 | 30 |
Groups []string |
| 29 | 31 |
|
| ... | ... |
@@ -41,7 +44,11 @@ var createClientLong = templates.LongDesc(` |
| 41 | 41 |
master as the provided user.`) |
| 42 | 42 |
|
| 43 | 43 |
func NewCommandCreateClient(commandName string, fullName string, out io.Writer) *cobra.Command {
|
| 44 |
- options := &CreateClientOptions{SignerCertOptions: NewDefaultSignerCertOptions(), Output: out}
|
|
| 44 |
+ options := &CreateClientOptions{
|
|
| 45 |
+ SignerCertOptions: NewDefaultSignerCertOptions(), |
|
| 46 |
+ ExpireDays: crypto.DefaultCertificateLifetimeInDays, |
|
| 47 |
+ Output: out, |
|
| 48 |
+ } |
|
| 45 | 49 |
|
| 46 | 50 |
cmd := &cobra.Command{
|
| 47 | 51 |
Use: commandName, |
| ... | ... |
@@ -71,6 +78,7 @@ func NewCommandCreateClient(commandName string, fullName string, out io.Writer) |
| 71 | 71 |
flags.StringVar(&options.APIServerURL, "master", "https://localhost:8443", "The API server's URL.") |
| 72 | 72 |
flags.StringVar(&options.PublicAPIServerURL, "public-master", "", "The API public facing server's URL (if applicable).") |
| 73 | 73 |
flags.StringSliceVar(&options.APIServerCAFiles, "certificate-authority", []string{"openshift.local.config/master/ca.crt"}, "Files containing signing authorities to use to verify the API server's serving certificate.")
|
| 74 |
+ flags.IntVar(&options.ExpireDays, "expire-days", options.ExpireDays, "Validity of the certificates in days (defaults to 2 years). WARNING: extending this above default value is highly discouraged.") |
|
| 74 | 75 |
|
| 75 | 76 |
// autocompletion hints |
| 76 | 77 |
cmd.MarkFlagFilename("client-dir")
|
| ... | ... |
@@ -96,7 +104,7 @@ func (o CreateClientOptions) Validate(args []string) error {
|
| 96 | 96 |
return errors.New("certificate-authority must be provided")
|
| 97 | 97 |
} else {
|
| 98 | 98 |
for _, caFile := range o.APIServerCAFiles {
|
| 99 |
- if _, err := crypto.CertPoolFromFile(caFile); err != nil {
|
|
| 99 |
+ if _, err := kcrypto.CertPoolFromFile(caFile); err != nil {
|
|
| 100 | 100 |
return fmt.Errorf("certificate-authority must be a valid certificate file: %v", err)
|
| 101 | 101 |
} |
| 102 | 102 |
} |
| ... | ... |
@@ -108,7 +116,9 @@ func (o CreateClientOptions) Validate(args []string) error {
|
| 108 | 108 |
if err := o.SignerCertOptions.Validate(); err != nil {
|
| 109 | 109 |
return err |
| 110 | 110 |
} |
| 111 |
- |
|
| 111 |
+ if o.ExpireDays <= 0 {
|
|
| 112 |
+ return errors.New("expire-days must be valid number of days")
|
|
| 113 |
+ } |
|
| 112 | 114 |
return nil |
| 113 | 115 |
} |
| 114 | 116 |
|
| ... | ... |
@@ -128,12 +138,16 @@ func (o CreateClientOptions) CreateClientFolder() error {
|
| 128 | 128 |
SignerCertOptions: o.SignerCertOptions, |
| 129 | 129 |
CertFile: clientCertFile, |
| 130 | 130 |
KeyFile: clientKeyFile, |
| 131 |
+ ExpireDays: o.ExpireDays, |
|
| 131 | 132 |
|
| 132 | 133 |
User: o.User, |
| 133 | 134 |
Groups: o.Groups, |
| 134 | 135 |
Overwrite: true, |
| 135 | 136 |
Output: o.Output, |
| 136 | 137 |
} |
| 138 |
+ if err := createClientCertOptions.Validate(nil); err != nil {
|
|
| 139 |
+ return err |
|
| 140 |
+ } |
|
| 137 | 141 |
if _, err := createClientCertOptions.CreateClientCert(); err != nil {
|
| 138 | 142 |
return err |
| 139 | 143 |
} |
| ... | ... |
@@ -17,6 +17,8 @@ type CreateClientCertOptions struct {
|
| 17 | 17 |
CertFile string |
| 18 | 18 |
KeyFile string |
| 19 | 19 |
|
| 20 |
+ ExpireDays int |
|
| 21 |
+ |
|
| 20 | 22 |
User string |
| 21 | 23 |
Groups []string |
| 22 | 24 |
|
| ... | ... |
@@ -34,6 +36,9 @@ func (o CreateClientCertOptions) Validate(args []string) error {
|
| 34 | 34 |
if len(o.KeyFile) == 0 {
|
| 35 | 35 |
return errors.New("key must be provided")
|
| 36 | 36 |
} |
| 37 |
+ if o.ExpireDays <= 0 {
|
|
| 38 |
+ return errors.New("expire-days must be valid number of days")
|
|
| 39 |
+ } |
|
| 37 | 40 |
if len(o.User) == 0 {
|
| 38 | 41 |
return errors.New("user must be provided")
|
| 39 | 42 |
} |
| ... | ... |
@@ -60,9 +65,9 @@ func (o CreateClientCertOptions) CreateClientCert() (*crypto.TLSCertificateConfi |
| 60 | 60 |
written := true |
| 61 | 61 |
userInfo := &user.DefaultInfo{Name: o.User, Groups: o.Groups}
|
| 62 | 62 |
if o.Overwrite {
|
| 63 |
- cert, err = signerCert.MakeClientCertificate(o.CertFile, o.KeyFile, userInfo) |
|
| 63 |
+ cert, err = signerCert.MakeClientCertificate(o.CertFile, o.KeyFile, userInfo, o.ExpireDays) |
|
| 64 | 64 |
} else {
|
| 65 |
- cert, written, err = signerCert.EnsureClientCertificate(o.CertFile, o.KeyFile, userInfo) |
|
| 65 |
+ cert, written, err = signerCert.EnsureClientCertificate(o.CertFile, o.KeyFile, userInfo, o.ExpireDays) |
|
| 66 | 66 |
} |
| 67 | 67 |
if written {
|
| 68 | 68 |
glog.V(3).Infof("Generated new client cert as %s and key as %s\n", o.CertFile, o.KeyFile)
|
| ... | ... |
@@ -14,9 +14,10 @@ import ( |
| 14 | 14 |
|
| 15 | 15 |
kapi "k8s.io/kubernetes/pkg/api" |
| 16 | 16 |
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" |
| 17 |
- "k8s.io/kubernetes/pkg/util/crypto" |
|
| 17 |
+ kcrypto "k8s.io/kubernetes/pkg/util/crypto" |
|
| 18 | 18 |
utilerrors "k8s.io/kubernetes/pkg/util/errors" |
| 19 | 19 |
|
| 20 |
+ "github.com/openshift/origin/pkg/cmd/server/crypto" |
|
| 20 | 21 |
"github.com/openshift/origin/pkg/cmd/templates" |
| 21 | 22 |
"github.com/openshift/origin/pkg/util/parallel" |
| 22 | 23 |
) |
| ... | ... |
@@ -72,6 +73,9 @@ type CreateMasterCertsOptions struct {
|
| 72 | 72 |
CertDir string |
| 73 | 73 |
SignerName string |
| 74 | 74 |
|
| 75 |
+ ExpireDays int |
|
| 76 |
+ SignerExpireDays int |
|
| 77 |
+ |
|
| 75 | 78 |
APIServerCAFiles []string |
| 76 | 79 |
CABundleFile string |
| 77 | 80 |
|
| ... | ... |
@@ -85,7 +89,11 @@ type CreateMasterCertsOptions struct {
|
| 85 | 85 |
} |
| 86 | 86 |
|
| 87 | 87 |
func NewCommandCreateMasterCerts(commandName string, fullName string, out io.Writer) *cobra.Command {
|
| 88 |
- options := &CreateMasterCertsOptions{Output: out}
|
|
| 88 |
+ options := &CreateMasterCertsOptions{
|
|
| 89 |
+ ExpireDays: crypto.DefaultCertificateLifetimeInDays, |
|
| 90 |
+ SignerExpireDays: crypto.DefaultCACertificateLifetimeInDays, |
|
| 91 |
+ Output: out, |
|
| 92 |
+ } |
|
| 89 | 93 |
|
| 90 | 94 |
cmd := &cobra.Command{
|
| 91 | 95 |
Use: commandName, |
| ... | ... |
@@ -113,6 +121,9 @@ func NewCommandCreateMasterCerts(commandName string, fullName string, out io.Wri |
| 113 | 113 |
flags.StringSliceVar(&options.Hostnames, "hostnames", options.Hostnames, "Every hostname or IP that server certs should be valid for (comma-delimited list)") |
| 114 | 114 |
flags.BoolVar(&options.Overwrite, "overwrite", false, "Overwrite all existing cert/key/config files (WARNING: includes signer/CA)") |
| 115 | 115 |
|
| 116 |
+ flags.IntVar(&options.ExpireDays, "expire-days", options.ExpireDays, "Validity of the certificates in days (defaults to 2 years). WARNING: extending this above default value is highly discouraged.") |
|
| 117 |
+ flags.IntVar(&options.SignerExpireDays, "signer-expire-days", options.SignerExpireDays, "Validity of the CA certificate in days (defaults to 5 years). WARNING: extending this above default value is highly discouraged.") |
|
| 118 |
+ |
|
| 116 | 119 |
// set dynamic value annotation - allows man pages to be generated and verified |
| 117 | 120 |
flags.SetAnnotation("signer-name", "manpage-def-value", []string{"openshift-signer@<current_timestamp>"})
|
| 118 | 121 |
|
| ... | ... |
@@ -136,6 +147,12 @@ func (o CreateMasterCertsOptions) Validate(args []string) error {
|
| 136 | 136 |
if len(o.SignerName) == 0 {
|
| 137 | 137 |
return errors.New("signer-name must be provided")
|
| 138 | 138 |
} |
| 139 |
+ if o.ExpireDays <= 0 {
|
|
| 140 |
+ return errors.New("expire-days must be valid number of days")
|
|
| 141 |
+ } |
|
| 142 |
+ if o.SignerExpireDays <= 0 {
|
|
| 143 |
+ return errors.New("signer-expire-days must be valid number of days")
|
|
| 144 |
+ } |
|
| 139 | 145 |
if len(o.APIServerURL) == 0 {
|
| 140 | 146 |
return errors.New("master must be provided")
|
| 141 | 147 |
} else if u, err := url.Parse(o.APIServerURL); err != nil {
|
| ... | ... |
@@ -153,7 +170,7 @@ func (o CreateMasterCertsOptions) Validate(args []string) error {
|
| 153 | 153 |
} |
| 154 | 154 |
|
| 155 | 155 |
for _, caFile := range o.APIServerCAFiles {
|
| 156 |
- if _, err := crypto.CertPoolFromFile(caFile); err != nil {
|
|
| 156 |
+ if _, err := kcrypto.CertPoolFromFile(caFile); err != nil {
|
|
| 157 | 157 |
return fmt.Errorf("certificate authority must be a valid certificate file: %v", err)
|
| 158 | 158 |
} |
| 159 | 159 |
} |
| ... | ... |
@@ -168,6 +185,7 @@ func (o CreateMasterCertsOptions) CreateMasterCerts() error {
|
| 168 | 168 |
CertFile: DefaultCertFilename(o.CertDir, CAFilePrefix), |
| 169 | 169 |
KeyFile: DefaultKeyFilename(o.CertDir, CAFilePrefix), |
| 170 | 170 |
SerialFile: DefaultSerialFilename(o.CertDir, CAFilePrefix), |
| 171 |
+ ExpireDays: o.SignerExpireDays, |
|
| 171 | 172 |
Name: o.SignerName, |
| 172 | 173 |
Overwrite: o.Overwrite, |
| 173 | 174 |
Output: o.Output, |
| ... | ... |
@@ -261,11 +279,16 @@ func (o CreateMasterCertsOptions) createClientCert(clientCertInfo ClientCertInfo |
| 261 | 261 |
CertFile: clientCertInfo.CertLocation.CertFile, |
| 262 | 262 |
KeyFile: clientCertInfo.CertLocation.KeyFile, |
| 263 | 263 |
|
| 264 |
+ ExpireDays: o.ExpireDays, |
|
| 265 |
+ |
|
| 264 | 266 |
User: clientCertInfo.User, |
| 265 | 267 |
Groups: clientCertInfo.Groups.List(), |
| 266 | 268 |
Overwrite: o.Overwrite, |
| 267 | 269 |
Output: o.Output, |
| 268 | 270 |
} |
| 271 |
+ if err := clientCertOptions.Validate(nil); err != nil {
|
|
| 272 |
+ return err |
|
| 273 |
+ } |
|
| 269 | 274 |
if _, err := clientCertOptions.CreateClientCert(); err != nil {
|
| 270 | 275 |
return err |
| 271 | 276 |
} |
| ... | ... |
@@ -295,6 +318,8 @@ func (o CreateMasterCertsOptions) createServerCerts(getSignerCertOptions *Signer |
| 295 | 295 |
CertFile: serverCertInfo.CertFile, |
| 296 | 296 |
KeyFile: serverCertInfo.KeyFile, |
| 297 | 297 |
|
| 298 |
+ ExpireDays: o.ExpireDays, |
|
| 299 |
+ |
|
| 298 | 300 |
Hostnames: o.Hostnames, |
| 299 | 301 |
Overwrite: o.Overwrite, |
| 300 | 302 |
Output: o.Output, |
| ... | ... |
@@ -333,6 +358,7 @@ func (o CreateMasterCertsOptions) createServiceSigningCA(getSignerCertOptions *S |
| 333 | 333 |
CertFile: caInfo.CertFile, |
| 334 | 334 |
KeyFile: caInfo.KeyFile, |
| 335 | 335 |
SerialFile: "", // we want the random cert serial for this one |
| 336 |
+ ExpireDays: o.SignerExpireDays, |
|
| 336 | 337 |
Name: DefaultServiceServingCertSignerName(), |
| 337 | 338 |
Output: o.Output, |
| 338 | 339 |
|
| ... | ... |
@@ -18,11 +18,12 @@ import ( |
| 18 | 18 |
kcmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util" |
| 19 | 19 |
"k8s.io/kubernetes/pkg/master/ports" |
| 20 | 20 |
"k8s.io/kubernetes/pkg/runtime" |
| 21 |
- "k8s.io/kubernetes/pkg/util/crypto" |
|
| 21 |
+ kcrypto "k8s.io/kubernetes/pkg/util/crypto" |
|
| 22 | 22 |
|
| 23 | 23 |
"github.com/openshift/origin/pkg/cmd/flagtypes" |
| 24 | 24 |
configapi "github.com/openshift/origin/pkg/cmd/server/api" |
| 25 | 25 |
latestconfigapi "github.com/openshift/origin/pkg/cmd/server/api/latest" |
| 26 |
+ "github.com/openshift/origin/pkg/cmd/server/crypto" |
|
| 26 | 27 |
cmdutil "github.com/openshift/origin/pkg/cmd/util" |
| 27 | 28 |
"github.com/openshift/origin/pkg/cmd/util/variable" |
| 28 | 29 |
) |
| ... | ... |
@@ -47,6 +48,7 @@ type CreateNodeConfigOptions struct {
|
| 47 | 47 |
ClientKeyFile string |
| 48 | 48 |
ServerCertFile string |
| 49 | 49 |
ServerKeyFile string |
| 50 |
+ ExpireDays int |
|
| 50 | 51 |
NodeClientCAFile string |
| 51 | 52 |
APIServerCAFiles []string |
| 52 | 53 |
APIServerURL string |
| ... | ... |
@@ -92,6 +94,7 @@ func NewCommandNodeConfig(commandName string, fullName string, out io.Writer) *c |
| 92 | 92 |
flags.StringVar(&options.ClientKeyFile, "client-key", "", "The client key file for the node to contact the API.") |
| 93 | 93 |
flags.StringVar(&options.ServerCertFile, "server-certificate", "", "The server cert file for the node to serve secure traffic.") |
| 94 | 94 |
flags.StringVar(&options.ServerKeyFile, "server-key", "", "The server key file for the node to serve secure traffic.") |
| 95 |
+ flags.IntVar(&options.ExpireDays, "expire-days", options.ExpireDays, "Validity of the certificates in days (defaults to 2 years). WARNING: extending this above default value is highly discouraged.") |
|
| 95 | 96 |
flags.StringVar(&options.NodeClientCAFile, "node-client-certificate-authority", options.NodeClientCAFile, "The file containing signing authorities to use to verify requests to the node. If empty, all requests will be allowed.") |
| 96 | 97 |
flags.StringVar(&options.APIServerURL, "master", options.APIServerURL, "The API server's URL.") |
| 97 | 98 |
flags.StringSliceVar(&options.APIServerCAFiles, "certificate-authority", options.APIServerCAFiles, "Files containing signing authorities to use to verify the API server's serving certificate.") |
| ... | ... |
@@ -111,7 +114,10 @@ func NewCommandNodeConfig(commandName string, fullName string, out io.Writer) *c |
| 111 | 111 |
} |
| 112 | 112 |
|
| 113 | 113 |
func NewDefaultCreateNodeConfigOptions() *CreateNodeConfigOptions {
|
| 114 |
- options := &CreateNodeConfigOptions{SignerCertOptions: NewDefaultSignerCertOptions()}
|
|
| 114 |
+ options := &CreateNodeConfigOptions{
|
|
| 115 |
+ SignerCertOptions: NewDefaultSignerCertOptions(), |
|
| 116 |
+ ExpireDays: crypto.DefaultCertificateLifetimeInDays, |
|
| 117 |
+ } |
|
| 115 | 118 |
options.VolumeDir = "openshift.local.volumes" |
| 116 | 119 |
// TODO: replace me with a proper round trip of config options through decode |
| 117 | 120 |
options.DNSDomain = "cluster.local" |
| ... | ... |
@@ -160,7 +166,7 @@ func (o CreateNodeConfigOptions) Validate(args []string) error {
|
| 160 | 160 |
return fmt.Errorf("--certificate-authority must be a valid certificate file")
|
| 161 | 161 |
} else {
|
| 162 | 162 |
for _, caFile := range o.APIServerCAFiles {
|
| 163 |
- if _, err := crypto.CertPoolFromFile(caFile); err != nil {
|
|
| 163 |
+ if _, err := kcrypto.CertPoolFromFile(caFile); err != nil {
|
|
| 164 | 164 |
return fmt.Errorf("--certificate-authority must be a valid certificate file: %v", err)
|
| 165 | 165 |
} |
| 166 | 166 |
} |
| ... | ... |
@@ -197,6 +203,10 @@ func (o CreateNodeConfigOptions) Validate(args []string) error {
|
| 197 | 197 |
} |
| 198 | 198 |
} |
| 199 | 199 |
|
| 200 |
+ if o.ExpireDays < 0 {
|
|
| 201 |
+ return errors.New("expire-days must be valid number of days")
|
|
| 202 |
+ } |
|
| 203 |
+ |
|
| 200 | 204 |
return nil |
| 201 | 205 |
} |
| 202 | 206 |
|
| ... | ... |
@@ -285,6 +295,8 @@ func (o CreateNodeConfigOptions) MakeClientCert(clientCertFile, clientKeyFile st |
| 285 | 285 |
CertFile: clientCertFile, |
| 286 | 286 |
KeyFile: clientKeyFile, |
| 287 | 287 |
|
| 288 |
+ ExpireDays: o.ExpireDays, |
|
| 289 |
+ |
|
| 288 | 290 |
User: "system:node:" + o.NodeName, |
| 289 | 291 |
Groups: []string{bootstrappolicy.NodesGroup},
|
| 290 | 292 |
Output: o.Output, |
| ... | ... |
@@ -317,6 +329,8 @@ func (o CreateNodeConfigOptions) MakeAndWriteServerCert(serverCertFile, serverKe |
| 317 | 317 |
CertFile: serverCertFile, |
| 318 | 318 |
KeyFile: serverKeyFile, |
| 319 | 319 |
|
| 320 |
+ ExpireDays: o.ExpireDays, |
|
| 321 |
+ |
|
| 320 | 322 |
Hostnames: o.Hostnames, |
| 321 | 323 |
Output: o.Output, |
| 322 | 324 |
} |
| ... | ... |
@@ -23,6 +23,8 @@ type CreateServerCertOptions struct {
|
| 23 | 23 |
CertFile string |
| 24 | 24 |
KeyFile string |
| 25 | 25 |
|
| 26 |
+ ExpireDays int |
|
| 27 |
+ |
|
| 26 | 28 |
Hostnames []string |
| 27 | 29 |
Overwrite bool |
| 28 | 30 |
Output io.Writer |
| ... | ... |
@@ -46,7 +48,11 @@ var createServerLong = templates.LongDesc(` |
| 46 | 46 |
`) |
| 47 | 47 |
|
| 48 | 48 |
func NewCommandCreateServerCert(commandName string, fullName string, out io.Writer) *cobra.Command {
|
| 49 |
- options := &CreateServerCertOptions{SignerCertOptions: NewDefaultSignerCertOptions(), Output: out}
|
|
| 49 |
+ options := &CreateServerCertOptions{
|
|
| 50 |
+ SignerCertOptions: NewDefaultSignerCertOptions(), |
|
| 51 |
+ ExpireDays: crypto.DefaultCertificateLifetimeInDays, |
|
| 52 |
+ Output: out, |
|
| 53 |
+ } |
|
| 50 | 54 |
|
| 51 | 55 |
cmd := &cobra.Command{
|
| 52 | 56 |
Use: commandName, |
| ... | ... |
@@ -72,6 +78,8 @@ func NewCommandCreateServerCert(commandName string, fullName string, out io.Writ |
| 72 | 72 |
flags.StringSliceVar(&options.Hostnames, "hostnames", options.Hostnames, "Every hostname or IP you want server certs to be valid for. Comma delimited list") |
| 73 | 73 |
flags.BoolVar(&options.Overwrite, "overwrite", true, "Overwrite existing cert files if found. If false, any existing file will be left as-is.") |
| 74 | 74 |
|
| 75 |
+ flags.IntVar(&options.ExpireDays, "expire-days", options.ExpireDays, "Validity of the certificate in days (defaults to 2 years). WARNING: extending this above default value is highly discouraged.") |
|
| 76 |
+ |
|
| 75 | 77 |
// autocompletion hints |
| 76 | 78 |
cmd.MarkFlagFilename("cert")
|
| 77 | 79 |
cmd.MarkFlagFilename("key")
|
| ... | ... |
@@ -93,6 +101,10 @@ func (o CreateServerCertOptions) Validate(args []string) error {
|
| 93 | 93 |
return errors.New("key must be provided")
|
| 94 | 94 |
} |
| 95 | 95 |
|
| 96 |
+ if o.ExpireDays <= 0 {
|
|
| 97 |
+ return errors.New("expire-days must be valid number of days")
|
|
| 98 |
+ } |
|
| 99 |
+ |
|
| 96 | 100 |
if o.SignerCertOptions == nil {
|
| 97 | 101 |
return errors.New("signer options are required")
|
| 98 | 102 |
} |
| ... | ... |
@@ -114,9 +126,9 @@ func (o CreateServerCertOptions) CreateServerCert() (*crypto.TLSCertificateConfi |
| 114 | 114 |
var ca *crypto.TLSCertificateConfig |
| 115 | 115 |
written := true |
| 116 | 116 |
if o.Overwrite {
|
| 117 |
- ca, err = signerCert.MakeAndWriteServerCert(o.CertFile, o.KeyFile, sets.NewString([]string(o.Hostnames)...)) |
|
| 117 |
+ ca, err = signerCert.MakeAndWriteServerCert(o.CertFile, o.KeyFile, sets.NewString([]string(o.Hostnames)...), o.ExpireDays) |
|
| 118 | 118 |
} else {
|
| 119 |
- ca, written, err = signerCert.EnsureServerCert(o.CertFile, o.KeyFile, sets.NewString([]string(o.Hostnames)...)) |
|
| 119 |
+ ca, written, err = signerCert.EnsureServerCert(o.CertFile, o.KeyFile, sets.NewString([]string(o.Hostnames)...), o.ExpireDays) |
|
| 120 | 120 |
} |
| 121 | 121 |
if written {
|
| 122 | 122 |
glog.V(3).Infof("Generated new server certificate as %s, key as %s\n", o.CertFile, o.KeyFile)
|
| ... | ... |
@@ -20,6 +20,7 @@ type CreateSignerCertOptions struct {
|
| 20 | 20 |
CertFile string |
| 21 | 21 |
KeyFile string |
| 22 | 22 |
SerialFile string |
| 23 |
+ ExpireDays int |
|
| 23 | 24 |
Name string |
| 24 | 25 |
Output io.Writer |
| 25 | 26 |
|
| ... | ... |
@@ -33,6 +34,8 @@ func BindCreateSignerCertOptions(options *CreateSignerCertOptions, flags *pflag. |
| 33 | 33 |
flags.StringVar(&options.Name, prefix+"name", DefaultSignerName(), "The name of the signer.") |
| 34 | 34 |
flags.BoolVar(&options.Overwrite, prefix+"overwrite", options.Overwrite, "Overwrite existing cert files if found. If false, any existing file will be left as-is.") |
| 35 | 35 |
|
| 36 |
+ flags.IntVar(&options.ExpireDays, "expire-days", options.ExpireDays, "Validity of the certificate in days (defaults to 5 years). WARNING: extending this above default value is highly discouraged.") |
|
| 37 |
+ |
|
| 36 | 38 |
// set dynamic value annotation - allows man pages to be generated and verified |
| 37 | 39 |
flags.SetAnnotation(prefix+"name", "manpage-def-value", []string{"openshift-signer@<current_timestamp>"})
|
| 38 | 40 |
|
| ... | ... |
@@ -46,7 +49,11 @@ var createSignerLong = templates.LongDesc(` |
| 46 | 46 |
Create a self-signed CA key/cert for signing certificates used by server components.`) |
| 47 | 47 |
|
| 48 | 48 |
func NewCommandCreateSignerCert(commandName string, fullName string, out io.Writer) *cobra.Command {
|
| 49 |
- options := &CreateSignerCertOptions{Overwrite: true, Output: out}
|
|
| 49 |
+ options := &CreateSignerCertOptions{
|
|
| 50 |
+ ExpireDays: crypto.DefaultCACertificateLifetimeInDays, |
|
| 51 |
+ Output: out, |
|
| 52 |
+ Overwrite: true, |
|
| 53 |
+ } |
|
| 50 | 54 |
|
| 51 | 55 |
cmd := &cobra.Command{
|
| 52 | 56 |
Use: commandName, |
| ... | ... |
@@ -78,6 +85,9 @@ func (o CreateSignerCertOptions) Validate(args []string) error {
|
| 78 | 78 |
if len(o.KeyFile) == 0 {
|
| 79 | 79 |
return errors.New("key must be provided")
|
| 80 | 80 |
} |
| 81 |
+ if o.ExpireDays <= 0 {
|
|
| 82 |
+ return errors.New("expire-days must be valid number of days")
|
|
| 83 |
+ } |
|
| 81 | 84 |
if len(o.Name) == 0 {
|
| 82 | 85 |
return errors.New("name must be provided")
|
| 83 | 86 |
} |
| ... | ... |
@@ -91,9 +101,9 @@ func (o CreateSignerCertOptions) CreateSignerCert() (*crypto.CA, error) {
|
| 91 | 91 |
var err error |
| 92 | 92 |
written := true |
| 93 | 93 |
if o.Overwrite {
|
| 94 |
- ca, err = crypto.MakeCA(o.CertFile, o.KeyFile, o.SerialFile, o.Name) |
|
| 94 |
+ ca, err = crypto.MakeCA(o.CertFile, o.KeyFile, o.SerialFile, o.Name, o.ExpireDays) |
|
| 95 | 95 |
} else {
|
| 96 |
- ca, written, err = crypto.EnsureCA(o.CertFile, o.KeyFile, o.SerialFile, o.Name) |
|
| 96 |
+ ca, written, err = crypto.EnsureCA(o.CertFile, o.KeyFile, o.SerialFile, o.Name, o.ExpireDays) |
|
| 97 | 97 |
} |
| 98 | 98 |
if written {
|
| 99 | 99 |
glog.V(3).Infof("Generated new CA for %s: cert in %s and key in %s\n", o.Name, o.CertFile, o.KeyFile)
|
| ... | ... |
@@ -174,12 +174,9 @@ func GetTLSCertificateConfig(certFile, keyFile string) (*TLSCertificateConfig, e |
| 174 | 174 |
return &TLSCertificateConfig{certs, key}, nil
|
| 175 | 175 |
} |
| 176 | 176 |
|
| 177 |
-var ( |
|
| 178 |
- // Default ca certs to be long-lived |
|
| 179 |
- caLifetime = time.Hour * 24 * 365 * 5 |
|
| 180 |
- |
|
| 181 |
- // Default templates to last for two years |
|
| 182 |
- lifetime = time.Hour * 24 * 365 * 2 |
|
| 177 |
+const ( |
|
| 178 |
+ DefaultCertificateLifetimeInDays = 365 * 2 // 2 years |
|
| 179 |
+ DefaultCACertificateLifetimeInDays = 365 * 5 // 5 years |
|
| 183 | 180 |
|
| 184 | 181 |
// Default keys are 2048 bits |
| 185 | 182 |
keyBits = 2048 |
| ... | ... |
@@ -261,11 +258,11 @@ func (s *RandomSerialGenerator) Next(template *x509.Certificate) (int64, error) |
| 261 | 261 |
|
| 262 | 262 |
// EnsureCA returns a CA, whether it was created (as opposed to pre-existing), and any error |
| 263 | 263 |
// if serialFile is empty, a RandomSerialGenerator will be used |
| 264 |
-func EnsureCA(certFile, keyFile, serialFile, name string) (*CA, bool, error) {
|
|
| 264 |
+func EnsureCA(certFile, keyFile, serialFile, name string, expireDays int) (*CA, bool, error) {
|
|
| 265 | 265 |
if ca, err := GetCA(certFile, keyFile, serialFile); err == nil {
|
| 266 | 266 |
return ca, false, err |
| 267 | 267 |
} |
| 268 |
- ca, err := MakeCA(certFile, keyFile, serialFile, name) |
|
| 268 |
+ ca, err := MakeCA(certFile, keyFile, serialFile, name, expireDays) |
|
| 269 | 269 |
return ca, true, err |
| 270 | 270 |
} |
| 271 | 271 |
|
| ... | ... |
@@ -293,17 +290,14 @@ func GetCA(certFile, keyFile, serialFile string) (*CA, error) {
|
| 293 | 293 |
} |
| 294 | 294 |
|
| 295 | 295 |
// if serialFile is empty, a RandomSerialGenerator will be used |
| 296 |
-func MakeCA(certFile, keyFile, serialFile, name string) (*CA, error) {
|
|
| 296 |
+func MakeCA(certFile, keyFile, serialFile, name string, expireDays int) (*CA, error) {
|
|
| 297 | 297 |
glog.V(2).Infof("Generating new CA for %s cert, and key in %s, %s", name, certFile, keyFile)
|
| 298 | 298 |
// Create CA cert |
| 299 | 299 |
rootcaPublicKey, rootcaPrivateKey, err := NewKeyPair() |
| 300 | 300 |
if err != nil {
|
| 301 | 301 |
return nil, err |
| 302 | 302 |
} |
| 303 |
- rootcaTemplate, err := newSigningCertificateTemplate(pkix.Name{CommonName: name})
|
|
| 304 |
- if err != nil {
|
|
| 305 |
- return nil, err |
|
| 306 |
- } |
|
| 303 |
+ rootcaTemplate := newSigningCertificateTemplate(pkix.Name{CommonName: name}, expireDays, time.Now)
|
|
| 307 | 304 |
rootcaCert, err := signCertificate(rootcaTemplate, rootcaPublicKey, rootcaTemplate, rootcaPrivateKey) |
| 308 | 305 |
if err != nil {
|
| 309 | 306 |
return nil, err |
| ... | ... |
@@ -335,10 +329,10 @@ func MakeCA(certFile, keyFile, serialFile, name string) (*CA, error) {
|
| 335 | 335 |
}, nil |
| 336 | 336 |
} |
| 337 | 337 |
|
| 338 |
-func (ca *CA) EnsureServerCert(certFile, keyFile string, hostnames sets.String) (*TLSCertificateConfig, bool, error) {
|
|
| 338 |
+func (ca *CA) EnsureServerCert(certFile, keyFile string, hostnames sets.String, expireDays int) (*TLSCertificateConfig, bool, error) {
|
|
| 339 | 339 |
certConfig, err := GetServerCert(certFile, keyFile, hostnames) |
| 340 | 340 |
if err != nil {
|
| 341 |
- certConfig, err = ca.MakeAndWriteServerCert(certFile, keyFile, hostnames) |
|
| 341 |
+ certConfig, err = ca.MakeAndWriteServerCert(certFile, keyFile, hostnames, expireDays) |
|
| 342 | 342 |
return certConfig, true, err |
| 343 | 343 |
} |
| 344 | 344 |
|
| ... | ... |
@@ -363,10 +357,10 @@ func GetServerCert(certFile, keyFile string, hostnames sets.String) (*TLSCertifi |
| 363 | 363 |
return nil, fmt.Errorf("Existing server certificate in %s was missing some hostnames (%v) or IP addresses (%v).", certFile, missingDns, missingIps)
|
| 364 | 364 |
} |
| 365 | 365 |
|
| 366 |
-func (ca *CA) MakeAndWriteServerCert(certFile, keyFile string, hostnames sets.String) (*TLSCertificateConfig, error) {
|
|
| 366 |
+func (ca *CA) MakeAndWriteServerCert(certFile, keyFile string, hostnames sets.String, expireDays int) (*TLSCertificateConfig, error) {
|
|
| 367 | 367 |
glog.V(4).Infof("Generating server certificate in %s, key in %s", certFile, keyFile)
|
| 368 | 368 |
|
| 369 |
- server, err := ca.MakeServerCert(hostnames) |
|
| 369 |
+ server, err := ca.MakeServerCert(hostnames, expireDays) |
|
| 370 | 370 |
if err != nil {
|
| 371 | 371 |
return nil, err |
| 372 | 372 |
} |
| ... | ... |
@@ -376,9 +370,9 @@ func (ca *CA) MakeAndWriteServerCert(certFile, keyFile string, hostnames sets.St |
| 376 | 376 |
return server, nil |
| 377 | 377 |
} |
| 378 | 378 |
|
| 379 |
-func (ca *CA) MakeServerCert(hostnames sets.String) (*TLSCertificateConfig, error) {
|
|
| 379 |
+func (ca *CA) MakeServerCert(hostnames sets.String, expireDays int) (*TLSCertificateConfig, error) {
|
|
| 380 | 380 |
serverPublicKey, serverPrivateKey, _ := NewKeyPair() |
| 381 |
- serverTemplate, _ := newServerCertificateTemplate(pkix.Name{CommonName: hostnames.List()[0]}, hostnames.List())
|
|
| 381 |
+ serverTemplate := newServerCertificateTemplate(pkix.Name{CommonName: hostnames.List()[0]}, hostnames.List(), expireDays, time.Now)
|
|
| 382 | 382 |
serverCrt, err := ca.signCertificate(serverTemplate, serverPublicKey) |
| 383 | 383 |
if err != nil {
|
| 384 | 384 |
return nil, err |
| ... | ... |
@@ -390,17 +384,17 @@ func (ca *CA) MakeServerCert(hostnames sets.String) (*TLSCertificateConfig, erro |
| 390 | 390 |
return server, nil |
| 391 | 391 |
} |
| 392 | 392 |
|
| 393 |
-func (ca *CA) EnsureClientCertificate(certFile, keyFile string, u user.Info) (*TLSCertificateConfig, bool, error) {
|
|
| 393 |
+func (ca *CA) EnsureClientCertificate(certFile, keyFile string, u user.Info, expireDays int) (*TLSCertificateConfig, bool, error) {
|
|
| 394 | 394 |
certConfig, err := GetTLSCertificateConfig(certFile, keyFile) |
| 395 | 395 |
if err != nil {
|
| 396 |
- certConfig, err = ca.MakeClientCertificate(certFile, keyFile, u) |
|
| 396 |
+ certConfig, err = ca.MakeClientCertificate(certFile, keyFile, u, expireDays) |
|
| 397 | 397 |
return certConfig, true, err // true indicates we wrote the files. |
| 398 | 398 |
} |
| 399 | 399 |
|
| 400 | 400 |
return certConfig, false, nil |
| 401 | 401 |
} |
| 402 | 402 |
|
| 403 |
-func (ca *CA) MakeClientCertificate(certFile, keyFile string, u user.Info) (*TLSCertificateConfig, error) {
|
|
| 403 |
+func (ca *CA) MakeClientCertificate(certFile, keyFile string, u user.Info, expireDays int) (*TLSCertificateConfig, error) {
|
|
| 404 | 404 |
glog.V(4).Infof("Generating client cert in %s and key in %s", certFile, keyFile)
|
| 405 | 405 |
// ensure parent dirs |
| 406 | 406 |
if err := os.MkdirAll(filepath.Dir(certFile), os.FileMode(0755)); err != nil {
|
| ... | ... |
@@ -411,7 +405,7 @@ func (ca *CA) MakeClientCertificate(certFile, keyFile string, u user.Info) (*TLS |
| 411 | 411 |
} |
| 412 | 412 |
|
| 413 | 413 |
clientPublicKey, clientPrivateKey, _ := NewKeyPair() |
| 414 |
- clientTemplate, _ := newClientCertificateTemplate(x509request.UserToSubject(u)) |
|
| 414 |
+ clientTemplate := newClientCertificateTemplate(x509request.UserToSubject(u), expireDays, time.Now) |
|
| 415 | 415 |
clientCrt, err := ca.signCertificate(clientTemplate, clientPublicKey) |
| 416 | 416 |
if err != nil {
|
| 417 | 417 |
return nil, err |
| ... | ... |
@@ -455,31 +449,53 @@ func NewKeyPair() (crypto.PublicKey, crypto.PrivateKey, error) {
|
| 455 | 455 |
} |
| 456 | 456 |
|
| 457 | 457 |
// Can be used for CA or intermediate signing certs |
| 458 |
-func newSigningCertificateTemplate(subject pkix.Name) (*x509.Certificate, error) {
|
|
| 458 |
+func newSigningCertificateTemplate(subject pkix.Name, expireDays int, currentTime func() time.Time) *x509.Certificate {
|
|
| 459 |
+ var caLifetimeInDays = DefaultCACertificateLifetimeInDays |
|
| 460 |
+ if expireDays > 0 {
|
|
| 461 |
+ caLifetimeInDays = expireDays |
|
| 462 |
+ } |
|
| 463 |
+ |
|
| 464 |
+ if caLifetimeInDays > DefaultCACertificateLifetimeInDays {
|
|
| 465 |
+ warnAboutCertificateLifeTime(subject.CommonName, DefaultCACertificateLifetimeInDays) |
|
| 466 |
+ } |
|
| 467 |
+ |
|
| 468 |
+ caLifetime := time.Duration(caLifetimeInDays) * 24 * time.Hour |
|
| 469 |
+ |
|
| 459 | 470 |
return &x509.Certificate{
|
| 460 | 471 |
Subject: subject, |
| 461 | 472 |
|
| 462 | 473 |
SignatureAlgorithm: x509.SHA256WithRSA, |
| 463 | 474 |
|
| 464 |
- NotBefore: time.Now().Add(-1 * time.Second), |
|
| 465 |
- NotAfter: time.Now().Add(caLifetime), |
|
| 475 |
+ NotBefore: currentTime().Add(-1 * time.Second), |
|
| 476 |
+ NotAfter: currentTime().Add(caLifetime), |
|
| 466 | 477 |
SerialNumber: big.NewInt(1), |
| 467 | 478 |
|
| 468 | 479 |
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, |
| 469 | 480 |
BasicConstraintsValid: true, |
| 470 | 481 |
IsCA: true, |
| 471 |
- }, nil |
|
| 482 |
+ } |
|
| 472 | 483 |
} |
| 473 | 484 |
|
| 474 | 485 |
// Can be used for ListenAndServeTLS |
| 475 |
-func newServerCertificateTemplate(subject pkix.Name, hosts []string) (*x509.Certificate, error) {
|
|
| 486 |
+func newServerCertificateTemplate(subject pkix.Name, hosts []string, expireDays int, currentTime func() time.Time) *x509.Certificate {
|
|
| 487 |
+ var lifetimeInDays = DefaultCertificateLifetimeInDays |
|
| 488 |
+ if expireDays > 0 {
|
|
| 489 |
+ lifetimeInDays = expireDays |
|
| 490 |
+ } |
|
| 491 |
+ |
|
| 492 |
+ if lifetimeInDays > DefaultCertificateLifetimeInDays {
|
|
| 493 |
+ warnAboutCertificateLifeTime(subject.CommonName, DefaultCertificateLifetimeInDays) |
|
| 494 |
+ } |
|
| 495 |
+ |
|
| 496 |
+ lifetime := time.Duration(lifetimeInDays) * 24 * time.Hour |
|
| 497 |
+ |
|
| 476 | 498 |
template := &x509.Certificate{
|
| 477 | 499 |
Subject: subject, |
| 478 | 500 |
|
| 479 | 501 |
SignatureAlgorithm: x509.SHA256WithRSA, |
| 480 | 502 |
|
| 481 |
- NotBefore: time.Now().Add(-1 * time.Second), |
|
| 482 |
- NotAfter: time.Now().Add(lifetime), |
|
| 503 |
+ NotBefore: currentTime().Add(-1 * time.Second), |
|
| 504 |
+ NotAfter: currentTime().Add(lifetime), |
|
| 483 | 505 |
SerialNumber: big.NewInt(1), |
| 484 | 506 |
|
| 485 | 507 |
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, |
| ... | ... |
@@ -489,7 +505,7 @@ func newServerCertificateTemplate(subject pkix.Name, hosts []string) (*x509.Cert |
| 489 | 489 |
|
| 490 | 490 |
template.IPAddresses, template.DNSNames = IPAddressesDNSNames(hosts) |
| 491 | 491 |
|
| 492 |
- return template, nil |
|
| 492 |
+ return template |
|
| 493 | 493 |
} |
| 494 | 494 |
|
| 495 | 495 |
func IPAddressesDNSNames(hosts []string) ([]net.IP, []string) {
|
| ... | ... |
@@ -542,20 +558,37 @@ func CertsFromPEM(pemCerts []byte) ([]*x509.Certificate, error) {
|
| 542 | 542 |
} |
| 543 | 543 |
|
| 544 | 544 |
// Can be used as a certificate in http.Transport TLSClientConfig |
| 545 |
-func newClientCertificateTemplate(subject pkix.Name) (*x509.Certificate, error) {
|
|
| 545 |
+func newClientCertificateTemplate(subject pkix.Name, expireDays int, currentTime func() time.Time) *x509.Certificate {
|
|
| 546 |
+ var lifetimeInDays = DefaultCertificateLifetimeInDays |
|
| 547 |
+ if expireDays > 0 {
|
|
| 548 |
+ lifetimeInDays = expireDays |
|
| 549 |
+ } |
|
| 550 |
+ |
|
| 551 |
+ if lifetimeInDays > DefaultCertificateLifetimeInDays {
|
|
| 552 |
+ warnAboutCertificateLifeTime(subject.CommonName, DefaultCertificateLifetimeInDays) |
|
| 553 |
+ } |
|
| 554 |
+ |
|
| 555 |
+ lifetime := time.Duration(lifetimeInDays) * 24 * time.Hour |
|
| 556 |
+ |
|
| 546 | 557 |
return &x509.Certificate{
|
| 547 | 558 |
Subject: subject, |
| 548 | 559 |
|
| 549 | 560 |
SignatureAlgorithm: x509.SHA256WithRSA, |
| 550 | 561 |
|
| 551 |
- NotBefore: time.Now().Add(-1 * time.Second), |
|
| 552 |
- NotAfter: time.Now().Add(lifetime), |
|
| 562 |
+ NotBefore: currentTime().Add(-1 * time.Second), |
|
| 563 |
+ NotAfter: currentTime().Add(lifetime), |
|
| 553 | 564 |
SerialNumber: big.NewInt(1), |
| 554 | 565 |
|
| 555 | 566 |
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, |
| 556 | 567 |
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
|
| 557 | 568 |
BasicConstraintsValid: true, |
| 558 |
- }, nil |
|
| 569 |
+ } |
|
| 570 |
+} |
|
| 571 |
+ |
|
| 572 |
+func warnAboutCertificateLifeTime(name string, defaultLifetimeInDays int) {
|
|
| 573 |
+ defaultLifetimeInYears := defaultLifetimeInDays / 365 |
|
| 574 |
+ fmt.Fprintf(os.Stderr, "WARNING: Validity period of the certificate for %q is greater than %d years!\n", name, defaultLifetimeInYears) |
|
| 575 |
+ fmt.Fprintln(os.Stderr, "WARNING: By security reasons it is strongly recommended to change this period and make it smaller!") |
|
| 559 | 576 |
} |
| 560 | 577 |
|
| 561 | 578 |
func signCertificate(template *x509.Certificate, requestKey crypto.PublicKey, issuer *x509.Certificate, issuerKey crypto.PrivateKey) (*x509.Certificate, error) {
|
| ... | ... |
@@ -6,8 +6,11 @@ import ( |
| 6 | 6 |
"crypto/x509/pkix" |
| 7 | 7 |
"fmt" |
| 8 | 8 |
"testing" |
| 9 |
+ "time" |
|
| 9 | 10 |
) |
| 10 | 11 |
|
| 12 |
+const certificateLifetime = 365 * 2 |
|
| 13 |
+ |
|
| 11 | 14 |
func TestCrypto(t *testing.T) {
|
| 12 | 15 |
roots := x509.NewCertPool() |
| 13 | 16 |
intermediates := x509.NewCertPool() |
| ... | ... |
@@ -78,10 +81,7 @@ func buildCA(t *testing.T) (crypto.PrivateKey, *x509.Certificate) {
|
| 78 | 78 |
if err != nil {
|
| 79 | 79 |
t.Fatalf("Unexpected error: %#v", err)
|
| 80 | 80 |
} |
| 81 |
- caTemplate, err := newSigningCertificateTemplate(pkix.Name{CommonName: "CA"})
|
|
| 82 |
- if err != nil {
|
|
| 83 |
- t.Fatalf("Unexpected error: %#v", err)
|
|
| 84 |
- } |
|
| 81 |
+ caTemplate := newSigningCertificateTemplate(pkix.Name{CommonName: "CA"}, certificateLifetime, time.Now)
|
|
| 85 | 82 |
caCrt, err := signCertificate(caTemplate, caPublicKey, caTemplate, caPrivateKey) |
| 86 | 83 |
if err != nil {
|
| 87 | 84 |
t.Fatalf("Unexpected error: %#v", err)
|
| ... | ... |
@@ -94,10 +94,7 @@ func buildIntermediate(t *testing.T, signingKey crypto.PrivateKey, signingCrt *x |
| 94 | 94 |
if err != nil {
|
| 95 | 95 |
t.Fatalf("Unexpected error: %#v", err)
|
| 96 | 96 |
} |
| 97 |
- intermediateTemplate, err := newSigningCertificateTemplate(pkix.Name{CommonName: "Intermediate"})
|
|
| 98 |
- if err != nil {
|
|
| 99 |
- t.Fatalf("Unexpected error: %#v", err)
|
|
| 100 |
- } |
|
| 97 |
+ intermediateTemplate := newSigningCertificateTemplate(pkix.Name{CommonName: "Intermediate"}, certificateLifetime, time.Now)
|
|
| 101 | 98 |
intermediateCrt, err := signCertificate(intermediateTemplate, intermediatePublicKey, signingCrt, signingKey) |
| 102 | 99 |
if err != nil {
|
| 103 | 100 |
t.Fatalf("Unexpected error: %#v", err)
|
| ... | ... |
@@ -113,10 +110,8 @@ func buildServer(t *testing.T, signingKey crypto.PrivateKey, signingCrt *x509.Ce |
| 113 | 113 |
if err != nil {
|
| 114 | 114 |
t.Fatalf("Unexpected error: %#v", err)
|
| 115 | 115 |
} |
| 116 |
- serverTemplate, err := newServerCertificateTemplate(pkix.Name{CommonName: "Server"}, []string{"127.0.0.1", "localhost", "www.example.com"})
|
|
| 117 |
- if err != nil {
|
|
| 118 |
- t.Fatalf("Unexpected error: %#v", err)
|
|
| 119 |
- } |
|
| 116 |
+ hosts := []string{"127.0.0.1", "localhost", "www.example.com"}
|
|
| 117 |
+ serverTemplate := newServerCertificateTemplate(pkix.Name{CommonName: "Server"}, hosts, certificateLifetime, time.Now)
|
|
| 120 | 118 |
serverCrt, err := signCertificate(serverTemplate, serverPublicKey, signingCrt, signingKey) |
| 121 | 119 |
if err != nil {
|
| 122 | 120 |
t.Fatalf("Unexpected error: %#v", err)
|
| ... | ... |
@@ -132,10 +127,7 @@ func buildClient(t *testing.T, signingKey crypto.PrivateKey, signingCrt *x509.Ce |
| 132 | 132 |
if err != nil {
|
| 133 | 133 |
t.Fatalf("Unexpected error: %#v", err)
|
| 134 | 134 |
} |
| 135 |
- clientTemplate, err := newClientCertificateTemplate(pkix.Name{CommonName: "Client"})
|
|
| 136 |
- if err != nil {
|
|
| 137 |
- t.Fatalf("Unexpected error: %#v", err)
|
|
| 138 |
- } |
|
| 135 |
+ clientTemplate := newClientCertificateTemplate(pkix.Name{CommonName: "Client"}, certificateLifetime, time.Now)
|
|
| 139 | 136 |
clientCrt, err := signCertificate(clientTemplate, clientPublicKey, signingCrt, signingKey) |
| 140 | 137 |
if err != nil {
|
| 141 | 138 |
t.Fatalf("Unexpected error: %#v", err)
|
| ... | ... |
@@ -167,11 +159,118 @@ func TestRandomSerialGenerator(t *testing.T) {
|
| 167 | 167 |
generator := &RandomSerialGenerator{}
|
| 168 | 168 |
|
| 169 | 169 |
hostnames := []string{"foo", "bar"}
|
| 170 |
- template, err := newServerCertificateTemplate(pkix.Name{CommonName: hostnames[0]}, hostnames)
|
|
| 171 |
- if err != nil {
|
|
| 172 |
- t.Fatalf("unexpected error: %v", err)
|
|
| 173 |
- } |
|
| 170 |
+ template := newServerCertificateTemplate(pkix.Name{CommonName: hostnames[0]}, hostnames, certificateLifetime, time.Now)
|
|
| 174 | 171 |
if _, err := generator.Next(template); err != nil {
|
| 175 | 172 |
t.Fatalf("unexpected error: %v", err)
|
| 176 | 173 |
} |
| 177 | 174 |
} |
| 175 |
+ |
|
| 176 |
+func TestValidityPeriodOfClientCertificate(t *testing.T) {
|
|
| 177 |
+ currentTime := time.Now() |
|
| 178 |
+ |
|
| 179 |
+ currentFakeTime := func() time.Time {
|
|
| 180 |
+ return currentTime |
|
| 181 |
+ } |
|
| 182 |
+ |
|
| 183 |
+ tests := []struct {
|
|
| 184 |
+ passedExpireDays int |
|
| 185 |
+ realExpireDays int |
|
| 186 |
+ }{
|
|
| 187 |
+ {
|
|
| 188 |
+ passedExpireDays: 100, |
|
| 189 |
+ realExpireDays: 100, |
|
| 190 |
+ }, |
|
| 191 |
+ {
|
|
| 192 |
+ passedExpireDays: 0, |
|
| 193 |
+ realExpireDays: DefaultCertificateLifetimeInDays, |
|
| 194 |
+ }, |
|
| 195 |
+ {
|
|
| 196 |
+ passedExpireDays: -1, |
|
| 197 |
+ realExpireDays: DefaultCertificateLifetimeInDays, |
|
| 198 |
+ }, |
|
| 199 |
+ } |
|
| 200 |
+ |
|
| 201 |
+ for _, test := range tests {
|
|
| 202 |
+ cert := newClientCertificateTemplate(pkix.Name{CommonName: "client"}, test.passedExpireDays, currentFakeTime)
|
|
| 203 |
+ expirationDate := cert.NotAfter |
|
| 204 |
+ expectedExpirationDate := currentTime.Add(time.Duration(test.realExpireDays) * 24 * time.Hour) |
|
| 205 |
+ if expectedExpirationDate != expirationDate {
|
|
| 206 |
+ t.Errorf("expected that client certificate will expire at %v but found %v", expectedExpirationDate, expirationDate)
|
|
| 207 |
+ } |
|
| 208 |
+ } |
|
| 209 |
+} |
|
| 210 |
+ |
|
| 211 |
+func TestValidityPeriodOfServerCertificate(t *testing.T) {
|
|
| 212 |
+ currentTime := time.Now() |
|
| 213 |
+ |
|
| 214 |
+ currentFakeTime := func() time.Time {
|
|
| 215 |
+ return currentTime |
|
| 216 |
+ } |
|
| 217 |
+ |
|
| 218 |
+ tests := []struct {
|
|
| 219 |
+ passedExpireDays int |
|
| 220 |
+ realExpireDays int |
|
| 221 |
+ }{
|
|
| 222 |
+ {
|
|
| 223 |
+ passedExpireDays: 100, |
|
| 224 |
+ realExpireDays: 100, |
|
| 225 |
+ }, |
|
| 226 |
+ {
|
|
| 227 |
+ passedExpireDays: 0, |
|
| 228 |
+ realExpireDays: DefaultCertificateLifetimeInDays, |
|
| 229 |
+ }, |
|
| 230 |
+ {
|
|
| 231 |
+ passedExpireDays: -1, |
|
| 232 |
+ realExpireDays: DefaultCertificateLifetimeInDays, |
|
| 233 |
+ }, |
|
| 234 |
+ } |
|
| 235 |
+ |
|
| 236 |
+ for _, test := range tests {
|
|
| 237 |
+ cert := newServerCertificateTemplate( |
|
| 238 |
+ pkix.Name{CommonName: "server"},
|
|
| 239 |
+ []string{"www.example.com"},
|
|
| 240 |
+ test.passedExpireDays, |
|
| 241 |
+ currentFakeTime, |
|
| 242 |
+ ) |
|
| 243 |
+ expirationDate := cert.NotAfter |
|
| 244 |
+ expectedExpirationDate := currentTime.Add(time.Duration(test.realExpireDays) * 24 * time.Hour) |
|
| 245 |
+ if expectedExpirationDate != expirationDate {
|
|
| 246 |
+ t.Errorf("expected that server certificate will expire at %v but found %v", expectedExpirationDate, expirationDate)
|
|
| 247 |
+ } |
|
| 248 |
+ } |
|
| 249 |
+} |
|
| 250 |
+ |
|
| 251 |
+func TestValidityPeriodOfSigningCertificate(t *testing.T) {
|
|
| 252 |
+ currentTime := time.Now() |
|
| 253 |
+ |
|
| 254 |
+ currentFakeTime := func() time.Time {
|
|
| 255 |
+ return currentTime |
|
| 256 |
+ } |
|
| 257 |
+ |
|
| 258 |
+ tests := []struct {
|
|
| 259 |
+ passedExpireDays int |
|
| 260 |
+ realExpireDays int |
|
| 261 |
+ }{
|
|
| 262 |
+ {
|
|
| 263 |
+ passedExpireDays: 100, |
|
| 264 |
+ realExpireDays: 100, |
|
| 265 |
+ }, |
|
| 266 |
+ {
|
|
| 267 |
+ passedExpireDays: 0, |
|
| 268 |
+ realExpireDays: DefaultCACertificateLifetimeInDays, |
|
| 269 |
+ }, |
|
| 270 |
+ {
|
|
| 271 |
+ passedExpireDays: -1, |
|
| 272 |
+ realExpireDays: DefaultCACertificateLifetimeInDays, |
|
| 273 |
+ }, |
|
| 274 |
+ } |
|
| 275 |
+ |
|
| 276 |
+ for _, test := range tests {
|
|
| 277 |
+ cert := newSigningCertificateTemplate(pkix.Name{CommonName: "CA"}, test.passedExpireDays, currentFakeTime)
|
|
| 278 |
+ expirationDate := cert.NotAfter |
|
| 279 |
+ expectedExpirationDate := currentTime.Add(time.Duration(test.realExpireDays) * 24 * time.Hour) |
|
| 280 |
+ if expectedExpirationDate != expirationDate {
|
|
| 281 |
+ t.Errorf("expected that CA certificate will expire at %v but found %v", expectedExpirationDate, expirationDate)
|
|
| 282 |
+ } |
|
| 283 |
+ } |
|
| 284 |
+} |
| ... | ... |
@@ -23,6 +23,7 @@ import ( |
| 23 | 23 |
|
| 24 | 24 |
"github.com/openshift/origin/pkg/cmd/server/admin" |
| 25 | 25 |
configapi "github.com/openshift/origin/pkg/cmd/server/api" |
| 26 |
+ "github.com/openshift/origin/pkg/cmd/server/crypto" |
|
| 26 | 27 |
"github.com/openshift/origin/pkg/cmd/server/start/kubernetes" |
| 27 | 28 |
"github.com/openshift/origin/pkg/cmd/templates" |
| 28 | 29 |
cmdutil "github.com/openshift/origin/pkg/cmd/util" |
| ... | ... |
@@ -33,6 +34,8 @@ type AllInOneOptions struct {
|
| 33 | 33 |
|
| 34 | 34 |
NodeArgs *NodeArgs |
| 35 | 35 |
|
| 36 |
+ ExpireDays int |
|
| 37 |
+ SignerExpireDays int |
|
| 36 | 38 |
ConfigDir util.StringFlag |
| 37 | 39 |
NodeConfigFile string |
| 38 | 40 |
PrintIP bool |
| ... | ... |
@@ -63,7 +66,14 @@ var allInOneLong = templates.LongDesc(` |
| 63 | 63 |
|
| 64 | 64 |
// NewCommandStartAllInOne provides a CLI handler for 'start' command |
| 65 | 65 |
func NewCommandStartAllInOne(basename string, out, errout io.Writer) (*cobra.Command, *AllInOneOptions) {
|
| 66 |
- options := &AllInOneOptions{Output: out, MasterOptions: &MasterOptions{Output: out}}
|
|
| 66 |
+ options := &AllInOneOptions{
|
|
| 67 |
+ MasterOptions: &MasterOptions{
|
|
| 68 |
+ Output: out, |
|
| 69 |
+ }, |
|
| 70 |
+ ExpireDays: crypto.DefaultCertificateLifetimeInDays, |
|
| 71 |
+ SignerExpireDays: crypto.DefaultCACertificateLifetimeInDays, |
|
| 72 |
+ Output: out, |
|
| 73 |
+ } |
|
| 67 | 74 |
options.MasterOptions.DefaultsFromName(basename) |
| 68 | 75 |
|
| 69 | 76 |
cmds := &cobra.Command{
|
| ... | ... |
@@ -100,6 +110,8 @@ func NewCommandStartAllInOne(basename string, out, errout io.Writer) (*cobra.Com |
| 100 | 100 |
flags.BoolVar(&options.MasterOptions.CreateCertificates, "create-certs", true, "Indicates whether missing certs should be created.") |
| 101 | 101 |
flags.BoolVar(&options.PrintIP, "print-ip", false, "Print the IP that would be used if no master IP is specified and exit.") |
| 102 | 102 |
flags.StringVar(&options.ServiceNetworkCIDR, "portal-net", NewDefaultNetworkArgs().ServiceNetworkCIDR, "The CIDR string representing the network that portal/service IPs will be assigned from. This must not overlap with any IP ranges assigned to nodes for pods.") |
| 103 |
+ flags.IntVar(&options.ExpireDays, "expire-days", options.ExpireDays, "Validity of the certificates in days (defaults to 2 years). WARNING: extending this above default value is highly discouraged.") |
|
| 104 |
+ flags.IntVar(&options.SignerExpireDays, "signer-expire-days", options.SignerExpireDays, "Validity of the CA certificate in days (defaults to 5 years). WARNING: extending this above default value is highly discouraged.") |
|
| 103 | 105 |
|
| 104 | 106 |
masterArgs, nodeArgs, listenArg, imageFormatArgs, _ := GetAllInOneArgs() |
| 105 | 107 |
options.MasterOptions.MasterArgs, options.NodeArgs = masterArgs, nodeArgs |
| ... | ... |
@@ -194,6 +206,13 @@ func (o AllInOneOptions) Validate(args []string) error {
|
| 194 | 194 |
return errors.New("all-in-one cannot start with a remote Kubernetes server, start the master instead")
|
| 195 | 195 |
} |
| 196 | 196 |
|
| 197 |
+ if o.ExpireDays < 0 {
|
|
| 198 |
+ return errors.New("expire-days must be valid number of days")
|
|
| 199 |
+ } |
|
| 200 |
+ if o.SignerExpireDays < 0 {
|
|
| 201 |
+ return errors.New("signer-expire-days must be valid number of days")
|
|
| 202 |
+ } |
|
| 203 |
+ |
|
| 197 | 204 |
return nil |
| 198 | 205 |
} |
| 199 | 206 |
|
| ... | ... |
@@ -268,11 +287,18 @@ func (o AllInOneOptions) StartAllInOne() error {
|
| 268 | 268 |
return nil |
| 269 | 269 |
} |
| 270 | 270 |
masterOptions := *o.MasterOptions |
| 271 |
+ masterOptions.ExpireDays = o.ExpireDays |
|
| 272 |
+ masterOptions.SignerExpireDays = o.SignerExpireDays |
|
| 271 | 273 |
if err := masterOptions.RunMaster(); err != nil {
|
| 272 | 274 |
return err |
| 273 | 275 |
} |
| 274 | 276 |
|
| 275 |
- nodeOptions := NodeOptions{o.NodeArgs, o.NodeConfigFile, o.MasterOptions.Output}
|
|
| 277 |
+ nodeOptions := NodeOptions{
|
|
| 278 |
+ NodeArgs: o.NodeArgs, |
|
| 279 |
+ ExpireDays: o.ExpireDays, |
|
| 280 |
+ ConfigFile: o.NodeConfigFile, |
|
| 281 |
+ Output: o.MasterOptions.Output, |
|
| 282 |
+ } |
|
| 276 | 283 |
if err := nodeOptions.RunNode(); err != nil {
|
| 277 | 284 |
return err |
| 278 | 285 |
} |
| ... | ... |
@@ -33,6 +33,7 @@ import ( |
| 33 | 33 |
configapilatest "github.com/openshift/origin/pkg/cmd/server/api/latest" |
| 34 | 34 |
"github.com/openshift/origin/pkg/cmd/server/api/validation" |
| 35 | 35 |
"github.com/openshift/origin/pkg/cmd/server/bootstrappolicy" |
| 36 |
+ "github.com/openshift/origin/pkg/cmd/server/crypto" |
|
| 36 | 37 |
"github.com/openshift/origin/pkg/cmd/server/etcd" |
| 37 | 38 |
"github.com/openshift/origin/pkg/cmd/server/etcd/etcdserver" |
| 38 | 39 |
"github.com/openshift/origin/pkg/cmd/server/kubernetes" |
| ... | ... |
@@ -49,6 +50,8 @@ type MasterOptions struct {
|
| 49 | 49 |
MasterArgs *MasterArgs |
| 50 | 50 |
|
| 51 | 51 |
CreateCertificates bool |
| 52 |
+ ExpireDays int |
|
| 53 |
+ SignerExpireDays int |
|
| 52 | 54 |
ConfigFile string |
| 53 | 55 |
Output io.Writer |
| 54 | 56 |
DisabledFeatures []string |
| ... | ... |
@@ -81,7 +84,11 @@ var masterLong = templates.LongDesc(` |
| 81 | 81 |
|
| 82 | 82 |
// NewCommandStartMaster provides a CLI handler for 'start master' command |
| 83 | 83 |
func NewCommandStartMaster(basename string, out, errout io.Writer) (*cobra.Command, *MasterOptions) {
|
| 84 |
- options := &MasterOptions{Output: out}
|
|
| 84 |
+ options := &MasterOptions{
|
|
| 85 |
+ ExpireDays: crypto.DefaultCertificateLifetimeInDays, |
|
| 86 |
+ SignerExpireDays: crypto.DefaultCACertificateLifetimeInDays, |
|
| 87 |
+ Output: out, |
|
| 88 |
+ } |
|
| 85 | 89 |
options.DefaultsFromName(basename) |
| 86 | 90 |
|
| 87 | 91 |
cmd := &cobra.Command{
|
| ... | ... |
@@ -127,6 +134,8 @@ func NewCommandStartMaster(basename string, out, errout io.Writer) (*cobra.Comma |
| 127 | 127 |
flags.Var(options.MasterArgs.ConfigDir, "write-config", "Directory to write an initial config into. After writing, exit without starting the server.") |
| 128 | 128 |
flags.StringVar(&options.ConfigFile, "config", "", "Location of the master configuration file to run from. When running from a configuration file, all other command-line arguments are ignored.") |
| 129 | 129 |
flags.BoolVar(&options.CreateCertificates, "create-certs", true, "Indicates whether missing certs should be created") |
| 130 |
+ flags.IntVar(&options.ExpireDays, "expire-days", options.ExpireDays, "Validity of the certificates in days (defaults to 2 years). WARNING: extending this above default value is highly discouraged.") |
|
| 131 |
+ flags.IntVar(&options.SignerExpireDays, "signer-expire-days", options.SignerExpireDays, "Validity of the CA certificate in days (defaults to 5 years). WARNING: extending this above default value is highly discouraged.") |
|
| 130 | 132 |
|
| 131 | 133 |
BindMasterArgs(options.MasterArgs, flags, "") |
| 132 | 134 |
BindListenArg(options.MasterArgs.ListenArg, flags, "") |
| ... | ... |
@@ -168,6 +177,13 @@ func (o MasterOptions) Validate(args []string) error {
|
| 168 | 168 |
|
| 169 | 169 |
} |
| 170 | 170 |
|
| 171 |
+ if o.ExpireDays < 0 {
|
|
| 172 |
+ return errors.New("expire-days must be valid number of days")
|
|
| 173 |
+ } |
|
| 174 |
+ if o.SignerExpireDays < 0 {
|
|
| 175 |
+ return errors.New("signer-expire-days must be valid number of days")
|
|
| 176 |
+ } |
|
| 177 |
+ |
|
| 171 | 178 |
return nil |
| 172 | 179 |
} |
| 173 | 180 |
|
| ... | ... |
@@ -320,6 +336,8 @@ func (o MasterOptions) CreateCerts() error {
|
| 320 | 320 |
mintAllCertsOptions := admin.CreateMasterCertsOptions{
|
| 321 | 321 |
CertDir: o.MasterArgs.ConfigDir.Value(), |
| 322 | 322 |
SignerName: signerName, |
| 323 |
+ ExpireDays: o.ExpireDays, |
|
| 324 |
+ SignerExpireDays: o.SignerExpireDays, |
|
| 323 | 325 |
Hostnames: hostnames.List(), |
| 324 | 326 |
APIServerURL: masterAddr.String(), |
| 325 | 327 |
APIServerCAFiles: o.MasterArgs.APIServerCAFiles, |
| ... | ... |
@@ -19,6 +19,7 @@ import ( |
| 19 | 19 |
configapi "github.com/openshift/origin/pkg/cmd/server/api" |
| 20 | 20 |
configapilatest "github.com/openshift/origin/pkg/cmd/server/api/latest" |
| 21 | 21 |
"github.com/openshift/origin/pkg/cmd/server/api/validation" |
| 22 |
+ "github.com/openshift/origin/pkg/cmd/server/crypto" |
|
| 22 | 23 |
"github.com/openshift/origin/pkg/cmd/templates" |
| 23 | 24 |
cmdutil "github.com/openshift/origin/pkg/cmd/util" |
| 24 | 25 |
"github.com/openshift/origin/pkg/cmd/util/docker" |
| ... | ... |
@@ -28,7 +29,8 @@ import ( |
| 28 | 28 |
) |
| 29 | 29 |
|
| 30 | 30 |
type NodeOptions struct {
|
| 31 |
- NodeArgs *NodeArgs |
|
| 31 |
+ NodeArgs *NodeArgs |
|
| 32 |
+ ExpireDays int |
|
| 32 | 33 |
|
| 33 | 34 |
ConfigFile string |
| 34 | 35 |
Output io.Writer |
| ... | ... |
@@ -46,7 +48,10 @@ var nodeLong = templates.LongDesc(` |
| 46 | 46 |
|
| 47 | 47 |
// NewCommandStartNode provides a CLI handler for 'start node' command |
| 48 | 48 |
func NewCommandStartNode(basename string, out, errout io.Writer) (*cobra.Command, *NodeOptions) {
|
| 49 |
- options := &NodeOptions{Output: out}
|
|
| 49 |
+ options := &NodeOptions{
|
|
| 50 |
+ ExpireDays: crypto.DefaultCertificateLifetimeInDays, |
|
| 51 |
+ Output: out, |
|
| 52 |
+ } |
|
| 50 | 53 |
|
| 51 | 54 |
cmd := &cobra.Command{
|
| 52 | 55 |
Use: "node", |
| ... | ... |
@@ -60,6 +65,7 @@ func NewCommandStartNode(basename string, out, errout io.Writer) (*cobra.Command |
| 60 | 60 |
flags := cmd.Flags() |
| 61 | 61 |
|
| 62 | 62 |
flags.StringVar(&options.ConfigFile, "config", "", "Location of the node configuration file to run from. When running from a configuration file, all other command-line arguments are ignored.") |
| 63 |
+ flags.IntVar(&options.ExpireDays, "expire-days", options.ExpireDays, "Validity of the certificates in days (defaults to 2 years). WARNING: extending this above default value is highly discouraged.") |
|
| 63 | 64 |
|
| 64 | 65 |
options.NodeArgs = NewDefaultNodeArgs() |
| 65 | 66 |
|
| ... | ... |
@@ -137,6 +143,10 @@ func (o NodeOptions) Validate(args []string) error {
|
| 137 | 137 |
return errors.New("no arguments are supported for start node")
|
| 138 | 138 |
} |
| 139 | 139 |
|
| 140 |
+ if o.ExpireDays < 0 {
|
|
| 141 |
+ return errors.New("expire-days must be valid number of days")
|
|
| 142 |
+ } |
|
| 143 |
+ |
|
| 140 | 144 |
if o.IsWriteConfigOnly() {
|
| 141 | 145 |
if o.IsRunFromConfig() {
|
| 142 | 146 |
return errors.New("--config may not be set if you're only writing the config")
|
| ... | ... |
@@ -264,6 +274,7 @@ func (o NodeOptions) CreateNodeConfig() error {
|
| 264 | 264 |
APIServerCAFiles: []string{admin.DefaultCABundleFile(o.NodeArgs.MasterCertDir)},
|
| 265 | 265 |
|
| 266 | 266 |
NodeClientCAFile: getSignerOptions.CertFile, |
| 267 |
+ ExpireDays: o.ExpireDays, |
|
| 267 | 268 |
Output: cmdutil.NewGLogWriterV(3), |
| 268 | 269 |
} |
| 269 | 270 |
|
| ... | ... |
@@ -196,7 +196,8 @@ func (sc *ServiceServingCertController) syncService(key string) error {
|
| 196 | 196 |
|
| 197 | 197 |
dnsName := service.Name + "." + service.Namespace + ".svc" |
| 198 | 198 |
fqDNSName := dnsName + "." + sc.dnsSuffix |
| 199 |
- servingCert, err := sc.ca.MakeServerCert(sets.NewString(dnsName, fqDNSName)) |
|
| 199 |
+ certificateLifetime := 365 * 2 // 2 years |
|
| 200 |
+ servingCert, err := sc.ca.MakeServerCert(sets.NewString(dnsName, fqDNSName), certificateLifetime) |
|
| 200 | 201 |
if err != nil {
|
| 201 | 202 |
return err |
| 202 | 203 |
} |
| ... | ... |
@@ -233,7 +233,8 @@ func (sc *ServiceServingCertUpdateController) syncSecret(key string) error {
|
| 233 | 233 |
|
| 234 | 234 |
dnsName := secret.Annotations[ServiceNameAnnotation] + "." + secret.Namespace + ".svc" |
| 235 | 235 |
fqDNSName := dnsName + "." + sc.dnsSuffix |
| 236 |
- servingCert, err := sc.ca.MakeServerCert(sets.NewString(dnsName, fqDNSName)) |
|
| 236 |
+ certificateLifetime := 365 * 2 // 2 years |
|
| 237 |
+ servingCert, err := sc.ca.MakeServerCert(sets.NewString(dnsName, fqDNSName), certificateLifetime) |
|
| 237 | 238 |
if err != nil {
|
| 238 | 239 |
return err |
| 239 | 240 |
} |
| 240 | 241 |
new file mode 100755 |
| ... | ... |
@@ -0,0 +1,405 @@ |
| 0 |
+#!/bin/bash |
|
| 1 |
+ |
|
| 2 |
+source "$(dirname "${BASH_SOURCE}")/../../hack/lib/init.sh"
|
|
| 3 |
+trap os::test::junit::reconcile_output EXIT |
|
| 4 |
+ |
|
| 5 |
+os::test::junit::declare_suite_start "cmd/admin/certs-validation" |
|
| 6 |
+ |
|
| 7 |
+CERT_DIR="${BASETMPDIR}/certs"
|
|
| 8 |
+mkdir -p -- "${CERT_DIR}"
|
|
| 9 |
+ |
|
| 10 |
+pushd "${CERT_DIR}" >/dev/null
|
|
| 11 |
+ |
|
| 12 |
+# oadm ca create-signer-cert should generate certificate for 5 years by default |
|
| 13 |
+os::cmd::expect_success_and_not_text \ |
|
| 14 |
+ "oadm ca create-signer-cert --cert='${CERT_DIR}/ca.crt' \
|
|
| 15 |
+ --key='${CERT_DIR}/ca.key' \
|
|
| 16 |
+ --serial='${CERT_DIR}/ca.serial.txt' \
|
|
| 17 |
+ --overwrite=true" \ |
|
| 18 |
+ 'WARNING: .* is greater than 5 years' |
|
| 19 |
+ |
|
| 20 |
+expected_year="$(TZ=GMT date -d "+$((365*5)) days" +'%Y')" |
|
| 21 |
+ |
|
| 22 |
+os::cmd::expect_success_and_text \ |
|
| 23 |
+ "openssl x509 -in '${CERT_DIR}/ca.crt' -enddate -noout | awk '{print \$4}'" \
|
|
| 24 |
+ "${expected_year}"
|
|
| 25 |
+ |
|
| 26 |
+# oadm ca create-signer-cert should generate certificate with specified number of days and show warning |
|
| 27 |
+os::cmd::expect_success_and_text \ |
|
| 28 |
+ "oadm ca create-signer-cert --cert='${CERT_DIR}/ca.crt' \
|
|
| 29 |
+ --key='${CERT_DIR}/ca.key' \
|
|
| 30 |
+ --serial='${CERT_DIR}/ca.serial.txt' \
|
|
| 31 |
+ --overwrite=true \ |
|
| 32 |
+ --expire-days=$((365*6))" \ |
|
| 33 |
+ 'WARNING: .* is greater than 5 years' |
|
| 34 |
+ |
|
| 35 |
+expected_year="$(TZ=GMT date -d "+$((365*6)) days" +'%Y')" |
|
| 36 |
+ |
|
| 37 |
+os::cmd::expect_success_and_text \ |
|
| 38 |
+ "openssl x509 -in '${CERT_DIR}/ca.crt' -enddate -noout | awk '{print \$4}'" \
|
|
| 39 |
+ "${expected_year}"
|
|
| 40 |
+ |
|
| 41 |
+ |
|
| 42 |
+# oadm create-node-config should generate certificates for 2 years by default |
|
| 43 |
+# NOTE: tests order is important here because this test uses CA certificate that was generated before |
|
| 44 |
+ |
|
| 45 |
+# we have to remove these files otherwise oadm create-node-config won't generate new ones |
|
| 46 |
+rm -f -- ${CERT_DIR}/master-client.crt ${CERT_DIR}/server.crt
|
|
| 47 |
+ |
|
| 48 |
+os::cmd::expect_success_and_not_text \ |
|
| 49 |
+ "oadm create-node-config \ |
|
| 50 |
+ --node-dir='${CERT_DIR}' \
|
|
| 51 |
+ --node=example \ |
|
| 52 |
+ --hostnames=example.org \ |
|
| 53 |
+ --certificate-authority='${CERT_DIR}/ca.crt' \
|
|
| 54 |
+ --node-client-certificate-authority='${CERT_DIR}/ca.crt' \
|
|
| 55 |
+ --signer-cert='${CERT_DIR}/ca.crt' \
|
|
| 56 |
+ --signer-key='${CERT_DIR}/ca.key' \
|
|
| 57 |
+ --signer-serial='${CERT_DIR}/ca.serial.txt'" \
|
|
| 58 |
+ 'WARNING: .* is greater than 2 years' |
|
| 59 |
+ |
|
| 60 |
+expected_year="$(TZ=GMT date -d "+$((365*2)) days" +'%Y')" |
|
| 61 |
+for CERT_FILE in master-client.crt server.crt; do |
|
| 62 |
+ os::cmd::expect_success_and_text \ |
|
| 63 |
+ "openssl x509 -in '${CERT_DIR}/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 64 |
+ "${expected_year}"
|
|
| 65 |
+done |
|
| 66 |
+ |
|
| 67 |
+# oadm create-node-config should generate certificates with specified number of days and show warning |
|
| 68 |
+# NOTE: tests order is important here because this test uses CA certificate that was generated before |
|
| 69 |
+ |
|
| 70 |
+# we have to remove these files otherwise oadm create-node-config won't generate new ones |
|
| 71 |
+rm -f -- ${CERT_DIR}/master-client.crt ${CERT_DIR}/server.crt
|
|
| 72 |
+ |
|
| 73 |
+os::cmd::expect_success_and_text \ |
|
| 74 |
+ "oadm create-node-config \ |
|
| 75 |
+ --node-dir='${CERT_DIR}' \
|
|
| 76 |
+ --node=example \ |
|
| 77 |
+ --hostnames=example.org \ |
|
| 78 |
+ --certificate-authority='${CERT_DIR}/ca.crt' \
|
|
| 79 |
+ --node-client-certificate-authority='${CERT_DIR}/ca.crt' \
|
|
| 80 |
+ --signer-cert='${CERT_DIR}/ca.crt' \
|
|
| 81 |
+ --signer-key='${CERT_DIR}/ca.key' \
|
|
| 82 |
+ --signer-serial='${CERT_DIR}/ca.serial.txt' \
|
|
| 83 |
+ --expire-days=$((365*3))" \ |
|
| 84 |
+ 'WARNING: .* is greater than 2 years' |
|
| 85 |
+ |
|
| 86 |
+expected_year="$(TZ=GMT date -d "+$((365*3)) days" +'%Y')" |
|
| 87 |
+ |
|
| 88 |
+for CERT_FILE in master-client.crt server.crt; do |
|
| 89 |
+ os::cmd::expect_success_and_text \ |
|
| 90 |
+ "openssl x509 -in '${CERT_DIR}/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 91 |
+ "${expected_year}"
|
|
| 92 |
+done |
|
| 93 |
+ |
|
| 94 |
+ |
|
| 95 |
+# oadm create-api-client-config should generate certificates for 2 years by default |
|
| 96 |
+# NOTE: tests order is important here because this test uses CA certificate that was generated before |
|
| 97 |
+ |
|
| 98 |
+os::cmd::expect_success_and_not_text \ |
|
| 99 |
+ "oadm create-api-client-config \ |
|
| 100 |
+ --client-dir='${CERT_DIR}' \
|
|
| 101 |
+ --user=test-user \ |
|
| 102 |
+ --certificate-authority='${CERT_DIR}/ca.crt' \
|
|
| 103 |
+ --signer-cert='${CERT_DIR}/ca.crt' \
|
|
| 104 |
+ --signer-key='${CERT_DIR}/ca.key' \
|
|
| 105 |
+ --signer-serial='${CERT_DIR}/ca.serial.txt'" \
|
|
| 106 |
+ 'WARNING: .* is greater than 2 years' |
|
| 107 |
+ |
|
| 108 |
+expected_year="$(TZ=GMT date -d "+$((365*2)) days" +'%Y')" |
|
| 109 |
+os::cmd::expect_success_and_text \ |
|
| 110 |
+ "openssl x509 -in '${CERT_DIR}/test-user.crt' -enddate -noout | awk '{print \$4}'" \
|
|
| 111 |
+ "${expected_year}"
|
|
| 112 |
+ |
|
| 113 |
+# oadm create-api-client-config should generate certificates with specified number of days and show warning |
|
| 114 |
+# NOTE: tests order is important here because this test uses CA certificate that was generated before |
|
| 115 |
+ |
|
| 116 |
+os::cmd::expect_success_and_text \ |
|
| 117 |
+ "oadm create-api-client-config \ |
|
| 118 |
+ --client-dir='${CERT_DIR}' \
|
|
| 119 |
+ --user=test-user \ |
|
| 120 |
+ --certificate-authority='${CERT_DIR}/ca.crt' \
|
|
| 121 |
+ --signer-cert='${CERT_DIR}/ca.crt' \
|
|
| 122 |
+ --signer-key='${CERT_DIR}/ca.key' \
|
|
| 123 |
+ --signer-serial='${CERT_DIR}/ca.serial.txt' \
|
|
| 124 |
+ --expire-days=$((365*3))" \ |
|
| 125 |
+ 'WARNING: .* is greater than 2 years' |
|
| 126 |
+ |
|
| 127 |
+expected_year="$(TZ=GMT date -d "+$((365*3)) days" +'%Y')" |
|
| 128 |
+os::cmd::expect_success_and_text \ |
|
| 129 |
+ "openssl x509 -in '${CERT_DIR}/test-user.crt' -enddate -noout | awk '{print \$4}'" \
|
|
| 130 |
+ "${expected_year}"
|
|
| 131 |
+ |
|
| 132 |
+ |
|
| 133 |
+# oadm ca create-server-cert should generate certificate for 2 years by default |
|
| 134 |
+# NOTE: tests order is important here because this test uses CA certificate that was generated before |
|
| 135 |
+os::cmd::expect_success_and_not_text \ |
|
| 136 |
+ "oadm ca create-server-cert --signer-cert='${CERT_DIR}/ca.crt' \
|
|
| 137 |
+ --signer-key='${CERT_DIR}/ca.key' \
|
|
| 138 |
+ --signer-serial='${CERT_DIR}/ca.serial.txt' \
|
|
| 139 |
+ --overwrite=true \ |
|
| 140 |
+ --hostnames=example.org \ |
|
| 141 |
+ --cert='${CERT_DIR}/example.org.crt' \
|
|
| 142 |
+ --key='${CERT_DIR}/example.org.key'" \
|
|
| 143 |
+ 'WARNING: .* is greater than 2 years' |
|
| 144 |
+ |
|
| 145 |
+expected_year="$(TZ=GMT date -d "+$((365*2)) days" +'%Y')" |
|
| 146 |
+ |
|
| 147 |
+os::cmd::expect_success_and_text \ |
|
| 148 |
+ "openssl x509 -in '${CERT_DIR}/example.org.crt' -enddate -noout | awk '{print \$4}'" \
|
|
| 149 |
+ "${expected_year}"
|
|
| 150 |
+ |
|
| 151 |
+# oadm ca create-server-cert should generate certificate with specified number of days and show warning |
|
| 152 |
+# NOTE: tests order is important here because this test uses CA certificate that was generated before |
|
| 153 |
+os::cmd::expect_success_and_text \ |
|
| 154 |
+ "oadm ca create-server-cert --signer-cert='${CERT_DIR}/ca.crt' \
|
|
| 155 |
+ --signer-key='${CERT_DIR}/ca.key' \
|
|
| 156 |
+ --signer-serial='${CERT_DIR}/ca.serial.txt' \
|
|
| 157 |
+ --overwrite=true --hostnames=example.org \ |
|
| 158 |
+ --cert='${CERT_DIR}/example.org.crt' \
|
|
| 159 |
+ --key='${CERT_DIR}/example.org.key' \
|
|
| 160 |
+ --expire-days=$((365*3))" \ |
|
| 161 |
+ 'WARNING: .* is greater than 2 years' |
|
| 162 |
+ |
|
| 163 |
+expected_year="$(TZ=GMT date -d "+$((365*3)) days" +'%Y')" |
|
| 164 |
+ |
|
| 165 |
+os::cmd::expect_success_and_text \ |
|
| 166 |
+ "openssl x509 -in '${CERT_DIR}/example.org.crt' -enddate -noout | awk '{print \$4}'" \
|
|
| 167 |
+ "${expected_year}"
|
|
| 168 |
+ |
|
| 169 |
+# oadm ca create-master-certs should generate certificates for 2 years and CA for 5 years by default |
|
| 170 |
+os::cmd::expect_success_and_not_text \ |
|
| 171 |
+ "oadm ca create-master-certs --cert-dir='${CERT_DIR}' \
|
|
| 172 |
+ --hostnames=example.org \ |
|
| 173 |
+ --overwrite=true" \ |
|
| 174 |
+ 'WARNING: .* is greater than' |
|
| 175 |
+ |
|
| 176 |
+expected_ca_year="$(TZ=GMT date -d "+$((365*5)) days" +'%Y')" |
|
| 177 |
+for CERT_FILE in ca.crt ca-bundle.crt service-signer.crt; do |
|
| 178 |
+ os::cmd::expect_success_and_text \ |
|
| 179 |
+ "openssl x509 -in '${CERT_DIR}/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 180 |
+ "${expected_ca_year}"
|
|
| 181 |
+done |
|
| 182 |
+ |
|
| 183 |
+expected_year="$(TZ=GMT date -d "+$((365*2)) days" +'%Y')" |
|
| 184 |
+for CERT_FILE in admin.crt {master,etcd}.server.crt master.{etcd,kubelet,proxy}-client.crt openshift-{master,registry,router}.crt; do
|
|
| 185 |
+ os::cmd::expect_success_and_text \ |
|
| 186 |
+ "openssl x509 -in '${CERT_DIR}/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 187 |
+ "${expected_year}"
|
|
| 188 |
+done |
|
| 189 |
+ |
|
| 190 |
+# oadm ca create-master-certs should generate certificates with specified number of days and show warnings |
|
| 191 |
+os::cmd::expect_success_and_text \ |
|
| 192 |
+ "oadm ca create-master-certs --cert-dir='${CERT_DIR}' \
|
|
| 193 |
+ --hostnames=example.org \ |
|
| 194 |
+ --overwrite=true \ |
|
| 195 |
+ --expire-days=$((365*3)) \ |
|
| 196 |
+ --signer-expire-days=$((365*6))" \ |
|
| 197 |
+ 'WARNING: .* is greater than' |
|
| 198 |
+ |
|
| 199 |
+expected_ca_year="$(TZ=GMT date -d "+$((365*6)) days" +'%Y')" |
|
| 200 |
+for CERT_FILE in ca.crt ca-bundle.crt service-signer.crt; do |
|
| 201 |
+ os::cmd::expect_success_and_text \ |
|
| 202 |
+ "openssl x509 -in '${CERT_DIR}/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 203 |
+ "${expected_ca_year}"
|
|
| 204 |
+done |
|
| 205 |
+ |
|
| 206 |
+expected_year="$(TZ=GMT date -d "+$((365*3)) days" +'%Y')" |
|
| 207 |
+for CERT_FILE in admin.crt {master,etcd}.server.crt master.{etcd,kubelet,proxy}-client.crt openshift-{master,registry,router}.crt; do
|
|
| 208 |
+ os::cmd::expect_success_and_text \ |
|
| 209 |
+ "openssl x509 -in '${CERT_DIR}/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 210 |
+ "${expected_year}"
|
|
| 211 |
+done |
|
| 212 |
+ |
|
| 213 |
+# Preparation for "openshift start node" tests |
|
| 214 |
+# NOTE: tests order is important here because this test uses client and CA certificates that were generated before |
|
| 215 |
+ |
|
| 216 |
+# Pre-create directory with certificates because "openshift start node" doesn't have options to specify |
|
| 217 |
+# alternative path to the certificates |
|
| 218 |
+mkdir -p -- "${CERT_DIR}/start-node/openshift.local.config/master"
|
|
| 219 |
+cp "${CERT_DIR}/ca-bundle.crt" \
|
|
| 220 |
+ "${CERT_DIR}/ca.crt" \
|
|
| 221 |
+ "${CERT_DIR}/ca.key" \
|
|
| 222 |
+ "${CERT_DIR}/ca.serial.txt" \
|
|
| 223 |
+ "${CERT_DIR}/start-node/openshift.local.config/master"
|
|
| 224 |
+ |
|
| 225 |
+# Pre-create kubeconfig that is required by "openshift start node" |
|
| 226 |
+oadm create-kubeconfig \ |
|
| 227 |
+ --client-certificate="${CERT_DIR}/master-client.crt" \
|
|
| 228 |
+ --client-key="${CERT_DIR}/master-client.key" \
|
|
| 229 |
+ --certificate-authority="${CERT_DIR}/ca.crt" \
|
|
| 230 |
+ --kubeconfig="${CERT_DIR}/start-node/cert-test.kubeconfig"
|
|
| 231 |
+ |
|
| 232 |
+# openshift start node should generate certificates for 2 years by default |
|
| 233 |
+pushd start-node >/dev/null |
|
| 234 |
+ |
|
| 235 |
+# we have to remove these files otherwise openshift start node won't generate new ones |
|
| 236 |
+rm -rf openshift.local.config/node/ |
|
| 237 |
+ |
|
| 238 |
+os::cmd::expect_failure_and_not_text \ |
|
| 239 |
+ "timeout 30 openshift start node \ |
|
| 240 |
+ --kubeconfig='${CERT_DIR}/start-node/cert-test.kubeconfig' \
|
|
| 241 |
+ --volume-dir='${CERT_DIR}/volumes'" \
|
|
| 242 |
+ 'WARNING: .* is greater than' |
|
| 243 |
+ |
|
| 244 |
+expected_year="$(TZ=GMT date -d "+$((365*2)) days" +'%Y')" |
|
| 245 |
+for CERT_FILE in master-client.crt server.crt; do |
|
| 246 |
+ os::cmd::expect_success_and_text \ |
|
| 247 |
+ "openssl x509 -in '${CERT_DIR}/start-node/openshift.local.config/node/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 248 |
+ "${expected_year}"
|
|
| 249 |
+done |
|
| 250 |
+ |
|
| 251 |
+popd >/dev/null |
|
| 252 |
+ |
|
| 253 |
+ |
|
| 254 |
+# openshift start node should generate certificates with specified number of days and show warning |
|
| 255 |
+# NOTE: tests order is important here because this test uses client and CA certificates that were generated before |
|
| 256 |
+pushd start-node >/dev/null |
|
| 257 |
+ |
|
| 258 |
+# we have to remove these files otherwise openshift start node won't generate new ones |
|
| 259 |
+rm -rf openshift.local.config/node/ |
|
| 260 |
+ |
|
| 261 |
+os::cmd::expect_failure_and_text \ |
|
| 262 |
+ "timeout 30 openshift start node \ |
|
| 263 |
+ --kubeconfig='${CERT_DIR}/start-node/cert-test.kubeconfig' \
|
|
| 264 |
+ --volume-dir='${CERT_DIR}/volumes' \
|
|
| 265 |
+ --expire-days=$((365*3))" \ |
|
| 266 |
+ 'WARNING: .* is greater than' |
|
| 267 |
+ |
|
| 268 |
+expected_year="$(TZ=GMT date -d "+$((365*3)) days" +'%Y')" |
|
| 269 |
+for CERT_FILE in master-client.crt server.crt; do |
|
| 270 |
+ os::cmd::expect_success_and_text \ |
|
| 271 |
+ "openssl x509 -in '${CERT_DIR}/start-node/openshift.local.config/node/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 272 |
+ "${expected_year}"
|
|
| 273 |
+done |
|
| 274 |
+ |
|
| 275 |
+popd >/dev/null |
|
| 276 |
+ |
|
| 277 |
+ |
|
| 278 |
+# openshift start master should generate certificates for 2 years and CA for 5 years by default |
|
| 279 |
+ |
|
| 280 |
+# we have to remove these files otherwise openshift start master won't generate new ones |
|
| 281 |
+rm -rf start-master |
|
| 282 |
+mkdir -p start-master |
|
| 283 |
+ |
|
| 284 |
+os::cmd::expect_success_and_not_text \ |
|
| 285 |
+ "timeout 30 openshift start master --write-config='${CERT_DIR}/start-master'" \
|
|
| 286 |
+ 'WARNING: .* is greater than' |
|
| 287 |
+ |
|
| 288 |
+expected_ca_year="$(TZ=GMT date -d "+$((365*5)) days" +'%Y')" |
|
| 289 |
+for CERT_FILE in ca.crt ca-bundle.crt service-signer.crt; do |
|
| 290 |
+ os::cmd::expect_success_and_text \ |
|
| 291 |
+ "openssl x509 -in '${CERT_DIR}/start-master/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 292 |
+ "${expected_ca_year}"
|
|
| 293 |
+done |
|
| 294 |
+ |
|
| 295 |
+expected_year="$(TZ=GMT date -d "+$((365*2)) days" +'%Y')" |
|
| 296 |
+for CERT_FILE in admin.crt {master,etcd}.server.crt master.{etcd,kubelet,proxy}-client.crt openshift-{master,registry,router}.crt; do
|
|
| 297 |
+ os::cmd::expect_success_and_text \ |
|
| 298 |
+ "openssl x509 -in '${CERT_DIR}/start-master/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 299 |
+ "${expected_year}"
|
|
| 300 |
+done |
|
| 301 |
+ |
|
| 302 |
+# openshift start master should generate certificates with specified number of days and show warnings |
|
| 303 |
+ |
|
| 304 |
+# we have to remove these files otherwise openshift start master won't generate new ones |
|
| 305 |
+rm -rf start-master |
|
| 306 |
+mkdir -p start-master |
|
| 307 |
+ |
|
| 308 |
+os::cmd::expect_success_and_text \ |
|
| 309 |
+ "timeout 30 openshift start master --write-config='${CERT_DIR}/start-master' \
|
|
| 310 |
+ --expire-days=$((365*3)) \ |
|
| 311 |
+ --signer-expire-days=$((365*6))" \ |
|
| 312 |
+ 'WARNING: .* is greater than' |
|
| 313 |
+ |
|
| 314 |
+expected_ca_year="$(TZ=GMT date -d "+$((365*6)) days" +'%Y')" |
|
| 315 |
+for CERT_FILE in ca.crt ca-bundle.crt service-signer.crt; do |
|
| 316 |
+ os::cmd::expect_success_and_text \ |
|
| 317 |
+ "openssl x509 -in '${CERT_DIR}/start-master/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 318 |
+ "${expected_ca_year}"
|
|
| 319 |
+done |
|
| 320 |
+ |
|
| 321 |
+expected_year="$(TZ=GMT date -d "+$((365*3)) days" +'%Y')" |
|
| 322 |
+for CERT_FILE in admin.crt {master,etcd}.server.crt master.{etcd,kubelet,proxy}-client.crt openshift-{master,registry,router}.crt; do
|
|
| 323 |
+ os::cmd::expect_success_and_text \ |
|
| 324 |
+ "openssl x509 -in '${CERT_DIR}/start-master/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 325 |
+ "${expected_year}"
|
|
| 326 |
+done |
|
| 327 |
+ |
|
| 328 |
+ |
|
| 329 |
+# openshift start should generate certificates for 2 years and CA for 5 years by default |
|
| 330 |
+ |
|
| 331 |
+# we have to remove these files otherwise openshift start won't generate new ones |
|
| 332 |
+rm -rf start-all |
|
| 333 |
+mkdir -p start-all |
|
| 334 |
+ |
|
| 335 |
+pushd start-all >/dev/null |
|
| 336 |
+os::cmd::expect_success_and_not_text \ |
|
| 337 |
+ "timeout 30 openshift start --write-config='${CERT_DIR}/start-all' \
|
|
| 338 |
+ --hostname=example.org" \ |
|
| 339 |
+ 'WARNING: .* is greater than' |
|
| 340 |
+ |
|
| 341 |
+expected_ca_year="$(TZ=GMT date -d "+$((365*5)) days" +'%Y')" |
|
| 342 |
+for CERT_FILE in ca.crt ca-bundle.crt service-signer.crt; do |
|
| 343 |
+ os::cmd::expect_success_and_text \ |
|
| 344 |
+ "openssl x509 -in '${CERT_DIR}/start-all/master/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 345 |
+ "${expected_ca_year}"
|
|
| 346 |
+done |
|
| 347 |
+ |
|
| 348 |
+expected_year="$(TZ=GMT date -d "+$((365*2)) days" +'%Y')" |
|
| 349 |
+for CERT_FILE in admin.crt {master,etcd}.server.crt master.{etcd,kubelet,proxy}-client.crt openshift-{master,registry,router}.crt; do
|
|
| 350 |
+ os::cmd::expect_success_and_text \ |
|
| 351 |
+ "openssl x509 -in '${CERT_DIR}/start-all/master/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 352 |
+ "${expected_year}"
|
|
| 353 |
+done |
|
| 354 |
+ |
|
| 355 |
+for CERT_FILE in master-client.crt server.crt; do |
|
| 356 |
+ os::cmd::expect_success_and_text \ |
|
| 357 |
+ "openssl x509 -in '${CERT_DIR}/start-all/node-example.org/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 358 |
+ "${expected_year}"
|
|
| 359 |
+done |
|
| 360 |
+ |
|
| 361 |
+popd >/dev/null |
|
| 362 |
+ |
|
| 363 |
+# openshift start should generate certificates with specified number of days and show warnings |
|
| 364 |
+ |
|
| 365 |
+# we have to remove these files otherwise openshift start won't generate new ones |
|
| 366 |
+rm -rf start-all |
|
| 367 |
+mkdir -p start-all |
|
| 368 |
+ |
|
| 369 |
+pushd start-all >/dev/null |
|
| 370 |
+os::cmd::expect_success_and_text \ |
|
| 371 |
+ "timeout 30 openshift start --write-config='${CERT_DIR}/start-all' \
|
|
| 372 |
+ --hostname=example.org \ |
|
| 373 |
+ --expire-days=$((365*3)) \ |
|
| 374 |
+ --signer-expire-days=$((365*6))" \ |
|
| 375 |
+ 'WARNING: .* is greater than' |
|
| 376 |
+ |
|
| 377 |
+expected_ca_year="$(TZ=GMT date -d "+$((365*6)) days" +'%Y')" |
|
| 378 |
+for CERT_FILE in ca.crt ca-bundle.crt service-signer.crt; do |
|
| 379 |
+ os::cmd::expect_success_and_text \ |
|
| 380 |
+ "openssl x509 -in '${CERT_DIR}/start-all/master/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 381 |
+ "${expected_ca_year}"
|
|
| 382 |
+done |
|
| 383 |
+ |
|
| 384 |
+expected_year="$(TZ=GMT date -d "+$((365*3)) days" +'%Y')" |
|
| 385 |
+for CERT_FILE in admin.crt {master,etcd}.server.crt master.{etcd,kubelet,proxy}-client.crt openshift-{master,registry,router}.crt; do
|
|
| 386 |
+ os::cmd::expect_success_and_text \ |
|
| 387 |
+ "openssl x509 -in '${CERT_DIR}/start-all/master/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 388 |
+ "${expected_year}"
|
|
| 389 |
+done |
|
| 390 |
+ |
|
| 391 |
+for CERT_FILE in master-client.crt server.crt; do |
|
| 392 |
+ os::cmd::expect_success_and_text \ |
|
| 393 |
+ "openssl x509 -in '${CERT_DIR}/start-all/node-example.org/${CERT_FILE}' -enddate -noout | awk '{print \$4}'" \
|
|
| 394 |
+ "${expected_year}"
|
|
| 395 |
+done |
|
| 396 |
+ |
|
| 397 |
+popd >/dev/null |
|
| 398 |
+ |
|
| 399 |
+os::test::junit::declare_suite_end |
|
| 400 |
+ |
|
| 401 |
+popd >/dev/null |
|
| 402 |
+ |
|
| 403 |
+# remove generated files only if tests passed |
|
| 404 |
+rm -rf -- "${CERT_DIR}"
|
| ... | ... |
@@ -92,6 +92,7 @@ func TestOAuthCertFallback(t *testing.T) {
|
| 92 | 92 |
path.Join(fakecadir, "fakeclient.crt"), |
| 93 | 93 |
path.Join(fakecadir, "fakeclient.key"), |
| 94 | 94 |
&user.DefaultInfo{Name: "fakeuser"},
|
| 95 |
+ 365*2, /* 2 years */ |
|
| 95 | 96 |
) |
| 96 | 97 |
if err != nil {
|
| 97 | 98 |
t.Fatalf("Unexpected error: %v", err)
|
| ... | ... |
@@ -28,6 +28,7 @@ import ( |
| 28 | 28 |
|
| 29 | 29 |
// install all APIs |
| 30 | 30 |
_ "github.com/openshift/origin/pkg/api/install" |
| 31 |
+ "github.com/openshift/origin/pkg/cmd/server/crypto" |
|
| 31 | 32 |
_ "k8s.io/kubernetes/pkg/api/install" |
| 32 | 33 |
_ "k8s.io/kubernetes/pkg/apis/extensions/install" |
| 33 | 34 |
) |
| ... | ... |
@@ -177,6 +178,9 @@ func CreateMasterCerts(masterArgs *start.MasterArgs) error {
|
| 177 | 177 |
SignerName: admin.DefaultSignerName(), |
| 178 | 178 |
Hostnames: hostnames.List(), |
| 179 | 179 |
|
| 180 |
+ ExpireDays: crypto.DefaultCertificateLifetimeInDays, |
|
| 181 |
+ SignerExpireDays: crypto.DefaultCACertificateLifetimeInDays, |
|
| 182 |
+ |
|
| 180 | 183 |
APIServerURL: masterURL.String(), |
| 181 | 184 |
PublicAPIServerURL: publicMasterURL.String(), |
| 182 | 185 |
|
| ... | ... |
@@ -227,7 +231,9 @@ func DefaultAllInOneOptions() (*configapi.MasterConfig, *configapi.NodeConfig, * |
| 227 | 227 |
startOptions.NodeArgs.AllowDisabledDocker = true |
| 228 | 228 |
startOptions.NodeArgs.Components.Disable("plugins", "proxy", "dns")
|
| 229 | 229 |
startOptions.ServiceNetworkCIDR = start.NewDefaultNetworkArgs().ServiceNetworkCIDR |
| 230 |
- startOptions.Complete() |
|
| 230 |
+ if err := startOptions.Complete(); err != nil {
|
|
| 231 |
+ return nil, nil, nil, err |
|
| 232 |
+ } |
|
| 231 | 233 |
startOptions.MasterOptions.MasterArgs.ConfigDir.Default(path.Join(util.GetBaseDir(), "openshift.local.config", "master")) |
| 232 | 234 |
startOptions.NodeArgs.ConfigDir.Default(path.Join(util.GetBaseDir(), "openshift.local.config", admin.DefaultNodeDir(startOptions.NodeArgs.NodeName))) |
| 233 | 235 |
startOptions.NodeArgs.MasterCertDir = startOptions.MasterOptions.MasterArgs.ConfigDir.Value() |