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

feat(process): Naive namespaces #312

Merged
merged 5 commits into from
Jul 7, 2020
Merged

feat(process): Naive namespaces #312

merged 5 commits into from
Jul 7, 2020

Conversation

sh0rez
Copy link
Member

@sh0rez sh0rez commented Jul 3, 2020

Now that lists are always unwrapped, we assume all other objects use ObjectMeta, so they do accept a namespace, regardless of whether they actually use it.

This allows us to simplify our code, by always setting it. For yet unknown edge-cases, we allow using the tanka.dev/namespaced annotation to override this behaviour.

Removed the nsPatch injection method, as it is not needed anymore. Show and Apply will behave exactly the same now.

I decided against implementing a default list for cluster-wide resources, because this seems to make things only marginally more correct in theory, but has no effect on the outcome, but comes at the cost of maintaining yet another static list in our code. Quick analysis suggested there is no official type that won't use ObjectMeta, which makes me pretty confident here.

Fixes #269
Fixes #308

sh0rez added 2 commits July 1, 2020 15:53
Now that lists are always unwrapped, we assume all other objects use
`ObjectMeta`, so they do accept a namespace, regardless of whether they
actually use it.

This allows us to simplify our code, by always setting it. For yet
unknown edge-cases, we allow using the `tanka.dev/namespaced` annotation
to override this behaviour.
Not required anymore as namespaces are again supplied in YAML
@sh0rez sh0rez added kind/enhancement Improve something existing component/kubernetes Working with Kubernetes clusters labels Jul 3, 2020
@captncraig
Copy link
Contributor

Here's my concern about just adding namespaces to everything without exception:

If I wanted to export into a file tree like {cluster}/{namespace}/{kind}-{name}.yaml, I would find cluster roles under the namespace of their environment instead of under default or maybe `` like I would expect to find them.

The kubernetes API won't complain, but things will not necessarily go into the directories I'd want them to.

Of course we could also work around this by having a set of overlays we put over the k8s jsonnet lib that add the annotation to those constructors as well.

@hamishforbes
Copy link
Contributor

How would this affect an 'environment' with resources across namespaces?

I would ideally like to have a setup like

environments/cluster1/base/
environments/cluster1/myapp-dev1/
environments/cluster1/myapp-dev2/
environments/cluster2/base/
environments/cluster2/myapp-dev3/
lib/myapp/
lib/base/

Where the myapp lib is a collection of resources for an instance of our application and base is our cluster configuration, ingress, logging, metrics etc.

App environments are all under 1 namespace but the cluster baseline is spread across a few.
i don't really want to have to do cluster/base-logging, cluster/base-metrics etc as separate tanka environments, conceptually they're the same thing and i want to apply them all at once.

@sh0rez
Copy link
Member Author

sh0rez commented Jul 6, 2020

@hamishforbes this should behave exactly as it did before, at least during apply.

Tanka will only ever set the namespace defined in spec.json, if your resources that come from Jsonnet don't already have one. If they do, Tanka won't touch that (it never did).

Only two differences will be there:

  • Cluster-wide resources will show a namespace in YAML, but this will always be discarded by kubectl afterwards. This makes our code much simpler however
  • Namespaces will already be present during show or export, so they are actually passed to CD tools like Argo or Flux if needed

@Duologic
Copy link
Member

Duologic commented Jul 6, 2020

I'd rather see Tanka or Kubectl return an error (or at least a warning), expecting the developer/jsonnet to set the namespace instead, depending on Tanka to resolve the namespace promotes negligence imo.

sh0rez added 2 commits July 6, 2020 19:02
Verifies that metadata.annotations and metadata.labels are of correct type
Copy link
Contributor

@captncraig captncraig left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM,

I do wish we could have a simple list of cluster-wide resources to skip namespacing on, but I can add that in a separate PR.

docs/docs/namespaces.md Outdated Show resolved Hide resolved
pkg/kubernetes/manifest/errors.go Outdated Show resolved Hide resolved
@hamishforbes
Copy link
Contributor

Would it be an option for this behaviour to be configurable?

I think I would prefer to require namespace to be explicitly set and it would be easier to lint/validate in a CI pipeline if Tanka didn't automatically inject namespaces.

@sh0rez
Copy link
Member Author

sh0rez commented Jul 7, 2020

@hamishforbes There is already discussion going about about this exact thing internally and I am happy to have this debate more broadly. Could you open a separate issue for this?

Generally spoken, in an attempt to have as few knobs as possible, I am not a fan of configurable things. Instead, we should aim for a solution that works better for everybody.

Also you could join our monthly community call (https://docs.google.com/document/d/1mEsc0GxlnwbWAXzbIP7tBb6T5WgAI66_0gIWJzqB93o) this evening and bring this up!

@sh0rez sh0rez merged commit eb167c9 into master Jul 7, 2020
@sh0rez sh0rez deleted the naive-namespaces branch July 7, 2020 11:39
sh0rez added a commit that referenced this pull request Aug 10, 2020
The manifest.Manifest is a `map[string]interface{}`, which sticks to
what `json.Unmarshal` returns, meaning it only includes concrete values,
`[]interface{}` and `map[string]interface{}`.

In a v0.10
change (https://github.com/grafana/tanka/blob/a6d5fde5aac69dc4d66bb57d5a501e52ba60fada/pkg/kubernetes/manifest/manifest.go#L248)
I accidentally broke that, without realizing it.

Up to #312, this didn't create any issues. Now however, because we
called `Annotations` on all objects, types weren't like they should have
been.

This caused subsetdiff to miss annotations, not computing the subset on
them at all.

Fixes #318
sh0rez added a commit that referenced this pull request Aug 15, 2020
The manifest.Manifest is a `map[string]interface{}`, which sticks to
what `json.Unmarshal` returns, meaning it only includes concrete values,
`[]interface{}` and `map[string]interface{}`.

In a v0.10
change (https://github.com/grafana/tanka/blob/a6d5fde5aac69dc4d66bb57d5a501e52ba60fada/pkg/kubernetes/manifest/manifest.go#L248)
I accidentally broke that, without realizing it.

Up to #312, this didn't create any issues. Now however, because we
called `Annotations` on all objects, types weren't like they should have
been.

This caused subsetdiff to miss annotations, not computing the subset on
them at all.

Fixes #318
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
component/kubernetes Working with Kubernetes clusters kind/enhancement Improve something existing
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Simplify namespaces in Tanka Add namespace to resources when exporting manifests file
5 participants