carvel-dev / kapp

kapp is a simple deployment tool focused on the concept of "Kubernetes application" — a set of resources with the same label
https://carvel.dev/kapp
Apache License 2.0
897 stars 108 forks source link

use kapp as a Go Module #564

Open universam1 opened 2 years ago

universam1 commented 2 years ago

Describe the problem/challenge you have

We'd be very excited if we would not have to shell out to Kapp from an orchestration tool but use as a Go module, which would dramatically improve the error handling and resilience.

Describe the solution you'd like

Similar to https://github.com/vmware-tanzu/carvel-ytt/blob/develop/examples/integrating-with-ytt/apis.md#as-a-go-module there could be general commitment to an exported pkg or API, that is subject to change as long as Kapp version is < 1

Anything else you would like to add:

Issue created on positive initial feedback from https://kubernetes.slack.com/archives/CH8KCCKA5/p1659086135812959


Vote on this request

This is an invitation to the community to vote on issues, to help us prioritize our backlog. Use the "smiley face" up to the right of this comment to vote.

👍 "I would like to see this addressed as soon as possible" 👎 "There are other more important things to focus on right now"

We are also happy to receive and review Pull Requests if you want to help working on this issue.

universam1 commented 2 years ago

Due to repo move a go.mod replace is required:

replace (
    github.com/k14s/kapp => github.com/vmware-tanzu/carvel-kapp v0.50.0
)
praveenrewar commented 2 years ago

Due to repo move a go.mod replace is required:

Ah, yes. @benmoss is working on a PR to update this :)

universam1 commented 2 years ago

as @praveenrewar mentioned the current requirement to build is k8s.io/client-go < v0.23

From my test a simple approach is to leverage the cobra command including all Kapp app per se. Disadvantage here is that the commands are to be generated via a string generator which is a dynamic not very safe interfacing. Example

import (
    "github.com/cppforlife/go-cli-ui/ui"
    "github.com/k14s/kapp/pkg/kapp/cmd"
)
    confUI := ui.NewConfUI(ui.NewNoopLogger())
    command := cmd.NewDefaultKappCmd(confUI)

    args := []string{
        "app-group",
        "deploy",
        "-g", "all",
        "-n", "default",
        "--directory", "myfolder",
        "-c",
        "--apply-default-update-strategy", "fallback-on-replace",
        "--yes"}
    command.SetArgs(args)
    command.Execute()

I'll research what it takes to do an explicit call to the pkg

universam1 commented 2 years ago

Alternative approach is to avoid spf13/cobra as dependency and call the structs and methods natively. Advantage is less dependencies and thus a little smaller binary, but with the rather challenging requirement to disassabmle all the default values of the structs.

Example for app-group only run:

    confUI := ui.NewConfUI(ui.NewNoopLogger())
    defer confUI.Flush()
    confUI.EnableNonInteractive()
    confUI.EnableColor()

    nonInteractiveUI := ui.NewNonInteractiveUI(confUI)

    configFactory := cmdcore.NewConfigFactoryImpl()
    configFactory.ConfigurePathResolver(func() (string, error) { return kubeConfig, nil })
    configFactory.ConfigureContextResolver(cmdcore.NewKubeconfigContextFlag().Value)
    configFactory.ConfigureYAMLResolver(cmdcore.NewKubeconfigYAMLFlag().Value)

    depsFactory := cmdcore.NewDepsFactoryImpl(configFactory, nonInteractiveUI)
    o := cmdag.NewDeployOptions(nonInteractiveUI, depsFactory, kapplogger.NewTODOLogger())

    o.AppGroupFlags.Name = "all"

    o.AppGroupFlags.NamespaceFlags.Name = "kube-system"
    o.DeployFlags.Directory = serviceFolder
    o.AppFlags.DiffFlags.Changes = false
    o.AppFlags.DeployFlags.OverrideOwnershipOfExistingResources = true
    o.AppFlags.DeployFlags.ExistingNonLabeledResourcesCheck = true
    o.AppFlags.DeployFlags.ExistingNonLabeledResourcesCheckConcurrency = 100

    o.AppFlags.ApplyFlags.ApplyIgnored = false
    o.AppFlags.ApplyFlags.Wait = true
    o.AppFlags.ApplyFlags.WaitIgnored = false
    o.AppFlags.DeleteApplyFlags.ApplyIgnored = false
    o.AppFlags.DeleteApplyFlags.Wait = true
    o.AppFlags.DeleteApplyFlags.WaitIgnored = true

    o.AppFlags.ApplyFlags.ApplyingChangesOpts.Timeout = 15 * time.Minute
    o.AppFlags.ApplyFlags.ApplyingChangesOpts.CheckInterval = time.Second
    o.AppFlags.ApplyFlags.ApplyingChangesOpts.Concurrency = 5

    o.AppFlags.ApplyFlags.WaitingChangesOpts.Timeout = 15 * time.Minute
    o.AppFlags.ApplyFlags.WaitingChangesOpts.ResourceTimeout = time.Minute
    o.AppFlags.ApplyFlags.WaitingChangesOpts.CheckInterval = time.Second
    o.AppFlags.ApplyFlags.WaitingChangesOpts.Concurrency = 5

    o.AppFlags.ApplyFlags.AddOrUpdateChangeOpts.DefaultUpdateStrategy = "fallback-on-replace"
    err = o.Run()
renuy commented 2 years ago

@praveenrewar to see the feasibility and figure out a way to make these functions as APIs

dprotaso commented 1 year ago

Following up here - it would be good for kapp to be a go module then it could be used as a library in an operator-like tool etc.