diff --git a/.generated_docs b/.generated_docs
index f3c1a4e7d46..a97b0374e35 100644
--- a/.generated_docs
+++ b/.generated_docs
@@ -26,6 +26,7 @@ docs/man/man1/kubectl-create-configmap.1
docs/man/man1/kubectl-create-namespace.1
docs/man/man1/kubectl-create-secret-docker-registry.1
docs/man/man1/kubectl-create-secret-generic.1
+docs/man/man1/kubectl-create-secret-tls.1
docs/man/man1/kubectl-create-secret.1
docs/man/man1/kubectl-create-serviceaccount.1
docs/man/man1/kubectl-create.1
@@ -84,6 +85,7 @@ docs/user-guide/kubectl/kubectl_create_namespace.md
docs/user-guide/kubectl/kubectl_create_secret.md
docs/user-guide/kubectl/kubectl_create_secret_docker-registry.md
docs/user-guide/kubectl/kubectl_create_secret_generic.md
+docs/user-guide/kubectl/kubectl_create_secret_tls.md
docs/user-guide/kubectl/kubectl_create_serviceaccount.md
docs/user-guide/kubectl/kubectl_delete.md
docs/user-guide/kubectl/kubectl_describe.md
diff --git a/contrib/completions/bash/kubectl b/contrib/completions/bash/kubectl
index ad2ccfddb22..f722590e2a3 100644
--- a/contrib/completions/bash/kubectl
+++ b/contrib/completions/bash/kubectl
@@ -837,6 +837,69 @@ _kubectl_create_secret_docker-registry()
noun_aliases=()
}
+_kubectl_create_secret_tls()
+{
+ last_command="kubectl_create_secret_tls"
+ commands=()
+
+ flags=()
+ two_word_flags=()
+ flags_with_completion=()
+ flags_completion=()
+
+ flags+=("--cert=")
+ flags+=("--dry-run")
+ flags+=("--generator=")
+ flags+=("--key=")
+ flags+=("--no-headers")
+ flags+=("--output=")
+ two_word_flags+=("-o")
+ flags+=("--output-version=")
+ flags+=("--save-config")
+ flags+=("--schema-cache-dir=")
+ flags_with_completion+=("--schema-cache-dir")
+ flags_completion+=("_filedir")
+ flags+=("--show-all")
+ flags+=("-a")
+ flags+=("--show-labels")
+ flags+=("--sort-by=")
+ flags+=("--template=")
+ flags_with_completion+=("--template")
+ flags_completion+=("_filedir")
+ flags+=("--validate")
+ flags+=("--alsologtostderr")
+ flags+=("--api-version=")
+ flags+=("--as=")
+ flags+=("--certificate-authority=")
+ flags+=("--client-certificate=")
+ flags+=("--client-key=")
+ flags+=("--cluster=")
+ flags+=("--context=")
+ flags+=("--insecure-skip-tls-verify")
+ flags+=("--kubeconfig=")
+ flags+=("--log-backtrace-at=")
+ flags+=("--log-dir=")
+ flags+=("--log-flush-frequency=")
+ flags+=("--logtostderr")
+ flags+=("--match-server-version")
+ flags+=("--namespace=")
+ flags_with_completion+=("--namespace")
+ flags_completion+=("__kubectl_get_namespaces")
+ flags+=("--password=")
+ flags+=("--server=")
+ two_word_flags+=("-s")
+ flags+=("--stderrthreshold=")
+ flags+=("--token=")
+ flags+=("--user=")
+ flags+=("--username=")
+ flags+=("--v=")
+ flags+=("--vmodule=")
+
+ must_have_one_flag=()
+ must_have_one_noun=()
+ noun_aliases=()
+}
+
_kubectl_create_secret_generic()
{
last_command="kubectl_create_secret_generic"
@@ -906,6 +969,7 @@ _kubectl_create_secret()
last_command="kubectl_create_secret"
commands=()
commands+=("docker-registry")
+ commands+=("tls")
commands+=("generic")
flags=()
diff --git a/docs/man/man1/kubectl-create-secret-docker-registry.1 b/docs/man/man1/kubectl-create-secret-docker-registry.1
index 32a94ee5fc6..643fc7f00f6 100644
--- a/docs/man/man1/kubectl-create-secret-docker-registry.1
+++ b/docs/man/man1/kubectl-create-secret-docker-registry.1
@@ -208,7 +208,7 @@ by creating a dockercfg secret and attaching it to your service account.
.nf
# If you don't already have a .dockercfg file, you can create a dockercfg secret directly by using:
- $ kubectl create secret docker\-registry my\-secret \-\-docker\-server=DOCKER\_REGISTRY\_SERVER \-\-docker\-username=DOCKER\_USER \-\-docker\-password=DOCKER\_PASSWORD \-\-docker\-email=DOCKER\_EMAIL
+ kubectl create secret docker\-registry my\-secret \-\-docker\-server=DOCKER\_REGISTRY\_SERVER \-\-docker\-username=DOCKER\_USER \-\-docker\-password=DOCKER\_PASSWORD \-\-docker\-email=DOCKER\_EMAIL
.fi
.RE
diff --git a/docs/man/man1/kubectl-create-secret-tls.1 b/docs/man/man1/kubectl-create-secret-tls.1
new file mode 100644
index 00000000000..75a136e2a0c
--- /dev/null
+++ b/docs/man/man1/kubectl-create-secret-tls.1
@@ -0,0 +1,200 @@
+.TH "KUBERNETES" "1" " kubernetes User Manuals" "Eric Paris" "Jan 2015" ""
+
+
+.SH NAME
+.PP
+kubectl create secret tls \- Create a TLS secret.
+
+
+.SH SYNOPSIS
+.PP
+\fBkubectl create secret tls\fP [OPTIONS]
+
+
+.SH DESCRIPTION
+.PP
+Create a TLS secret from the given public/private key pair.
+
+.PP
+The public/private key pair must exist before hand. The public key certificate must be .PEM encoded and match the given private key.
+
+
+.SH OPTIONS
+.PP
+\fB\-\-cert\fP=""
+ Path to PEM encoded public key certificate.
+
+.PP
+\fB\-\-dry\-run\fP=false
+ If true, only print the object that would be sent, without sending it.
+
+.PP
+\fB\-\-generator\fP="secret\-for\-tls/v1"
+ The name of the API generator to use.
+
+.PP
+\fB\-\-key\fP=""
+ Path to private key associated with given certificate.
+
+.PP
+\fB\-\-no\-headers\fP=false
+ When using the default output, don't print headers.
+
+.PP
+\fB\-o\fP, \fB\-\-output\fP=""
+ Output format. One of: json|yaml|wide|name|go\-template=...|go\-template\-file=...|jsonpath=...|jsonpath\-file=... See golang template [
+\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]] and jsonpath template [
+\[la]http://releases.k8s.io/HEAD/docs/user-guide/jsonpath.md\[ra]].
+
+.PP
+\fB\-\-output\-version\fP=""
+ Output the formatted object with the given group version (for ex: 'extensions/v1beta1').
+
+.PP
+\fB\-\-save\-config\fP=false
+ If true, the configuration of current object will be saved in its annotation. This is useful when you want to perform kubectl apply on this object in the future.
+
+.PP
+\fB\-\-schema\-cache\-dir\fP="\~/.kube/schema"
+ If non\-empty, load/store cached API schemas in this directory, default is '$HOME/.kube/schema'
+
+.PP
+\fB\-a\fP, \fB\-\-show\-all\fP=false
+ When printing, show all resources (default hide terminated pods.)
+
+.PP
+\fB\-\-show\-labels\fP=false
+ When printing, show all labels as the last column (default hide labels column)
+
+.PP
+\fB\-\-sort\-by\fP=""
+ If non\-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. '{.metadata.name}'). The field in the API resource specified by this JSONPath expression must be an integer or a string.
+
+.PP
+\fB\-\-template\fP=""
+ Template string or path to template file to use when \-o=go\-template, \-o=go\-template\-file. The template format is golang templates [
+\[la]http://golang.org/pkg/text/template/#pkg-overview\[ra]].
+
+.PP
+\fB\-\-validate\fP=true
+ If true, use a schema to validate the input before sending it
+
+
+.SH OPTIONS INHERITED FROM PARENT COMMANDS
+.PP
+\fB\-\-alsologtostderr\fP=false
+ log to standard error as well as files
+
+.PP
+\fB\-\-api\-version\fP=""
+ DEPRECATED: The API version to use when talking to the server
+
+.PP
+\fB\-\-as\fP=""
+ Username to impersonate for the operation.
+
+.PP
+\fB\-\-certificate\-authority\fP=""
+ Path to a cert. file for the certificate authority.
+
+.PP
+\fB\-\-client\-certificate\fP=""
+ Path to a client certificate file for TLS.
+
+.PP
+\fB\-\-client\-key\fP=""
+ Path to a client key file for TLS.
+
+.PP
+\fB\-\-cluster\fP=""
+ The name of the kubeconfig cluster to use
+
+.PP
+\fB\-\-context\fP=""
+ The name of the kubeconfig context to use
+
+.PP
+\fB\-\-insecure\-skip\-tls\-verify\fP=false
+ If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure.
+
+.PP
+\fB\-\-kubeconfig\fP=""
+ Path to the kubeconfig file to use for CLI requests.
+
+.PP
+\fB\-\-log\-backtrace\-at\fP=:0
+ when logging hits line file:N, emit a stack trace
+
+.PP
+\fB\-\-log\-dir\fP=""
+ If non\-empty, write log files in this directory
+
+.PP
+\fB\-\-log\-flush\-frequency\fP=5s
+ Maximum number of seconds between log flushes
+
+.PP
+\fB\-\-logtostderr\fP=true
+ log to standard error instead of files
+
+.PP
+\fB\-\-match\-server\-version\fP=false
+ Require server version to match client version
+
+.PP
+\fB\-\-namespace\fP=""
+ If present, the namespace scope for this CLI request.
+
+.PP
+\fB\-\-password\fP=""
+ Password for basic authentication to the API server.
+
+.PP
+\fB\-s\fP, \fB\-\-server\fP=""
+ The address and port of the Kubernetes API server
+
+.PP
+\fB\-\-stderrthreshold\fP=2
+ logs at or above this threshold go to stderr
+
+.PP
+\fB\-\-token\fP=""
+ Bearer token for authentication to the API server.
+
+.PP
+\fB\-\-user\fP=""
+ The name of the kubeconfig user to use
+
+.PP
+\fB\-\-username\fP=""
+ Username for basic authentication to the API server.
+
+.PP
+\fB\-\-v\fP=0
+ log level for V logs
+
+.PP
+\fB\-\-vmodule\fP=
+ comma\-separated list of pattern=N settings for file\-filtered logging
+
+
+.SH EXAMPLE
+.PP
+.RS
+
+.nf
+ # Create a new TLS secret named tls\-secret with the given key pair:
+ kubectl create secret tls tls\-secret \-\-cert=path/to/tls.cert \-\-key=path/to/tls.key
+
+.fi
+.RE
+
+
+.SH SEE ALSO
+.PP
+\fBkubectl\-create\-secret(1)\fP,
+
+
+.SH HISTORY
+.PP
+January 2015, Originally compiled by Eric Paris (eparis at redhat dot com) based on the kubernetes source material, but hopefully they have been automatically generated since!
diff --git a/docs/man/man1/kubectl-create-secret.1 b/docs/man/man1/kubectl-create-secret.1
index a353e3b7d67..e17da7f14a8 100644
--- a/docs/man/man1/kubectl-create-secret.1
+++ b/docs/man/man1/kubectl-create-secret.1
@@ -116,7 +116,7 @@ Create a secret using specified subcommand.
.SH SEE ALSO
.PP
-\fBkubectl\-create(1)\fP, \fBkubectl\-create\-secret\-docker\-registry(1)\fP, \fBkubectl\-create\-secret\-generic(1)\fP,
+\fBkubectl\-create(1)\fP, \fBkubectl\-create\-secret\-docker\-registry(1)\fP, \fBkubectl\-create\-secret\-tls(1)\fP, \fBkubectl\-create\-secret\-generic(1)\fP,
.SH HISTORY
diff --git a/docs/user-guide/kubectl/kubectl_create_secret.md b/docs/user-guide/kubectl/kubectl_create_secret.md
index 011c5cd349c..e8338f0c557 100644
--- a/docs/user-guide/kubectl/kubectl_create_secret.md
+++ b/docs/user-guide/kubectl/kubectl_create_secret.md
@@ -78,8 +78,9 @@ kubectl create secret
* [kubectl create](kubectl_create.md) - Create a resource by filename or stdin
* [kubectl create secret docker-registry](kubectl_create_secret_docker-registry.md) - Create a secret for use with a Docker registry.
* [kubectl create secret generic](kubectl_create_secret_generic.md) - Create a secret from a local file, directory or literal value.
+* [kubectl create secret tls](kubectl_create_secret_tls.md) - Create a TLS secret.
-###### Auto generated by spf13/cobra on 5-Apr-2016
+###### Auto generated by spf13/cobra on 25-Apr-2016
[]()
diff --git a/docs/user-guide/kubectl/kubectl_create_secret_docker-registry.md b/docs/user-guide/kubectl/kubectl_create_secret_docker-registry.md
index f2c1907d47b..9637b2003ff 100644
--- a/docs/user-guide/kubectl/kubectl_create_secret_docker-registry.md
+++ b/docs/user-guide/kubectl/kubectl_create_secret_docker-registry.md
@@ -61,7 +61,7 @@ kubectl create secret docker-registry NAME --docker-username=user --docker-passw
```
# If you don't already have a .dockercfg file, you can create a dockercfg secret directly by using:
- $ kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
+ kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
```
### Options
@@ -118,7 +118,7 @@ kubectl create secret docker-registry NAME --docker-username=user --docker-passw
* [kubectl create secret](kubectl_create_secret.md) - Create a secret using specified subcommand.
-###### Auto generated by spf13/cobra on 5-Apr-2016
+###### Auto generated by spf13/cobra on 16-May-2016
[]()
diff --git a/docs/user-guide/kubectl/kubectl_create_secret_tls.md b/docs/user-guide/kubectl/kubectl_create_secret_tls.md
new file mode 100644
index 00000000000..d468320ab3c
--- /dev/null
+++ b/docs/user-guide/kubectl/kubectl_create_secret_tls.md
@@ -0,0 +1,108 @@
+
+
+
+
+
+
+
+
+
+
+
PLEASE NOTE: This document applies to the HEAD of the source tree
+
+If you are using a released version of Kubernetes, you should
+refer to the docs that go with that version.
+
+Documentation for other releases can be found at
+[releases.k8s.io](http://releases.k8s.io).
+
+--
+
+
+
+
+
+## kubectl create secret tls
+
+Create a TLS secret.
+
+### Synopsis
+
+
+
+Create a TLS secret from the given public/private key pair.
+
+The public/private key pair must exist before hand. The public key certificate must be .PEM encoded and match the given private key.
+
+```
+kubectl create secret tls NAME --cert=path/to/cert/file --key=path/to/key/file [--dry-run]
+```
+
+### Examples
+
+```
+ # Create a new TLS secret named tls-secret with the given key pair:
+ kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key
+```
+
+### Options
+
+```
+ --cert="": Path to PEM encoded public key certificate.
+ --dry-run[=false]: If true, only print the object that would be sent, without sending it.
+ --generator="secret-for-tls/v1": The name of the API generator to use.
+ --key="": Path to private key associated with given certificate.
+ --no-headers[=false]: When using the default output, don't print headers.
+ -o, --output="": Output format. One of: json|yaml|wide|name|go-template=...|go-template-file=...|jsonpath=...|jsonpath-file=... See golang template [http://golang.org/pkg/text/template/#pkg-overview] and jsonpath template [http://releases.k8s.io/HEAD/docs/user-guide/jsonpath.md].
+ --output-version="": Output the formatted object with the given group version (for ex: 'extensions/v1beta1').
+ --save-config[=false]: If true, the configuration of current object will be saved in its annotation. This is useful when you want to perform kubectl apply on this object in the future.
+ --schema-cache-dir="~/.kube/schema": If non-empty, load/store cached API schemas in this directory, default is '$HOME/.kube/schema'
+ -a, --show-all[=false]: When printing, show all resources (default hide terminated pods.)
+ --show-labels[=false]: When printing, show all labels as the last column (default hide labels column)
+ --sort-by="": If non-empty, sort list types using this field specification. The field specification is expressed as a JSONPath expression (e.g. '{.metadata.name}'). The field in the API resource specified by this JSONPath expression must be an integer or a string.
+ --template="": Template string or path to template file to use when -o=go-template, -o=go-template-file. The template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
+ --validate[=true]: If true, use a schema to validate the input before sending it
+```
+
+### Options inherited from parent commands
+
+```
+ --alsologtostderr[=false]: log to standard error as well as files
+ --as="": Username to impersonate for the operation.
+ --certificate-authority="": Path to a cert. file for the certificate authority.
+ --client-certificate="": Path to a client certificate file for TLS.
+ --client-key="": Path to a client key file for TLS.
+ --cluster="": The name of the kubeconfig cluster to use
+ --context="": The name of the kubeconfig context to use
+ --insecure-skip-tls-verify[=false]: If true, the server's certificate will not be checked for validity. This will make your HTTPS connections insecure.
+ --kubeconfig="": Path to the kubeconfig file to use for CLI requests.
+ --log-backtrace-at=:0: when logging hits line file:N, emit a stack trace
+ --log-dir="": If non-empty, write log files in this directory
+ --log-flush-frequency=5s: Maximum number of seconds between log flushes
+ --logtostderr[=true]: log to standard error instead of files
+ --match-server-version[=false]: Require server version to match client version
+ --namespace="": If present, the namespace scope for this CLI request.
+ --password="": Password for basic authentication to the API server.
+ -s, --server="": The address and port of the Kubernetes API server
+ --stderrthreshold=2: logs at or above this threshold go to stderr
+ --token="": Bearer token for authentication to the API server.
+ --user="": The name of the kubeconfig user to use
+ --username="": Username for basic authentication to the API server.
+ --v=0: log level for V logs
+ --vmodule=: comma-separated list of pattern=N settings for file-filtered logging
+```
+
+### SEE ALSO
+
+* [kubectl create secret](kubectl_create_secret.md) - Create a secret using specified subcommand.
+
+###### Auto generated by spf13/cobra on 16-May-2016
+
+
+[]()
+
diff --git a/hack/test-cmd.sh b/hack/test-cmd.sh
index 1fda2229c54..8178819119e 100755
--- a/hack/test-cmd.sh
+++ b/hack/test-cmd.sh
@@ -1209,6 +1209,16 @@ __EOF__
# Clean-up
kubectl delete secret test-secret --namespace=test-secrets
+ ### Create a tls secret
+ # Pre-condition: no SECRET exists
+ kube::test::get_object_assert 'secrets --namespace=test-secrets' "{{range.items}}{{$id_field}}:{{end}}" ''
+ # Command
+ kubectl create secret tls test-secret --namespace=test-secrets --key=hack/testdata/tls.key --cert=hack/testdata/tls.crt
+ kube::test::get_object_assert 'secret/test-secret --namespace=test-secrets' "{{$id_field}}" 'test-secret'
+ kube::test::get_object_assert 'secret/test-secret --namespace=test-secrets' "{{$secret_type}}" 'kubernetes.io/tls'
+ # Clean-up
+ kubectl delete secret test-secret --namespace=test-secrets
+
### Create a secret using output flags
# Pre-condition: no secret exists
kube::test::get_object_assert 'secrets --namespace=test-secrets' "{{range.items}}{{$id_field}}:{{end}}" ''
@@ -2101,7 +2111,7 @@ __EOF__
object="all -l'app=cassandra'"
request="{{range.items}}{{range .metadata.labels}}{{.}}:{{end}}{{end}}"
- # all 4 cassandra's might not be in the request immediately...
+ # all 4 cassandra's might not be in the request immediately...
kube::test::get_object_assert "$object" "$request" 'cassandra:cassandra:cassandra:cassandra:' || \
kube::test::get_object_assert "$object" "$request" 'cassandra:cassandra:cassandra:' || \
kube::test::get_object_assert "$object" "$request" 'cassandra:cassandra:'
diff --git a/hack/testdata/tls.crt b/hack/testdata/tls.crt
new file mode 100644
index 00000000000..4e101761abd
--- /dev/null
+++ b/hack/testdata/tls.crt
@@ -0,0 +1,19 @@
+-----BEGIN CERTIFICATE-----
+MIIDKzCCAhOgAwIBAgIJAP6zX1i14mEuMA0GCSqGSIb3DQEBCwUAMCwxFDASBgNV
+BAMMC2V4YW1wbGUuY29tMRQwEgYDVQQKDAtleGFtcGxlLmNvbTAeFw0xNjA1MTUw
+MDQ0NThaFw0xNzA1MTUwMDQ0NThaMCwxFDASBgNVBAMMC2V4YW1wbGUuY29tMRQw
+EgYDVQQKDAtleGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+ggEBAL/rrmHnmFYPhXaSJD4H8b0018HDr14GJsSEj29aQ9TKffoY7avcc+1ETrfA
+F8WlXjzqez0OhmecBgQloaNU0IKpLm1DIwFanzjejrooGsSAGm510KGKC/K6XfcW
+EPUiYWc35XLRqM4n7X9lqLbzMFdZvEJYRurPuzx7ZSw+UF3QJqPiBx3fbIPYHCIe
+rMHyh1OhZFRPuX6lLxGoDUGu5C+2MQityhZWUTXvRlh7v4Cmb3oD5a+1VGSjM/Kf
+EcXxK4SLDiECHSVdHpvjNnPi1lVXx6/Yel9+95X/rwaILJ4UNuCWp3ixn8iBr+vC
+7ttVj8HMUCkfC7aGaZVcudpre5UCAwEAAaNQME4wHQYDVR0OBBYEFMqQZOeB0B/V
+pPgBNs23SW2aRZsZMB8GA1UdIwQYMBaAFMqQZOeB0B/VpPgBNs23SW2aRZsZMAwG
+A1UdEwQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEtLa1+ovgKHHr3YKUyrbWi2
+SbNmrMrQIdomdNnhQn/3tYl2RG/twUIpi2LaxLC8+n+hhVO9Gy1hy18xQ9bXDKtC
+I30dml8qmNqqCpCxTz6jSh7kxiBF8+7lj6B3zoN4JLVDdmp+8iQwecd+rgB5jW8O
+c333juUWA/c9QC9VO6yeDZs4EBkD2/a1GRtMkU2nkk7jk4QhMcjSxFKH+7ROC6yN
+/+80NcHdDitVt0VRqogWusZDCMeZFwGVrfPVT8iYfP8lP7p6HBkYzvVP6SaMn76P
+/tGxy/BYC4mGosiyhdfLBQS/Q1bkvNhu2O6Y9hqWE6tLNy+YIC3A0ON5/xN36dY=
+-----END CERTIFICATE-----
diff --git a/hack/testdata/tls.key b/hack/testdata/tls.key
new file mode 100644
index 00000000000..8f94973fc66
--- /dev/null
+++ b/hack/testdata/tls.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC/665h55hWD4V2
+kiQ+B/G9NNfBw69eBibEhI9vWkPUyn36GO2r3HPtRE63wBfFpV486ns9DoZnnAYE
+JaGjVNCCqS5tQyMBWp843o66KBrEgBpuddChigvyul33FhD1ImFnN+Vy0ajOJ+1/
+Zai28zBXWbxCWEbqz7s8e2UsPlBd0Caj4gcd32yD2BwiHqzB8odToWRUT7l+pS8R
+qA1BruQvtjEIrcoWVlE170ZYe7+Apm96A+WvtVRkozPynxHF8SuEiw4hAh0lXR6b
+4zZz4tZVV8ev2HpffveV/68GiCyeFDbglqd4sZ/Iga/rwu7bVY/BzFApHwu2hmmV
+XLnaa3uVAgMBAAECggEAG+kvnCdtPR7Wvw6z3J2VJ3oW4qQNzfPBEZVhssUC1mB4
+f7W+Yt8VsOzdMdXq3yCUmvFS6OdC3rCPI21Bm5pLFKV8DgHUhm7idwfO4/3PHsKu
+lV/m7odAA5Xc8oEwCCZu2e8EHHWnQgwGex+SsMCfSCTRvyhNb/qz9TDQ3uVVFL9e
+9a4OKqZl/GlRspJSuXhy+RSVulw9NjeX1VRjIbhqpdXAmQNXgShA+gZSQh8T/tgv
+XQYsMtg+FUDvcunJQf4OW5BY7IenYBV/GvsnJU8L7oD0wjNSAwe/iLKqV/NpYhre
+QR4DsGnmoRYlUlHdHFTTJpReDjWm+vH3T756yDdFAQKBgQD2/sP5dM/aEW7Z1TgS
+TG4ts1t8Rhe9escHxKZQR81dfOxBeCJMBDm6ySfR8rvyUM4VsogxBL/RhRQXsjJM
+7wN08MhdiXG0J5yy/oNo8W6euD8m8Mk1UmqcZjSgV4vA7zQkvkr6DRJdybKsT9mE
+jouEwev8sceS6iBpPw/+Ws8z1QKBgQDG6uYHMfMcS844xKQQWhargdN2XBzeG6TV
+YXfNFstNpD84d9zIbpG/AKJF8fKrseUhXkJhkDjFGJTriD3QQsntOFaDOrHMnveV
+zGzvC4OTFUUFHe0SVJ0HuLf8YCHoZ+DXEeCKCN6zBXnUue+bt3NvLOf2yN5o9kYx
+SIa8O1vIwQKBgEdONXWG65qg/ceVbqKZvhUjen3eHmxtTZhIhVsX34nlzq73567a
+aXArMnvB/9Bs05IgAIFmRZpPOQW+RBdByVWxTabzTwgbh3mFUJqzWKQpvNGZIf1q
+1axhNUA1BfulEwCojyyxKWQ6HoLwanOCU3T4JxDEokEfpku8EPn1bWwhAoGAAN8A
+eOGYHfSbB5ac3VF3rfKYmXkXy0U1uJV/r888vq9Mc5PazKnnS33WOBYyKNxTk4zV
+H5ZBGWPdKxbipmnUdox7nIGCS9IaZXaKt5VGUzuRnM8fvafPNDxz2dAV9e2Wh3qV
+kCUvzHrmqK7TxMvN3pvEvEju6GjDr+2QYXylD0ECgYAGK5r+y+EhtKkYFLeYReUt
+znvSsWq+JCQH/cmtZLaVOldCaMRL625hSl3XPPcMIHE14xi3d4njoXWzvzPcg8L6
+vNXk3GiNldACS+vwk4CwEqe5YlZRm5doD07wIdsg2zRlnKsnXNM152OwgmcchDul
+rLTt0TTazzwBCgCD0Jkoqg==
+-----END PRIVATE KEY-----
diff --git a/pkg/kubectl/cmd/create_secret.go b/pkg/kubectl/cmd/create_secret.go
index ed4540db679..227c1e0ce40 100644
--- a/pkg/kubectl/cmd/create_secret.go
+++ b/pkg/kubectl/cmd/create_secret.go
@@ -37,6 +37,7 @@ func NewCmdCreateSecret(f *cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
},
}
cmd.AddCommand(NewCmdCreateSecretDockerRegistry(f, cmdOut))
+ cmd.AddCommand(NewCmdCreateSecretTLS(f, cmdOut))
cmd.AddCommand(NewCmdCreateSecretGeneric(f, cmdOut))
return cmd
@@ -130,7 +131,7 @@ nodes to pull images on your behalf, they have to have the credentials. You can
by creating a dockercfg secret and attaching it to your service account.`
secretForDockerRegistryExample = ` # If you don't already have a .dockercfg file, you can create a dockercfg secret directly by using:
- $ kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL`
+ kubectl create secret docker-registry my-secret --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL`
)
// NewCmdCreateSecretDockerRegistry is a macro command for creating secrets to work with Docker registries
@@ -192,3 +193,65 @@ func CreateSecretDockerRegistry(f *cmdutil.Factory, cmdOut io.Writer, cmd *cobra
OutputFormat: cmdutil.GetFlagString(cmd, "output"),
})
}
+
+const (
+ secretForTLSLong = `
+Create a TLS secret from the given public/private key pair.
+
+The public/private key pair must exist before hand. The public key certificate must be .PEM encoded and match the given private key.`
+
+ secretForTLSExample = ` # Create a new TLS secret named tls-secret with the given key pair:
+ kubectl create secret tls tls-secret --cert=path/to/tls.cert --key=path/to/tls.key`
+)
+
+// NewCmdCreateSecretTLS is a macro command for creating secrets to work with Docker registries
+func NewCmdCreateSecretTLS(f *cmdutil.Factory, cmdOut io.Writer) *cobra.Command {
+ cmd := &cobra.Command{
+ Use: "tls NAME --cert=path/to/cert/file --key=path/to/key/file [--dry-run]",
+ Short: "Create a TLS secret.",
+ Long: secretForTLSLong,
+ Example: secretForTLSExample,
+ Run: func(cmd *cobra.Command, args []string) {
+ err := CreateSecretTLS(f, cmdOut, cmd, args)
+ cmdutil.CheckErr(err)
+ },
+ }
+ cmdutil.AddApplyAnnotationFlags(cmd)
+ cmdutil.AddValidateFlags(cmd)
+ cmdutil.AddPrinterFlags(cmd)
+ cmdutil.AddGeneratorFlags(cmd, cmdutil.SecretForTLSV1GeneratorName)
+ cmd.Flags().String("cert", "", "Path to PEM encoded public key certificate.")
+ cmd.Flags().String("key", "", "Path to private key associated with given certificate.")
+ return cmd
+}
+
+// CreateSecretTLS is the implementation of the create secret tls command
+func CreateSecretTLS(f *cmdutil.Factory, cmdOut io.Writer, cmd *cobra.Command, args []string) error {
+ name, err := NameFromCommandArgs(cmd, args)
+ if err != nil {
+ return err
+ }
+ requiredFlags := []string{"cert", "key"}
+ for _, requiredFlag := range requiredFlags {
+ if value := cmdutil.GetFlagString(cmd, requiredFlag); len(value) == 0 {
+ return cmdutil.UsageError(cmd, "flag %s is required", requiredFlag)
+ }
+ }
+ var generator kubectl.StructuredGenerator
+ switch generatorName := cmdutil.GetFlagString(cmd, "generator"); generatorName {
+ case cmdutil.SecretForTLSV1GeneratorName:
+ generator = &kubectl.SecretForTLSGeneratorV1{
+ Name: name,
+ Key: cmdutil.GetFlagString(cmd, "key"),
+ Cert: cmdutil.GetFlagString(cmd, "cert"),
+ }
+ default:
+ return cmdutil.UsageError(cmd, fmt.Sprintf("Generator: %s not supported.", generatorName))
+ }
+ return RunCreateSubcommand(f, cmd, cmdOut, &CreateSubcommandOptions{
+ Name: name,
+ StructuredGenerator: generator,
+ DryRun: cmdutil.GetFlagBool(cmd, "dry-run"),
+ OutputFormat: cmdutil.GetFlagString(cmd, "output"),
+ })
+}
diff --git a/pkg/kubectl/cmd/util/factory.go b/pkg/kubectl/cmd/util/factory.go
index 280387822d8..d42fdd3c703 100644
--- a/pkg/kubectl/cmd/util/factory.go
+++ b/pkg/kubectl/cmd/util/factory.go
@@ -161,6 +161,7 @@ const (
NamespaceV1GeneratorName = "namespace/v1"
SecretV1GeneratorName = "secret/v1"
SecretForDockerRegistryV1GeneratorName = "secret-for-docker-registry/v1"
+ SecretForTLSV1GeneratorName = "secret-for-tls/v1"
ConfigMapV1GeneratorName = "configmap/v1"
)
@@ -190,6 +191,10 @@ func DefaultGenerators(cmdName string) map[string]kubectl.Generator {
generators["secret-for-docker-registry"] = map[string]kubectl.Generator{
SecretForDockerRegistryV1GeneratorName: kubectl.SecretForDockerRegistryGeneratorV1{},
}
+ generators["secret-for-tls"] = map[string]kubectl.Generator{
+ SecretForTLSV1GeneratorName: kubectl.SecretForTLSGeneratorV1{},
+ }
+
return generators[cmdName]
}
diff --git a/pkg/kubectl/secret_for_tls.go b/pkg/kubectl/secret_for_tls.go
new file mode 100644
index 00000000000..05061d25974
--- /dev/null
+++ b/pkg/kubectl/secret_for_tls.go
@@ -0,0 +1,124 @@
+/*
+Copyright 2015 The Kubernetes Authors All rights reserved.
+
+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 kubectl
+
+import (
+ "crypto/tls"
+ "fmt"
+ "io/ioutil"
+
+ "k8s.io/kubernetes/pkg/api"
+ "k8s.io/kubernetes/pkg/runtime"
+)
+
+// SecretForTLSGeneratorV1 supports stable generation of a TLS secret.
+type SecretForTLSGeneratorV1 struct {
+ // Name is the name of this TLS secret.
+ Name string
+ // Key is the path to the user's private key.
+ Key string
+ // Cert is the path to the user's public key certificate.
+ Cert string
+}
+
+// Ensure it supports the generator pattern that uses parameter injection
+var _ Generator = &SecretForTLSGeneratorV1{}
+
+// Ensure it supports the generator pattern that uses parameters specified during construction
+var _ StructuredGenerator = &SecretForTLSGeneratorV1{}
+
+// Generate returns a secret using the specified parameters
+func (s SecretForTLSGeneratorV1) Generate(genericParams map[string]interface{}) (runtime.Object, error) {
+ err := ValidateParams(s.ParamNames(), genericParams)
+ if err != nil {
+ return nil, err
+ }
+ params := map[string]string{}
+ for key, value := range genericParams {
+ strVal, isString := value.(string)
+ if !isString {
+ return nil, fmt.Errorf("expected string, saw %v for '%s'", value, key)
+ }
+ params[key] = strVal
+ }
+ delegate := &SecretForTLSGeneratorV1{
+ Name: params["name"],
+ Key: params["key"],
+ Cert: params["cert"],
+ }
+ return delegate.StructuredGenerate()
+}
+
+// StructuredGenerate outputs a secret object using the configured fields
+func (s SecretForTLSGeneratorV1) StructuredGenerate() (runtime.Object, error) {
+ if err := s.validate(); err != nil {
+ return nil, err
+ }
+ tlsCrt, err := readFile(s.Cert)
+ if err != nil {
+ return nil, err
+ }
+ tlsKey, err := readFile(s.Key)
+ if err != nil {
+ return nil, err
+ }
+ secret := &api.Secret{}
+ secret.Name = s.Name
+ secret.Type = api.SecretTypeTLS
+ secret.Data = map[string][]byte{}
+ secret.Data[api.TLSCertKey] = []byte(tlsCrt)
+ secret.Data[api.TLSPrivateKeyKey] = []byte(tlsKey)
+ return secret, nil
+}
+
+// readFile just reads a file into a byte array.
+func readFile(file string) ([]byte, error) {
+ b, err := ioutil.ReadFile(file)
+ if err != nil {
+ return []byte{}, fmt.Errorf("Cannot read file %v, %v", file, err)
+ }
+ return b, nil
+}
+
+// ParamNames returns the set of supported input parameters when using the parameter injection generator pattern
+func (s SecretForTLSGeneratorV1) ParamNames() []GeneratorParam {
+ return []GeneratorParam{
+ {"name", true},
+ {"key", true},
+ {"cert", true},
+ }
+}
+
+// validate validates required fields are set to support structured generation
+func (s SecretForTLSGeneratorV1) validate() error {
+ // TODO: This is not strictly necessary. We can generate a self signed cert
+ // if no key/cert is given. The only requiredment is that we either get both
+ // or none. See test/e2e/ingress_utils for self signed cert generation.
+ if len(s.Key) == 0 {
+ return fmt.Errorf("key must be specified.")
+ }
+ if len(s.Cert) == 0 {
+ return fmt.Errorf("certificate must be specified.")
+ }
+ if _, err := tls.LoadX509KeyPair(s.Cert, s.Key); err != nil {
+ return fmt.Errorf("failed to load key pair %v", err)
+ }
+ // TODO: Add more validation.
+ // 1. If the certificate contains intermediates, it is a valid chain.
+ // 2. Format etc.
+ return nil
+}
diff --git a/pkg/kubectl/secret_for_tls_test.go b/pkg/kubectl/secret_for_tls_test.go
new file mode 100644
index 00000000000..f24403fd221
--- /dev/null
+++ b/pkg/kubectl/secret_for_tls_test.go
@@ -0,0 +1,204 @@
+/*
+Copyright 2015 The Kubernetes Authors All rights reserved.
+
+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 kubectl
+
+import (
+ "fmt"
+ "os"
+ "path"
+ "reflect"
+ "testing"
+
+ "k8s.io/kubernetes/pkg/api"
+ utiltesting "k8s.io/kubernetes/pkg/util/testing"
+)
+
+var rsaCertPEM = `-----BEGIN CERTIFICATE-----
+MIIB0zCCAX2gAwIBAgIJAI/M7BYjwB+uMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV
+BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
+aWRnaXRzIFB0eSBMdGQwHhcNMTIwOTEyMjE1MjAyWhcNMTUwOTEyMjE1MjAyWjBF
+MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
+ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBANLJ
+hPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wok/4xIA+ui35/MmNa
+rtNuC+BdZ1tMuVCPFZcCAwEAAaNQME4wHQYDVR0OBBYEFJvKs8RfJaXTH08W+SGv
+zQyKn0H8MB8GA1UdIwQYMBaAFJvKs8RfJaXTH08W+SGvzQyKn0H8MAwGA1UdEwQF
+MAMBAf8wDQYJKoZIhvcNAQEFBQADQQBJlffJHybjDGxRMqaRmDhX0+6v02TUKZsW
+r5QuVbpQhH6u+0UgcW0jp9QwpxoPTLTWGXEWBBBurxFwiCBhkQ+V
+-----END CERTIFICATE-----
+`
+
+var rsaKeyPEM = `-----BEGIN RSA PRIVATE KEY-----
+MIIBOwIBAAJBANLJhPHhITqQbPklG3ibCVxwGMRfp/v4XqhfdQHdcVfHap6NQ5Wo
+k/4xIA+ui35/MmNartNuC+BdZ1tMuVCPFZcCAwEAAQJAEJ2N+zsR0Xn8/Q6twa4G
+6OB1M1WO+k+ztnX/1SvNeWu8D6GImtupLTYgjZcHufykj09jiHmjHx8u8ZZB/o1N
+MQIhAPW+eyZo7ay3lMz1V01WVjNKK9QSn1MJlb06h/LuYv9FAiEA25WPedKgVyCW
+SmUwbPw8fnTcpqDWE3yTO3vKcebqMSsCIBF3UmVue8YU3jybC3NxuXq3wNm34R8T
+xVLHwDXh/6NJAiEAl2oHGGLz64BuAfjKrqwz7qMYr9HCLIe/YsoWq/olzScCIQDi
+D2lWusoe2/nEqfDVVWGWlyJ7yOmqaVm/iNUN9B2N2g==
+-----END RSA PRIVATE KEY-----
+`
+
+const mismatchRSAKeyPEM = `-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQC/665h55hWD4V2
+kiQ+B/G9NNfBw69eBibEhI9vWkPUyn36GO2r3HPtRE63wBfFpV486ns9DoZnnAYE
+JaGjVNCCqS5tQyMBWp843o66KBrEgBpuddChigvyul33FhD1ImFnN+Vy0ajOJ+1/
+Zai28zBXWbxCWEbqz7s8e2UsPlBd0Caj4gcd32yD2BwiHqzB8odToWRUT7l+pS8R
+qA1BruQvtjEIrcoWVlE170ZYe7+Apm96A+WvtVRkozPynxHF8SuEiw4hAh0lXR6b
+4zZz4tZVV8ev2HpffveV/68GiCyeFDbglqd4sZ/Iga/rwu7bVY/BzFApHwu2hmmV
+XLnaa3uVAgMBAAECggEAG+kvnCdtPR7Wvw6z3J2VJ3oW4qQNzfPBEZVhssUC1mB4
+f7W+Yt8VsOzdMdXq3yCUmvFS6OdC3rCPI21Bm5pLFKV8DgHUhm7idwfO4/3PHsKu
+lV/m7odAA5Xc8oEwCCZu2e8EHHWnQgwGex+SsMCfSCTRvyhNb/qz9TDQ3uVVFL9e
+9a4OKqZl/GlRspJSuXhy+RSVulw9NjeX1VRjIbhqpdXAmQNXgShA+gZSQh8T/tgv
+XQYsMtg+FUDvcunJQf4OW5BY7IenYBV/GvsnJU8L7oD0wjNSAwe/iLKqV/NpYhre
+QR4DsGnmoRYlUlHdHFTTJpReDjWm+vH3T756yDdFAQKBgQD2/sP5dM/aEW7Z1TgS
+TG4ts1t8Rhe9escHxKZQR81dfOxBeCJMBDm6ySfR8rvyUM4VsogxBL/RhRQXsjJM
+7wN08MhdiXG0J5yy/oNo8W6euD8m8Mk1UmqcZjSgV4vA7zQkvkr6DRJdybKsT9mE
+jouEwev8sceS6iBpPw/+Ws8z1QKBgQDG6uYHMfMcS844xKQQWhargdN2XBzeG6TV
+YXfNFstNpD84d9zIbpG/AKJF8fKrseUhXkJhkDjFGJTriD3QQsntOFaDOrHMnveV
+zGzvC4OTFUUFHe0SVJ0HuLf8YCHoZ+DXEeCKCN6zBXnUue+bt3NvLOf2yN5o9kYx
+SIa8O1vIwQKBgEdONXWG65qg/ceVbqKZvhUjen3eHmxtTZhIhVsX34nlzq73567a
+aXArMnvB/9Bs05IgAIFmRZpPOQW+RBdByVWxTabzTwgbh3mFUJqzWKQpvNGZIf1q
+1axhNUA1BfulEwCojyyxKWQ6HoLwanOCU3T4JxDEokEfpku8EPn1bWwhAoGAAN8A
+eOGYHfSbB5ac3VF3rfKYmXkXy0U1uJV/r888vq9Mc5PazKnnS33WOBYyKNxTk4zV
+H5ZBGWPdKxbipmnUdox7nIGCS9IaZXaKt5VGUzuRnM8fvafPNDxz2dAV9e2Wh3qV
+kCUvzHrmqK7TxMvN3pvEvEju6GjDr+2QYXylD0ECgYAGK5r+y+EhtKkYFLeYReUt
+znvSsWq+JCQH/cmtZLaVOldCaMRL625hSl3XPPcMIHE14xi3d4njoXWzvzPcg8L6
+vNXk3GiNldACS+vwk4CwEqe5YlZRm5doD07wIdsg2zRlnKsnXNM152OwgmcchDul
+rLTt0TTazzwBCgCD0Jkoqg==
+-----END PRIVATE KEY-----`
+
+func tearDown(tmpDir string) {
+ err := os.RemoveAll(tmpDir)
+ if err != nil {
+ fmt.Printf("Error in cleaning up test: %v", err)
+ }
+}
+
+func write(path, contents string, t *testing.T) {
+ f, err := os.Create(path)
+ if err != nil {
+ t.Fatalf("Failed to create %v.", path)
+ }
+ _, err = f.WriteString(contents)
+ if err != nil {
+ t.Fatalf("Failed to write to %v.", path)
+ }
+}
+
+func writeKeyPair(tmpDirPath, key, cert string, t *testing.T) (keyPath, certPath string) {
+ keyPath = path.Join(tmpDirPath, "tls.key")
+ certPath = path.Join(tmpDirPath, "tls.cert")
+ write(keyPath, key, t)
+ write(certPath, cert, t)
+ return
+}
+
+func TestSecretForTLSGenerate(t *testing.T) {
+ invalidCertTmpDir := utiltesting.MkTmpdirOrDie("tls-test")
+ defer tearDown(invalidCertTmpDir)
+ invalidKeyPath, invalidCertPath := writeKeyPair(invalidCertTmpDir, "test", "test", t)
+
+ validCertTmpDir := utiltesting.MkTmpdirOrDie("tls-test")
+ defer tearDown(validCertTmpDir)
+ validKeyPath, validCertPath := writeKeyPair(validCertTmpDir, rsaKeyPEM, rsaCertPEM, t)
+
+ mismatchCertTmpDir := utiltesting.MkTmpdirOrDie("tls-mismatch-test")
+ defer tearDown(mismatchCertTmpDir)
+ mismatchKeyPath, mismatchCertPath := writeKeyPair(mismatchCertTmpDir, mismatchRSAKeyPEM, rsaCertPEM, t)
+
+ tests := map[string]struct {
+ params map[string]interface{}
+ expected *api.Secret
+ expectErr bool
+ }{
+ "test-valid-tls-secret": {
+ params: map[string]interface{}{
+ "name": "foo",
+ "key": validKeyPath,
+ "cert": validCertPath,
+ },
+ expected: &api.Secret{
+ ObjectMeta: api.ObjectMeta{
+ Name: "foo",
+ },
+ Data: map[string][]byte{
+ api.TLSCertKey: []byte(rsaCertPEM),
+ api.TLSPrivateKeyKey: []byte(rsaKeyPEM),
+ },
+ Type: api.SecretTypeTLS,
+ },
+ expectErr: false,
+ },
+ "test-invalid-key-pair": {
+ params: map[string]interface{}{
+ "name": "foo",
+ "key": invalidKeyPath,
+ "cert": invalidCertPath,
+ },
+ expected: &api.Secret{
+ ObjectMeta: api.ObjectMeta{
+ Name: "foo",
+ },
+ Data: map[string][]byte{
+ api.TLSCertKey: []byte("test"),
+ api.TLSPrivateKeyKey: []byte("test"),
+ },
+ Type: api.SecretTypeTLS,
+ },
+ expectErr: true,
+ },
+ "test-mismatched-key-pair": {
+ params: map[string]interface{}{
+ "name": "foo",
+ "key": mismatchKeyPath,
+ "cert": mismatchCertPath,
+ },
+ expected: &api.Secret{
+ ObjectMeta: api.ObjectMeta{
+ Name: "foo",
+ },
+ Data: map[string][]byte{
+ api.TLSCertKey: []byte(rsaCertPEM),
+ api.TLSPrivateKeyKey: []byte(mismatchRSAKeyPEM),
+ },
+ Type: api.SecretTypeTLS,
+ },
+ expectErr: true,
+ },
+ "test-missing-required-param": {
+ params: map[string]interface{}{
+ "name": "foo",
+ "key": "/tmp/foo.key",
+ },
+ expectErr: true,
+ },
+ }
+
+ generator := SecretForTLSGeneratorV1{}
+ for _, test := range tests {
+ obj, err := generator.Generate(test.params)
+ if !test.expectErr && err != nil {
+ t.Errorf("unexpected error: %v", err)
+ }
+ if test.expectErr && err != nil {
+ continue
+ }
+ if !reflect.DeepEqual(obj.(*api.Secret), test.expected) {
+ t.Errorf("\nexpected:\n%#v\nsaw:\n%#v", test.expected, obj.(*api.Secret))
+ }
+ }
+}