installer: fix how collection of in memory app configs is created (#74)
Was allocating non empty slice before, which followed by appends
would leave nil-s at the beginning of the slice.
Co-authored-by: Giorgi Lekveishvili <lekva@gl-mbp-m1-max.local>
diff --git a/core/installer/Makefile b/core/installer/Makefile
index 461de4d..b29233b 100644
--- a/core/installer/Makefile
+++ b/core/installer/Makefile
@@ -13,7 +13,7 @@
test: export CGO_ENABLED=0
test:
- /usr/local/go/bin/go test ./... -v
+ /usr/local/go/bin/go test ./...
bootstrap:
./pcloud --kubeconfig=../../priv/kubeconfig-hetzner bootstrap --env-name=dodo --charts-dir=../../charts --admin-pub-key=/Users/lekva/.ssh/id_rsa.pub --from-ip=192.168.100.210 --to-ip=192.168.100.240 --storage-dir=/pcloud-storage/longhorn
diff --git a/core/installer/app.go b/core/installer/app.go
index 5791780..058c31b 100644
--- a/core/installer/app.go
+++ b/core/installer/app.go
@@ -349,7 +349,7 @@
}
func createApps(configs []string) []App {
- ret := make([]App, len(configs))
+ ret := make([]App, 0)
for _, cfgFile := range configs {
cfg, err := readCueConfigFromFile(valuesTmpls, cfgFile)
if err != nil {
diff --git a/core/installer/app_test.go b/core/installer/app_test.go
index d43809c..6162299 100644
--- a/core/installer/app_test.go
+++ b/core/installer/app_test.go
@@ -1,296 +1,16 @@
package installer
import (
- "bytes"
- "context"
- _ "embed"
- "encoding/json"
- "fmt"
- "io"
- "net/http"
- "strings"
"testing"
- "time"
-
- "cuelang.org/go/cue"
- "cuelang.org/go/cue/cuecontext"
- fluxcd "github.com/fluxcd/source-controller/api/v1beta2"
- "helm.sh/helm/v3/pkg/registry"
- // "github.com/go-git/go-billy/v5/memfs"
- "github.com/go-git/go-billy/v5/osfs"
- "helm.sh/helm/v3/pkg/action"
- 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"
- "k8s.io/client-go/rest"
- "k8s.io/client-go/tools/clientcmd"
)
-//go:embed values-tmpl/rpuppy.cue
-var rpuppyConfig []byte
-
-type ContainerImage struct {
- Repository string
- Tag string
- PullPolicy string
-}
-
-type Chart struct {
- Source ChartSource
- Chart string
-}
-
-type ChartSource struct {
- Kind string
- Address string
-}
-
-type ApplicationConfig struct {
- Images map[string]ContainerImage
- Charts map[string]Chart
-}
-
-type client struct {
- clientset dynamic.Interface
-}
-
-func (c *client) CreateHelmChart(chart fluxcd.HelmChart) error {
- var buf bytes.Buffer
- if err := json.NewEncoder(&buf).Encode(chart); err != nil {
- return nil
- }
- var u unstructured.Unstructured
- if err := json.NewDecoder(&buf).Decode(&u.Object); err != nil {
- return err
- }
- _, err := c.clientset.Resource(schema.GroupVersionResource{Group: fluxcd.GroupVersion.Group, Version: fluxcd.GroupVersion.Version, Resource: "helmcharts"}).Namespace(chart.Namespace).Create(context.TODO(), &u, metav1.CreateOptions{})
- return err
-}
-
-func NewClient(kubeconfig string) (*client, error) {
- if kubeconfig == "" {
- config, err := rest.InClusterConfig()
- if err != nil {
- return nil, err
- }
- c, err := dynamic.NewForConfig(config)
- if err != nil {
- return nil, err
- }
- return &client{c}, nil
-
- } else {
- config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
- if err != nil {
- return nil, err
- }
- c, err := dynamic.NewForConfig(config)
- if err != nil {
- return nil, err
- }
- return &client{c}, nil
- }
-}
-
-const networkSchema = `
-#Network: {
- IngressClass: string
- CertificateIssuer: string
- Domain: string
-}
-
-value: %s
-
-valid: #Network & value
-`
-
-type StringFormatter struct {
- s strings.Builder
-}
-
-func (f *StringFormatter) Write(b []byte) (n int, err error) {
- return f.s.Write(b)
-}
-
-func (f *StringFormatter) Width() (wid int, ok bool) {
- return 4, true
-}
-
-func (f *StringFormatter) Precision() (prec int, ok bool) {
- return 4, true
-}
-
-func (f *StringFormatter) Flag(c int) bool {
- return false
-}
-
-func IsNetwork(v cue.Value) bool {
- if v.Value().Kind() != cue.StructKind {
- return false
- }
- value := fmt.Sprintf("%#v", v)
- s := fmt.Sprintf(networkSchema, value)
- c := cuecontext.New()
- u := c.CompileString(s)
- return u.Err() == nil && u.Validate() == nil
-}
-
-func PrintSchema(v cue.Value) {
- f, _ := v.Fields()
- for f.Next() {
- fmt.Printf("%s\n", f.Selector())
- if IsNetwork(f.Value()) {
- fmt.Println("network")
- }
- PrintSchema(f.Value())
- }
-}
-
-func TestInput(t *testing.T) {
- c := cuecontext.New()
- cfg := c.CompileBytes(rpuppyConfig)
- input := c.CompileString(`
-global: {
- id: "foo"
-}
-input: {
- network: {
- name: "public"
- ingressClass: "dodo-ingress-public"
- certificateIssuer: "rpuppu-public"
- domain: "lekva.me"
- }
- subdomain: "rpuppy"
-}
-`)
- if cfg.Err() != nil {
- panic(cfg.Err())
- }
- if err := cfg.Validate(); err != nil {
- panic(err)
- }
- PrintSchema(cfg.Eval().LookupPath(cue.ParsePath("input")))
- out := cfg.Unify(input)
- if out.Err() != nil {
- panic(out.Err())
- }
- if err := out.Validate(); err != nil {
- panic(err)
- }
- fmt.Printf("%#v\n", out)
- e := out.Eval()
- if e.Err() != nil {
- panic(out.Err())
- }
- if err := e.Validate(); err != nil {
- panic(err)
- }
- fmt.Printf("%#v\n", e)
- fmt.Println(e.IsConcrete())
-}
-
-func TestParseApplicationConfig(t *testing.T) {
- return
- var r cue.Runtime
- i, err := r.Compile("rpuppy", rpuppyConfig)
+func TestHeadscaleUser(t *testing.T) {
+ r := NewInMemoryAppRepository(CreateAllApps())
+ a, err := r.Find("headscale-user")
if err != nil {
- panic(err)
+ t.Fatal(err)
}
- var cfg ApplicationConfig
- if err := i.Value().Decode(&cfg); err != nil {
- panic(err)
+ if a == nil {
+ t.Fatal("returned app is nil")
}
- fmt.Printf("%+v\n", cfg)
- _, err = NewClient("/Users/lekva/dev/src/pcloud/priv/kubeconfig-hetzner")
- if err != nil {
- panic(err)
- }
-
- for name, c := range cfg.Charts {
- chart := fluxcd.HelmChart{
- TypeMeta: metav1.TypeMeta{
- APIVersion: fluxcd.GroupVersion.String(),
- Kind: "HelmChart",
- },
- ObjectMeta: metav1.ObjectMeta{
- Name: name,
- Namespace: "dodo",
- },
- Spec: fluxcd.HelmChartSpec{
- Chart: c.Chart,
- SourceRef: fluxcd.LocalHelmChartSourceReference{
- Kind: c.Source.Kind,
- Name: c.Source.Address,
- },
- Interval: metav1.Duration{time.Hour},
- },
- }
- fmt.Printf("%+v\n", chart)
- // if err := client.CreateHelmChart(chart); err != nil {
- // panic(err)
- // }
- }
-}
-
-type downloader struct {
- client *http.Client
-}
-
-func NewDownloader() *downloader {
- return &downloader{
- client: http.DefaultClient,
- }
-}
-
-func (d *downloader) Download(addr string, out io.Writer) error {
- resp, err := d.client.Get(addr)
- if err != nil {
- return err
- }
- if _, err := io.Copy(out, resp.Body); err != nil {
- return err
- }
- return nil
-}
-
-func TestDownload(t *testing.T) {
- return
- // fs := memfs.New()
- fs := osfs.New("/tmp")
- func() {
- f, err := fs.Create("/chart")
- if err != nil {
- panic(err)
- }
- defer f.Close()
- d := NewDownloader()
- if err := d.Download("http://localhost:9090/helmchart/dodo/rpuppy/rpuppy-0.0.1.tgz", f); err != nil {
- panic(err)
- }
- }()
- client, err := registry.NewClient()
- if err != nil {
- panic(err)
- }
- if err := client.Login("https://harbor.t46.lekva.me", registry.LoginOptBasicAuth("admin", "Harbor12345")); err != nil {
- panic(err)
- }
- defer client.Logout("https://harbor.t46.lekva.me")
- push := action.NewPushWithOpts(action.WithPushConfig(&action.Configuration{
- RegistryClient: client,
- }))
- fmt.Printf("%+v\n", push)
- res, err := push.Run("/tmp/chart", "oci://harbor.t46.lekva.me/library/charts")
- fmt.Println(res)
- if err != nil {
- panic(err)
- }
- // cfg, err := ActionConfigFactory{"/Users/lekva/dev/src/pcloud/priv/kubeconfig-hetzner"}.New("")
- // installer := action.NewInstall(config)
- // installer.Namespace = env.Name
- // installer.ReleaseName = "metallb-ns"
- // installer.Wait = true
- // installer.WaitForJobs = true
-
}
diff --git a/core/installer/values-tmpl/headscale-user.cue b/core/installer/values-tmpl/headscale-user.cue
index 5265613..fb38f8b 100644
--- a/core/installer/values-tmpl/headscale-user.cue
+++ b/core/installer/values-tmpl/headscale-user.cue
@@ -5,6 +5,7 @@
}
}
+name: "headscale-user"
namespace: "app-headscale"
images: {}