argoproj / argo-cd

Declarative Continuous Deployment for Kubernetes
https://argo-cd.readthedocs.io
Apache License 2.0
17.46k stars 5.3k forks source link

ArgoCD go.mod requires k8s.io/kubernetes directly, resulting in go build unknown revision v0.0.0 #4055

Open wmgroot opened 4 years ago

wmgroot commented 4 years ago

If you are trying to resolve an environment-specific issue or have a one-off question about the edge case that does not require a feature then please consider asking a question in argocd slack channel.

Checklist:

Describe the bug

The ArgoCD go.mod file requires k8s.io/kubernetes instead of individually published kubernetes packages. https://github.com/argoproj/argo-cd/blob/master/go.mod#L80

https://github.com/kubernetes/kubernetes/issues/79384#issuecomment-505725449 According to the issue linked above, this is not supported behavior, and leads to issues with including argocd types for use with go-client.

To Reproduce

Add argocd to an external project's go.mod.

module my-module

require (
    github.com/argoproj/argo-cd v1.6.2
        ...

Import the argocd types and client into your package.

package my-package

import (
    argocd "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1"
    argocdclient "github.com/argoproj/argo-cd/pkg/client/clientset/versioned"
)

Attempt to go build.

$ go build
go: finding module for package github.com/argoproj/argo-cd/pkg/client/clientset/versioned
go: found github.com/argoproj/argo-cd/pkg/client/clientset/versioned in github.com/argoproj/argo-cd v1.6.2
go: github.com/argoproj/argo-cd@v1.6.2 requires
    k8s.io/kubernetes@v1.16.6 requires
    k8s.io/api@v0.0.0: reading k8s.io/api/go.mod at revision v0.0.0: unknown revision v0.0.0

Notice you can't go build, because k8s.io/api@v0.0.0 is an unknown revision.

Expected behavior

Including argocd types is supported and compiles successfully with go build

sbose78 commented 4 years ago

Usage of this solution is fairly widespread, we could do the same https://github.com/kubernetes/kubernetes/issues/79384#issuecomment-505632294

jwelch92 commented 4 years ago

We've been using the above linked workaround but ideally we would not need replace directives in every project where we import Argo code. Argo projects should only require and import k8s.io modules as needed.

sbose78 commented 4 years ago

@jwelch92 , yeah, that would be ideal. I agree.

alexmt commented 4 years ago

Argo CD imports k8s.io/kubernetes package to perform client-side diffing and execute kubectl apply/auth reconcile programmatically instead of using fork exec.

sidheshdivekar29 commented 4 years ago

Hi, I am trying to import "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1" on client side to populate v1alpha1.AppProjectSpec{} and then json marshal it and send the data using rest api. I am hitting this exact same issue. How do I get it working with this bug being open.

shahadarsh commented 3 years ago

I saw the workaround recommended above but was wondering if we are looking at a better solution any time soon. Thanks.

shahadarsh commented 3 years ago

Hi, I am trying to import "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1" on client side to populate v1alpha1.AppProjectSpec{} and then json marshal it and send the data using rest api. I am hitting this exact same issue. How do I get it working with this bug being open.

@sidheshdivekar29 What did you end up doing? I'm also having the same issue.

sidheshdivekar29 commented 3 years ago

Hi Adarsh,

I ended up not importing the library. Since rest apis just post json body, I just defined my own structures for required rest api.

On Mon, Nov 9, 2020 at 12:06 PM Adarsh Shah notifications@github.com wrote:

Hi, I am trying to import " github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1" on client side to populate v1alpha1.AppProjectSpec{} and then json marshal it and send the data using rest api. I am hitting this exact same issue. How do I get it working with this bug being open.

@sidheshdivekar29 https://github.com/sidheshdivekar29 What did you end up doing? I'm also having the same issue.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/argoproj/argo-cd/issues/4055#issuecomment-724248413, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADYCOPO3FQQCMXPAESJC2Q3SPBDTVANCNFSM4PV7WFYQ .

-- -Siddhesh.

shahadarsh commented 3 years ago

Hi Adarsh, I ended up not importing the library. Since rest apis just post json body, I just defined my own structures for required rest api. On Mon, Nov 9, 2020 at 12:06 PM Adarsh Shah @.***> wrote: Hi, I am trying to import " github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1" on client side to populate v1alpha1.AppProjectSpec{} and then json marshal it and send the data using rest api. I am hitting this exact same issue. How do I get it working with this bug being open. @sidheshdivekar29 https://github.com/sidheshdivekar29 What did you end up doing? I'm also having the same issue. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#4055 (comment)>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADYCOPO3FQQCMXPAESJC2Q3SPBDTVANCNFSM4PV7WFYQ . -- -Siddhesh.

@sidheshdivekar29 Thanks. I was actually able to make it work with v1.5.5.

Added following:

replace (
    github.com/argoproj/argo-cd => github.com/argoproj/argo-cd v1.5.5
)
sidheshdivekar29 commented 3 years ago

Great Adarsh, Thanks for letting me know.

On Fri, Nov 13, 2020 at 8:41 AM Adarsh Shah notifications@github.com wrote:

Hi Adarsh, I ended up not importing the library. Since rest apis just post json body, I just defined my own structures for required rest api. … <#m3495484218996143026> On Mon, Nov 9, 2020 at 12:06 PM Adarsh Shah @.***> wrote: Hi, I am trying to import " github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1" on client side to populate v1alpha1.AppProjectSpec{} and then json marshal it and send the data using rest api. I am hitting this exact same issue. How do I get it working with this bug being open. @sidheshdivekar29 https://github.com/sidheshdivekar29 https://github.com/sidheshdivekar29 What did you end up doing? I'm also having the same issue. — You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub <#4055 (comment) https://github.com/argoproj/argo-cd/issues/4055#issuecomment-724248413>, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADYCOPO3FQQCMXPAESJC2Q3SPBDTVANCNFSM4PV7WFYQ . -- -Siddhesh.

@sidheshdivekar29 https://github.com/sidheshdivekar29 Thanks. I was actually able to make it work with v1.5.5.

Added following:

replace (

github.com/argoproj/argo-cd => github.com/argoproj/argo-cd v1.5.5

)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/argoproj/argo-cd/issues/4055#issuecomment-726867355, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADYCOPJ7CURE5XL6WPMIXC3SPVOSDANCNFSM4PV7WFYQ .

-- -Siddhesh.

sbose78 commented 3 years ago

There are no direct references to k8s.io/kubernetes anymore. However, projects importing ArgoCD may still face an issue because ArgoCD imports gitops-engine which still uses k8s.io/kubernetes directly. :)

dejanzele commented 3 years ago

Hello,

Here is my go.mod file where I managed to reference github.com/argoproj/argo-cd/v2 v2.0.5

require github.com/argoproj/argo-cd/v2 v2.0.5

replace (
    github.com/argoproj/gitops-engine => github.com/argoproj/gitops-engine v0.4.0
    k8s.io/api => k8s.io/api v0.21.0
    k8s.io/apiextensions-apiserver => k8s.io/apiextensions-apiserver v0.21.4
    k8s.io/apimachinery => k8s.io/apimachinery v0.21.4
    k8s.io/apiserver => k8s.io/apiserver v0.21.4
    k8s.io/cli-runtime => k8s.io/cli-runtime v0.21.4
    k8s.io/client-go => k8s.io/client-go v0.21.4
    k8s.io/cloud-provider => k8s.io/cloud-provider v0.21.4
    k8s.io/cluster-bootstrap => k8s.io/cluster-bootstrap v0.21.4
    k8s.io/code-generator => k8s.io/code-generator v0.21.4
    k8s.io/component-base => k8s.io/component-base v0.21.4
    k8s.io/component-helpers => k8s.io/component-helpers v0.21.4
    k8s.io/controller-manager => k8s.io/controller-manager v0.21.4
    k8s.io/cri-api => k8s.io/cri-api v0.21.4
    k8s.io/csi-translation-lib => k8s.io/csi-translation-lib v0.21.4
    k8s.io/kube-aggregator => k8s.io/kube-aggregator v0.21.4
    k8s.io/kube-controller-manager => k8s.io/kube-controller-manager v0.21.4
    k8s.io/kube-proxy => k8s.io/kube-proxy v0.21.4
    k8s.io/kube-scheduler => k8s.io/kube-scheduler v0.21.4
    k8s.io/kubectl => k8s.io/kubectl v0.21.4
    k8s.io/kubelet => k8s.io/kubelet v0.21.4
    k8s.io/kubernetes => k8s.io/kubernetes v1.21.0
    k8s.io/legacy-cloud-providers => k8s.io/legacy-cloud-providers v0.21.4
    k8s.io/metrics => k8s.io/metrics v0.21.4
    k8s.io/mount-utils => k8s.io/mount-utils v0.21.4
    k8s.io/pod-security-admission => k8s.io/pod-security-admission v0.22.0
    k8s.io/sample-apiserver => k8s.io/sample-apiserver v0.21.4
)
shahadarsh commented 3 years ago

Gracias @dejanzele

jrhoward commented 1 year ago

~this script worked nicely for me which is further down in previously suggested link~ https://github.com/kubernetes/kubernetes/issues/79384#issuecomment-521493597

Decided to go with the rest client and marshaling of resources

Usage of this solution is fairly widespread, we could do the same kubernetes/kubernetes#79384 (comment)

jrhoward commented 1 year ago

ok after knowing my solution above was a terrible hack with the potential for being a maintenance nightmare I persisted on looking for a better solution and found this article:

https://itnext.io/generically-working-with-kubernetes-resources-in-go-53bce678f887

works perfectly for reading resources at least

package main

import (
    "context"
    "fmt"

    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    "k8s.io/apimachinery/pkg/runtime/schema"
    "k8s.io/client-go/dynamic"
    ctrl "sigs.k8s.io/controller-runtime"
)

func main() {
    ctx := context.Background()
    config := ctrl.GetConfigOrDie()
    dynamic := dynamic.NewForConfigOrDie(config)

    namespace := "argocd"
    items, err := GetResourcesDynamically(dynamic, ctx,
        "argoproj.io", "v1alpha1", "applications", namespace)
    if err != nil {
        fmt.Println(err)
    } else {
        for _, item := range items {
            fmt.Printf("%+v\n", item)
        }
    }
}

func GetResourcesDynamically(dynamic dynamic.Interface, ctx context.Context,
    group string, version string, resource string, namespace string) (
    []unstructured.Unstructured, error) {

    resourceId := schema.GroupVersionResource{
        Group:    group,
        Version:  version,
        Resource: resource,
    }
    list, err := dynamic.Resource(resourceId).Namespace(namespace).
        List(ctx, metav1.ListOptions{})

    if err != nil {
        return nil, err
    }

    return list.Items, nil
}

kudos to https://medium.com/@jsnouff

yhrn commented 1 year ago

We also wanted to use the structs in "github.com/argoproj/argo-cd/pkg/apis/application/v1alpha1" to programmatically create Argo CD applications from a controller. Because of this problem we decided to go with creating our own structs for now. It would be really nice though if the API structs could be moved to their own module with minimal dependencies.

Any thoughts on that?

I assume that the more common reason to take a dependency on github.com/argoproj/argo-cd/v2 is just to be able to use these structs. I also realize that it might be a large refactoring given how many receiver functions there are for those structs, but in my opinion it would be a lot cleaner to separate that out from the data objects.

crenshaw-dev commented 1 year ago

@yhrn at a glance, I wouldn't be opposed to that refactor... I'm not sure how it might complicate our already-complex codegen code though.

criscola commented 4 months ago

I also strongly advise to move ArgoCD API definitions in its own module and get rid of replace directives when possible. They greatly complicate the development of third-party integrations for ArgoCD, as they require a lot of painstaking effort to find the correct dependency versions (especially for pre-existing projects which already rely on shared dependencies).

rumstead commented 4 months ago

It is currently impossible to use the last helm sdk with Argo CD modules