243 lines
6.7 KiB
Go
243 lines
6.7 KiB
Go
/*
|
|
Copyright 2020 The Jetstack cert-manager contributors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package certificaterequest
|
|
|
|
import (
|
|
"io/ioutil"
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
func TestValidate(t *testing.T) {
|
|
tests := map[string]struct {
|
|
inputFile string
|
|
inputArgs []string
|
|
keyFilename string
|
|
certFilename string
|
|
fetchCert bool
|
|
|
|
expErr bool
|
|
expErrMsg string
|
|
}{
|
|
"CR name not passed as arg throws error": {
|
|
inputFile: "example.yaml",
|
|
inputArgs: []string{},
|
|
expErr: true,
|
|
expErrMsg: "the name of the CertificateRequest to be created has to be provided as argument",
|
|
},
|
|
"More than one arg throws error": {
|
|
inputFile: "example.yaml",
|
|
inputArgs: []string{"hello", "World"},
|
|
expErr: true,
|
|
expErrMsg: "only one argument can be passed in: the name of the CertificateRequest",
|
|
},
|
|
"not specifying path to yaml manifest throws error": {
|
|
inputFile: "",
|
|
inputArgs: []string{"hello"},
|
|
expErr: true,
|
|
expErrMsg: "the path to a YAML manifest of a Certificate resource cannot be empty, please specify by using --from-certificate-file flag",
|
|
},
|
|
"key filename and cert filename are optional flags": {
|
|
inputFile: "example.yaml",
|
|
inputArgs: []string{"hello"},
|
|
keyFilename: "",
|
|
certFilename: "",
|
|
expErr: false,
|
|
},
|
|
"identical key filename and cert filename throws error": {
|
|
inputFile: "example.yaml",
|
|
inputArgs: []string{"hello"},
|
|
keyFilename: "same",
|
|
certFilename: "same",
|
|
expErr: true,
|
|
expErrMsg: "the file to store private key cannot be the same as the file to store certificate",
|
|
},
|
|
"cannot specify cert filename without fetch-certificate flag": {
|
|
inputFile: "example.yaml",
|
|
inputArgs: []string{"hello"},
|
|
certFilename: "cert.crt",
|
|
fetchCert: false,
|
|
expErr: true,
|
|
expErrMsg: "cannot specify file to store certificate if not waiting for and fetching certificate, please set --fetch-certificate flag",
|
|
},
|
|
}
|
|
|
|
for name, test := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
opts := &Options{
|
|
InputFilename: test.inputFile,
|
|
KeyFilename: test.keyFilename,
|
|
CertFileName: test.certFilename,
|
|
FetchCert: test.fetchCert,
|
|
}
|
|
|
|
// Validating args and flags
|
|
err := opts.Validate(test.inputArgs)
|
|
if err != nil {
|
|
if !test.expErr {
|
|
t.Fatalf("got unexpected error when validating args and flags: %v", err)
|
|
}
|
|
if err.Error() != test.expErrMsg {
|
|
t.Fatalf("got unexpected error when validating args and flags, expected: %v; actual: %v", test.expErrMsg, err)
|
|
}
|
|
} else if test.expErr {
|
|
// got no error
|
|
t.Errorf("expected but got no error validating args and flags")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// Test Run tests the Run function's error behaviour up where it fails before interacting with
|
|
// other components, e.g. writing private key to file.
|
|
func TestRun(t *testing.T) {
|
|
const (
|
|
crName = "testcr-3"
|
|
ns1 = "testns-1"
|
|
ns2 = "testns-2"
|
|
)
|
|
|
|
tests := map[string]struct {
|
|
inputFileContent string
|
|
inputArgs []string
|
|
inputNamespace string
|
|
keyFilename string
|
|
certFilename string
|
|
fetchCert bool
|
|
|
|
expErr bool
|
|
expErrMsg string
|
|
}{
|
|
// Build clients
|
|
"conflicting namespaces defined in flag and file": {
|
|
inputFileContent: `---
|
|
apiVersion: cert-manager.io/v1
|
|
kind: Certificate
|
|
metadata:
|
|
name: testcert-1
|
|
namespace: testns-1
|
|
spec:
|
|
isCA: true
|
|
secretName: ca-key-pair
|
|
commonName: my-csi-app
|
|
issuerRef:
|
|
name: selfsigned-issuer
|
|
kind: Issuer
|
|
group: cert-manager.io
|
|
`,
|
|
inputArgs: []string{crName},
|
|
inputNamespace: ns2,
|
|
keyFilename: "",
|
|
expErr: true,
|
|
expErrMsg: "the namespace from the provided object \"testns-1\" does not match the namespace \"testns-2\". You must pass '--namespace=testns-1' to perform this operation.",
|
|
},
|
|
"file passed in defines resource other than certificate": {
|
|
inputFileContent: `---
|
|
apiVersion: cert-manager.io/v1
|
|
kind: Issuer
|
|
metadata:
|
|
name: ca-issuer
|
|
namespace: testns-1
|
|
spec:
|
|
ca:
|
|
secretName: ca-key-pair
|
|
`,
|
|
inputArgs: []string{crName},
|
|
inputNamespace: ns1,
|
|
keyFilename: "",
|
|
expErr: true,
|
|
expErrMsg: "decoded object is not a v1 Certificate",
|
|
},
|
|
"empty manifest file throws error": {
|
|
inputFileContent: ``,
|
|
inputArgs: []string{crName},
|
|
inputNamespace: ns1,
|
|
keyFilename: "",
|
|
expErr: true,
|
|
expErrMsg: "no objects found in manifest file \"testfile.yaml\". Expected one Certificate object",
|
|
},
|
|
"manifest file with multiple objects throws error": {
|
|
inputFileContent: `---
|
|
apiVersion: cert-manager.io/v1
|
|
kind: Issuer
|
|
metadata:
|
|
name: ca-issuer
|
|
namespace: testns-1
|
|
spec:
|
|
ca:
|
|
secretName: ca-key-pair
|
|
---
|
|
apiVersion: cert-manager.io/v1
|
|
kind: Certificate
|
|
metadata:
|
|
name: testcert-1
|
|
namespace: testns-1
|
|
spec:
|
|
isCA: true
|
|
secretName: ca-key-pair
|
|
commonName: my-csi-app
|
|
issuerRef:
|
|
name: selfsigned-issuer
|
|
kind: Issuer
|
|
group: cert-manager.io`,
|
|
inputArgs: []string{crName},
|
|
inputNamespace: ns1,
|
|
keyFilename: "",
|
|
expErr: true,
|
|
expErrMsg: "multiple objects found in manifest file \"testfile.yaml\". Expected only one Certificate object",
|
|
},
|
|
}
|
|
|
|
for name, test := range tests {
|
|
t.Run(name, func(t *testing.T) {
|
|
if err := ioutil.WriteFile("testfile.yaml", []byte(test.inputFileContent), 0644); err != nil {
|
|
t.Fatalf("error creating test file %#v", err)
|
|
}
|
|
defer os.Remove("testfile.yaml")
|
|
|
|
// Options to run create CR command
|
|
opts := &Options{
|
|
CmdNamespace: test.inputNamespace,
|
|
EnforceNamespace: test.inputNamespace != "",
|
|
InputFilename: "testfile.yaml",
|
|
KeyFilename: test.keyFilename,
|
|
CertFileName: test.certFilename,
|
|
}
|
|
|
|
// Validating args and flags
|
|
err := opts.Validate(test.inputArgs)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
// Create CR
|
|
err = opts.Run(test.inputArgs)
|
|
if err != nil {
|
|
if !test.expErr {
|
|
t.Fatalf("got unexpected error when trying to create CR: %v", err)
|
|
}
|
|
if err.Error() != test.expErrMsg {
|
|
t.Fatalf("got unexpected error when trying to create CR, expected: %v; actual: %v", test.expErrMsg, err)
|
|
}
|
|
} else if test.expErr {
|
|
// got no error
|
|
t.Errorf("expected but got no error when creating CR")
|
|
}
|
|
})
|
|
}
|
|
}
|