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

ServerSideApply breaks CreateNamespace #13874

Closed
3 tasks done
morey-tech opened this issue Jun 1, 2023 · 20 comments
Closed
3 tasks done

ServerSideApply breaks CreateNamespace #13874

morey-tech opened this issue Jun 1, 2023 · 20 comments
Labels
bug Something isn't working

Comments

@morey-tech
Copy link
Contributor

morey-tech commented Jun 1, 2023

Checklist:

  • I've searched in the docs and FAQ for my answer: https://bit.ly/argocd-faq.
  • I've included steps to reproduce the bug.
  • I've pasted the output of argocd version.

Describe the bug

When ServerSideApply is enabled on a resource (e.g., a ConfigMap or Deployment) and the Application is using CreateNamespace, the sync will fail with namespaces "<namespace>" not found.

Based on this thread in the #argo-cd channel.

To Reproduce

Create new application using this spec:

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: 'kustomize-guestbook'
spec:
  project: default
  source:
    repoURL: 'https://github.com/morey-tech/argocd-example-apps/'
    path: general/kustomize-guestbook
    targetRevision: ssa-createnamespace-test
    kustomize:
      namespace: kustomize-guestbook
  destination:
    namespace: kustomize-guestbook
    name: kind
  syncPolicy:
    automated:
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Xnapper-2023-06-01-11 22 32

Expected behavior

Without ServerSideApply on a resource, the sync creates the namespace and the resources without issue. I would expect the same here. Here's a working example (the only difference is no SSA on the deployment):

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: 'kustomize-guestbook'
spec:
  project: default
  source:
    repoURL: 'https://github.com/morey-tech/argocd-example-apps/'
    path: general/kustomize-guestbook
    targetRevision: HEAD
  destination:
    namespace: kustomize-guestbook
    name: kind
  syncPolicy:
    automated:
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

Xnapper-2023-06-01-11 38 40

Version

{
    "Version": "v2.7.2+cbee7e6.dirty",
    "BuildDate": "2023-05-12T13:43:26Z",
    "GitCommit": "cbee7e6011407ed2d1066c482db74e97e0cc6bdb",
    "GitTreeState": "dirty",
    "GoVersion": "go1.19.6",
    "Compiler": "gc",
    "Platform": "linux/amd64",
    "KustomizeVersion": "v5.0.1 2023-03-14T01:32:48Z",
    "HelmVersion": "v3.11.2+g912ebc1",
    "KubectlVersion": "v0.24.2",
    "JsonnetVersion": "v0.19.1"
}

Logs

Paste any relevant application logs here.
@morey-tech morey-tech added the bug Something isn't working label Jun 1, 2023
@morey-tech
Copy link
Contributor Author

@leoluz, is this expected behaviour with the implementation of #9711?

@blakepettersson
Copy link
Member

Does this work when adding managedNamespaceMetadata, like

  syncPolicy:
    automated:
      selfHeal: true
    managedNamespaceMetadata:
      labels: {}
      annotations: {}
    syncOptions:
      - CreateNamespace=true

@nicl-dev
Copy link

nicl-dev commented Jun 2, 2023

We tried that already. Unfortunately it doesn't.

@morey-tech
Copy link
Contributor Author

In my example, the addition of spec.syncPolicy.managedNamespaceMetadata={} does solve the problem.

  apiVersion: argoproj.io/v1alpha1
  kind: Application
  metadata:
    name: 'kustomize-guestbook'
  spec:
    project: default
    source:
      repoURL: 'https://github.com/morey-tech/argocd-example-apps/'
      path: general/kustomize-guestbook
      targetRevision: ssa-createnamespace-test
    destination:
      namespace: kustomize-guestbook
      name: kind
    syncPolicy:
      automated:
        selfHeal: true
      syncOptions:
        - CreateNamespace=true
++    managedNamespaceMetadata: {}

Xnapper-2023-06-02-09 34 07

@morey-tech
Copy link
Contributor Author

@nicl-dev, can you provide the steps to reproduce the issue with managedNamespaceMetadata in use?

@nicl-dev
Copy link

nicl-dev commented Jun 2, 2023

Yea sure, I will try to reproduce it on Monday. My colleague was 100% sure he tried that solution but I'll try it again.

@leoluz
Copy link
Collaborator

leoluz commented Jun 2, 2023

@leoluz, is this expected behaviour with the implementation of #9711?

@morey-tech Not an expected behaviour. If it doesn't, it might be a bug.

In my example, the addition of spec.syncPolicy.managedNamespaceMetadata={} does solve the problem.

@morey-tech That is surprising because enabling managedNamespaceMetadata will create the namespace with server-side apply.

@morey-tech
Copy link
Contributor Author

morey-tech commented Jun 2, 2023

In my example, the addition of spec.syncPolicy.managedNamespaceMetadata={} does solve the problem.

@morey-tech That is surprising because enabling managedNamespaceMetadata will create the namespace with server-side apply.

@leoluz, this almost makes sense then right? Without that, the Deployment uses SSA, but the namespace isn't. So SSA complains that the namespace doesn't exist. But with managedNamespaceMetadata, both the deployment and namespace are included in the SSA, and therefore the cluster knows the namespace will exist before applying the deployment.

@nicl-dev
Copy link

nicl-dev commented Jun 5, 2023

Alright, I just tested it again and managedNamespaceMetadata does indeed fix the problem. Sorry for the confusion.

@jaideepr97
Copy link
Contributor

closing this issue since it sounds like we have reached a resolution
please feel free to re-open if that is not the case

@morey-tech
Copy link
Contributor Author

@jaideepr97 the resolution reached was merely a way to mitigate this issue's bug. I assume it's not the desired behaviour for any resource using ServerSideApply to cause CreateNamespace to malfunction when managedNamespaceMetadata is absent.

It seems like automatically including managedNamespaceMetadata: {} when CreateNamespace is in use, along with ServerSideApply, would resolve this bug. But maybe there is a more intelligent solution.

@evs-ops
Copy link

evs-ops commented Nov 23, 2023

I can confirm that also in version v2.9.2 the problem exists. I tried to use managedNamespaceMetadata on an applicationset with ServerSideApply=true and it didn't do anything. Once I removed ServerSideApply it worked like a charm

@blakepettersson
Copy link
Member

@evs-ops can you show the Application[Set] that displays this issue?

It seems like automatically including managedNamespaceMetadata: {} when CreateNamespace is in use, along with ServerSideApply, would resolve this bug. But maybe there is a more intelligent solution.

The issue is that gitops-engine will already SSA the namespace if the [whole] application itself has ServerSideApply as a sync option. In this example it's only the Deployment that has SSA applied to it and since the Application doesn't have SSA on it, the namespace in turn will not be SSA'd. Not sure what the right course of action should be here.

@anandf
Copy link
Contributor

anandf commented Jan 16, 2024

The fix done for #16829 via PR argoproj/gitops-engine#563 seems to fix this issue as well.

I used the following application to reproduce the error (in v2.10.0-rc1) and validate the fix with the modified code.

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: kustomize-guestbook
  namespace: argocd
spec:
  destination:
    namespace: kustomize-guestbook
    server: https://kubernetes.default.svc
  project: default
  source:
    kustomize:
      namespace: kustomize-guestbook
    path: general/kustomize-guestbook
    repoURL: https://github.com/morey-tech/argocd-example-apps/
    targetRevision: ssa-createnamespace-test
  syncPolicy:
    automated:
      selfHeal: true
    syncOptions:
      - CreateNamespace=true

@leoluz
Copy link
Collaborator

leoluz commented Jan 17, 2024

I ran some tests yesterday and I understand the problem:

  1. Server side apply was implemented configuring the kubectl library to set the ServerSideApply flag with what was defined in the sync context.
  2. During sync Argo CD will first (by default) apply all resources in dry-run mode to make sure that all yamls are valid.
  3. If sync context is set to run with ServerSideApply, it will also run the dry-run phase in that mode.
  4. By the time the server-side apply was implemented, the dry-run phase was always executed with dry-run=client (which was ignored by the kubectl lib here).
  5. This caused this bug and it was attempted to be fixed by setting the dry-run=server during ServerSideApply syncs in this PR.
  6. Setting dry-run=server creates a new problem as it will validate if the namespace exists in the server during the dry-run phase. This fails syncs for apps that request to auto create namespace as described in this issue.

In my opinion the better way to solve this problem is, regardless if the sync context is defined to sync with ServerSideApply, the dry-run phase should always run with client-side-apply and dry-run=client. This will address all the problems mentioned above and the implementation will be simpler. I think that this direction should be taken instead of this, this and this.

Related to #16829

cc @pasha-codefresh , @anandf, @morey-tech

@MattiasAng
Copy link

@leoluz I am not gonna say what's wrong or right in terms of implementation, but I think it is important to know that a server dry run will catch issues that would not be shown in a client dry run. For us, a client dry run is basically useless for what we're trying to test before applying a manifest.

A good example of this is when using any form of policy controller that validates the manifest, for example Kyverno.

While I understand that the first reasoning behind implementing it might have been the wrong direction, I think having the ability to run with dry-run=server would be a nice-to-have feature.

@leoluz
Copy link
Collaborator

leoluz commented Jan 17, 2024

While I understand that the first reasoning behind implementing it might have been the wrong direction, I think having the ability to run with dry-run=server would be a nice-to-have feature.

@MattiasAng I agree with you and the feature that you described is already implemented and will be available as part of Argo CD 2.10 release. It is called ServerSide Diff and when enabled will calculate diffs using server-side apply in dryrun mode. This will take into consideration validation and mutation webhooks use-cases like what you are describing. We blogged about it here.

The current dry-run phase that is currently executed on every sync will be obsolete (and possibly removed) when server-side diff is promoted as the main diff strategy.

@MattiasAng
Copy link

@leoluz Thanks for the clarification, seems like I was missing some context.

@leoluz
Copy link
Collaborator

leoluz commented Jan 23, 2024

@morey-tech Given that we just merged the PRs(argoproj/gitops-engine#564 and #16942) with the fix suggested here can you give it another try with the latest master build?

@leoluz
Copy link
Collaborator

leoluz commented Feb 6, 2024

Closing this for now as this is addressed by argoproj/gitops-engine#564 and #16942.
@morey-tech please feel free to reopen if the issue remains.

@leoluz leoluz closed this as completed Feb 6, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

9 participants