Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

kubernetes_secret should allow the . character in the name #87

Closed
rochdev opened this issue Nov 10, 2017 · 6 comments · Fixed by #152
Closed

kubernetes_secret should allow the . character in the name #87

rochdev opened this issue Nov 10, 2017 · 6 comments · Fixed by #152
Labels

Comments

@rochdev
Copy link

rochdev commented Nov 10, 2017

The . character is allowed by Kubernetes and we use it for many of our existing secrets.

@sl1pm4t
Copy link
Contributor

sl1pm4t commented Nov 10, 2017

Does wrapping the secret key in quotes help?

@rochdev
Copy link
Author

rochdev commented Nov 10, 2017

It doesn't. Replacing the . with - resolves the issue but that means we would have to rename all our secrets.

@radeksimko radeksimko added the bug label Nov 16, 2017
@sl1pm4t
Copy link
Contributor

sl1pm4t commented Nov 22, 2017

@rochdev could you paste an example config that isn't working?

I'm able to create a secret with . in the name:

resource "kubernetes_secret" "dot-test" {
  metadata {
    name      = "dot.test"
  }

  data {
    ".start" = "foo"
    "mid.dle" = "foo"
    "end." = "foo"
  }

}
terraform apply

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  + kubernetes_secret.dot-test
      id:                          <computed>
      data.%:                      "3"
      data..start:                 <sensitive>
      data.end.:                   <sensitive>
      data.mid.dle:                <sensitive>
      metadata.#:                  "1"
      metadata.0.generation:       <computed>
      metadata.0.labels.%:         <computed>
      metadata.0.name:             "dot.test"
      metadata.0.namespace:        "default"
      metadata.0.resource_version: <computed>
      metadata.0.self_link:        <computed>
      metadata.0.uid:              <computed>
      type:                        "Opaque"


Plan: 1 to add, 0 to change, 0 to destroy.

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

kubernetes_secret.dot-test: Creating...
  data.%:                      "" => "3"
  data..start:                 "<sensitive>" => "<sensitive>"
  data.end.:                   "<sensitive>" => "<sensitive>"
  data.mid.dle:                "<sensitive>" => "<sensitive>"
  metadata.#:                  "" => "1"
  metadata.0.generation:       "" => "<computed>"
  metadata.0.labels.%:         "" => "<computed>"
  metadata.0.name:             "" => "dot.test"
  metadata.0.namespace:        "" => "default"
  metadata.0.resource_version: "" => "<computed>"
  metadata.0.self_link:        "" => "<computed>"
  metadata.0.uid:              "" => "<computed>"
  type:                        "" => "Opaque"
kubernetes_secret.dot-test: Creation complete after 0s (ID: default/dot.test)

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

However, I'm not able to create a secret with a . at the start or end of the name, but that's the same when I try create via kubectl:

kubectl create secret generic ".my-secret" --from-literal=foo=bar
The Secret ".my-secret" is invalid: metadata.name: Invalid value: ".my-secret": a DNS-1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*')

@rochdev
Copy link
Author

rochdev commented Nov 22, 2017

@sl1pm4t Just tried your exact example and cannot even get a plan working.

tf plan

Error: kubernetes_secret.dot-test: metadata.0.name a DNS-1123 label must consist of lower case alphanumeric characters or '-', and must start and end with an alphanumeric character (e.g. 'my-name',  or '123-abc', regex used for validation is '[a-z0-9]([-a-z0-9]*[a-z0-9])?')

When using the CLI it works:

kubectl create secret generic "dot.secret" --from-literal=foo=bar
secret "dot.secret" created

I am using Terraform v0.11.0 with provider.kubernetes v1.0.1

I don't know if it would make a difference but the cluster is using Kubernetes 1.7.8-gke.0.

@appilon
Copy link
Contributor

appilon commented Apr 6, 2018

The issue arises from the metadata validation we apply.

https://github.com/terraform-providers/terraform-provider-kubernetes/blob/master/kubernetes/validators.go#L32-L42

We are performing DNS label validation (which only permits alphanum and dashes). However the docs for k8s state:
https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

By convention, the names of Kubernetes resources should be up to maximum length of 253 characters and consist of lower case alphanumeric characters, -, and ., but certain resources have more specific restrictions.

Meaning the DNS label is too strict for the name attribute. I would open the PR myself but I'm concerned about the effects of changing this general schema (metadata). Furthermore it appears that "certain resources have more specific restrictions", I think we will need to dig through k8s to find the validation rules for this resource. As mentioned in above comments "starting or ending with a ." is not allowed in kubectl, however the definition I pasted doesn't describe any restriction like that.

UPDATE:
the error posted by @sl1pm4t

The Secret ".my-secret" is invalid: metadata.name: Invalid value: ".my-secret": a DNS-1123 subdomain must consist of lower case alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character (e.g. 'example.com', regex used for validation is 'a-z0-9?(.a-z0-9?)*')

Actually revealed to me kubectl is applying the DNS subdomain validation. Traced to the source in k8s:

const dns1123SubdomainFmt string = dns1123LabelFmt + "(\\." + dns1123LabelFmt + ")*"

@bradcburns
Copy link

bradcburns commented Nov 5, 2018

For those arriving from their preferred search engine, as I did:

Importantly, the validation described seems to only allow lowercase characters for secret names. This precludes camelCase.

My version:
version.Info{Major:"1", Minor:"12", GitVersion:"v1.12.2", GitCommit:"17c77c7898218073f14c8d573582e8d2313dc740", GitTreeState:"clean", BuildDate:"2018-10-30T21:39:38Z", GoVersion:"go1.11.1", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"6", GitVersion:"v1.6.5", GitCommit:"490c6f13df1cb6612e0993c4c14f2ff90f8cdbf3", GitTreeState:"clean", BuildDate:"2017-06-14T20:03:38Z", GoVersion:"go1.7.6", Compiler:"gc", Platform:"linux/amd64"}

@ghost ghost locked and limited conversation to collaborators Apr 21, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants