Skip to content
This repository was archived by the owner on Jun 11, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 0 additions & 15 deletions .github/ISSUE_TEMPLATE/sweep-template.yml

This file was deleted.

3 changes: 0 additions & 3 deletions .tools/nvim/__http__/accounts/accounts.graphql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,6 @@ query: |+
# labels
name
}
spec {
targetNamespace
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion .tools/nvim/__http__/auth/auth.graphql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ query: |+
}
}
variables:
token: "***********************************"
token: "{{.verify_token}}"

---

Expand Down
7 changes: 3 additions & 4 deletions .tools/nvim/__http__/infra/clusters.graphql.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
---
global:
accountName: kloudlite-dev
clusterName: sample-cluster
clusterName: sample-cluster2

providerSecretName: "aws-creds"
providerSecretNamespace: "kl-account-kloudlite-dev"
providerSecretName: "aws-283277"
providerSecretNamespace: "kl-account-new-prod-team"
---

label: Create Cluster
Expand Down
2 changes: 1 addition & 1 deletion .tools/nvim/__http__/infra/nodepools.graphql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ global:
providerNamespace: s1
providerSecretName: provider-sample

clusterName: sample-cluster
clusterName: sample-cluster2
# clusterName: teshdhr-797053
---

Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Changelog
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [v1.0.5] - 2024-02-02

### Added

- [apps/infra] tenant clusters installation of `charts/kloudlite-agent` is now installed and managed by infra API. It is done to ensure that kloudlite can upgrade those releases, as new releases arrive
4 changes: 2 additions & 2 deletions apps/auth/Taskfile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ version: '3'
dotenv: [".secrets/oauth.env", ".secrets/env"]

vars:
ImagePrefix: "ghcr.io/kloudlite/platform/apis"
ImagePrefix: "ghcr.io/kloudlite/api"

tasks:
run:
Expand Down Expand Up @@ -32,7 +32,7 @@ tasks:
- sh: '[ -n "{{.Out}}" ]'
msg: var Out must have a value
cmds:
- go build -v -ldflags="-s -w -X kloudlite.io/common.BuiltAt=\"{{.BuiltAt}}\"" -o {{.Out}}
- go build -v -ldflags="-s -w -X github.com/kloudlite/api/common.BuiltAt=\"{{.BuiltAt}}\"" -o {{.Out}}
- upx {{.Out}}

local-build:
Expand Down
4 changes: 2 additions & 2 deletions apps/infra/internal/app/grpc-server.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,8 +81,8 @@ func (g *grpcServer) GetNodepool(ctx context.Context, in *infra.GetNodepoolIn) (
}

return &infra.GetNodepoolOut{
IACJobName: np.Spec.IAC.JobName,
IACJobNamespace: np.Spec.IAC.JobNamespace,
// IACJobName: np.Spec.IAC.JobName,
// IACJobNamespace: np.Spec.IAC.JobNamespace,
}, nil
}

Expand Down
73 changes: 71 additions & 2 deletions apps/infra/internal/domain/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import (
"fmt"

iamT "github.com/kloudlite/api/apps/iam/types"
"github.com/kloudlite/api/apps/infra/internal/domain/templates"
fc "github.com/kloudlite/api/apps/infra/internal/entities/field-constants"
"github.com/kloudlite/api/common"
"github.com/kloudlite/api/common/fields"
message_office_internal "github.com/kloudlite/api/grpc-interfaces/kloudlite.io/rpc/message-office-internal"
ct "github.com/kloudlite/operator/apis/common-types"
"github.com/kloudlite/operator/operators/resource-watcher/types"
"sigs.k8s.io/yaml"

"github.com/kloudlite/api/apps/infra/internal/entities"
clustersv1 "github.com/kloudlite/operator/apis/clusters/v1"
Expand All @@ -18,6 +20,7 @@ import (
fn "github.com/kloudlite/api/pkg/functions"
"github.com/kloudlite/api/pkg/repos"
t "github.com/kloudlite/api/pkg/types"
crdsv1 "github.com/kloudlite/operator/apis/crds/v1"
corev1 "k8s.io/api/core/v1"
apiErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
Expand Down Expand Up @@ -56,8 +59,8 @@ func (d *domain) createTokenSecret(ctx InfraContext, ps *entities.CloudProviderS
return nil, errors.NewE(err)
}

secret.StringData = map[string]string{
keyClusterToken: tout.ClusterToken,
secret.Data = map[string][]byte{
keyClusterToken: []byte(tout.ClusterToken),
}

return secret, nil
Expand Down Expand Up @@ -256,9 +259,75 @@ func (d *domain) CreateCluster(ctx InfraContext, cluster entities.Cluster) (*ent

d.resourceEventPublisher.PublishInfraEvent(ctx, ResourceTypeCluster, nCluster.Name, PublishAdd)

if err := d.applyHelmKloudliteAgent(ctx, nCluster, string(tokenScrt.Data[keyClusterToken])); err != nil {
return nil, errors.NewE(err)
}

return nCluster, nil
}

func (d *domain) applyHelmKloudliteAgent(ctx InfraContext, cluster *entities.Cluster, clusterToken string) error {
b, err := templates.Read(templates.HelmKloudliteAgent)
if err != nil {
return errors.NewE(err)
}

b2, err := templates.ParseBytes(b, map[string]any{
"account-name": ctx.AccountName,
"cluster-name": cluster.Name,
"cluster-token": clusterToken,

"kloudlite-release": d.env.KloudliteRelease,
"message-office-grpc-addr": d.env.MessageOfficeExternalGrpcAddr,
})
if err != nil {
return errors.NewE(err)
}

var m map[string]any
if err := yaml.Unmarshal(b2, &m); err != nil {
return errors.NewE(err)
}

helmChart, err := fn.JsonConvert[crdsv1.HelmChart](m)
if err != nil {
return errors.NewE(err)
}

hr := entities.HelmRelease{
HelmChart: helmChart,
ResourceMetadata: common.ResourceMetadata{
DisplayName: fmt.Sprintf("kloudlite agent %s", d.env.KloudliteRelease),
CreatedBy: common.CreatedOrUpdatedBy{
UserId: "kloudlite-platform",
UserName: "kloudlite-platform",
UserEmail: "kloudlite-platform",
},
LastUpdatedBy: common.CreatedOrUpdatedBy{
UserId: "kloudlite-platform",
UserName: "kloudlite-platform",
UserEmail: "kloudlite-platform",
},
},
AccountName: ctx.AccountName,
ClusterName: cluster.Name,
SyncStatus: t.GenSyncStatus(t.SyncActionApply, 0),
}

hr.IncrementRecordVersion()

uhr, err := d.upsertHelmRelease(ctx, cluster.Name, &hr)
if err != nil {
return errors.NewE(err)
}

if err := d.resDispatcher.ApplyToTargetCluster(ctx, cluster.Name, &uhr.HelmChart, uhr.RecordVersion); err != nil {
return errors.NewE(err)
}

return nil
}

func (d *domain) ListClusters(ctx InfraContext, mf map[string]repos.MatchFilter, pagination repos.CursorPagination) (*repos.PaginatedRecord[*entities.Cluster], error) {
if err := d.canPerformActionInAccount(ctx, iamT.ListClusters); err != nil {
return nil, errors.NewE(err)
Expand Down
16 changes: 16 additions & 0 deletions apps/infra/internal/domain/helm-release.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,22 @@ func (d *domain) findHelmRelease(ctx InfraContext, clusterName string, hrName st
return cluster, nil
}

func (d *domain) upsertHelmRelease(ctx InfraContext, clusterName string, hr *entities.HelmRelease) (*entities.HelmRelease, error) {
cluster, err := d.helmReleaseRepo.Upsert(ctx, repos.Filter{
fields.ClusterName: clusterName,
fields.AccountName: ctx.AccountName,
fields.MetadataName: hr.Name,
}, hr)
if err != nil {
return nil, errors.NewE(err)
}

if cluster == nil {
return nil, errors.Newf("could not upsert helm release %s", hr.Name)
}
return cluster, nil
}

func (d *domain) ListHelmReleases(ctx InfraContext, clusterName string, mf map[string]repos.MatchFilter, pagination repos.CursorPagination) (*repos.PaginatedRecord[*entities.HelmRelease], error) {
if err := d.canPerformActionInAccount(ctx, iamT.ListHelmReleases); err != nil {
return nil, errors.NewE(err)
Expand Down
57 changes: 4 additions & 53 deletions apps/infra/internal/domain/nodepool.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
package domain

import (
"fmt"

iamT "github.com/kloudlite/api/apps/iam/types"
fc "github.com/kloudlite/api/apps/infra/internal/entities/field-constants"
"github.com/kloudlite/api/common"
Expand All @@ -13,15 +11,10 @@ import (
"github.com/kloudlite/operator/operators/resource-watcher/types"

"github.com/kloudlite/api/apps/infra/internal/entities"
fn "github.com/kloudlite/api/pkg/functions"
"github.com/kloudlite/api/pkg/repos"
t "github.com/kloudlite/api/pkg/types"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

const tenantControllerNamespace = "kloudlite"

func (d *domain) applyNodePool(ctx InfraContext, np *entities.NodePool) error {
addTrackingId(&np.NodePool, np.Id)
return d.resDispatcher.ApplyToTargetCluster(ctx, np.ClusterName, &np.NodePool, np.RecordVersion)
Expand All @@ -40,57 +33,11 @@ func (d *domain) CreateNodePool(ctx InfraContext, clusterName string, nodepool e
}
nodepool.LastUpdatedBy = nodepool.CreatedBy

out, err := d.accountsSvc.GetAccount(ctx, string(ctx.UserId), ctx.AccountName)
if err != nil {
return nil, errors.NewE(err)
}

cluster, err := d.findCluster(ctx, clusterName)
if err != nil {
return nil, errors.NewE(err)
}

// fetch cloud provider credentials, access key, and ps key
credsSecret := &corev1.Secret{}
if err := d.k8sClient.Get(ctx, fn.NN(cluster.Spec.CredentialsRef.Namespace, cluster.Spec.CredentialsRef.Name), credsSecret); err != nil {
return nil, errors.NewE(err)
}

providerSecret := &corev1.Secret{
TypeMeta: metav1.TypeMeta{
Kind: "Secret",
APIVersion: "v1",
},
ObjectMeta: metav1.ObjectMeta{
Name: "provider-creds",
Namespace: tenantControllerNamespace,
},
Data: map[string][]byte{
"access_key": credsSecret.Data[cluster.Spec.CredentialKeys.KeyAccessKey],
"secret_key": credsSecret.Data[cluster.Spec.CredentialKeys.KeySecretKey],
},
}

if err := d.resDispatcher.ApplyToTargetCluster(ctx, clusterName, providerSecret, 1); err != nil {
return nil, errors.NewE(err)
}

nodepool.Spec.IAC = clustersv1.InfrastuctureAsCode{
StateS3BucketName: fmt.Sprintf("kl-%s", out.AccountId),
StateS3BucketRegion: "ap-south-1",
StateS3BucketFilePath: fmt.Sprintf("iac/kl-account-%s/cluster-%s/nodepool-%s.tfstate", ctx.AccountName, clusterName, nodepool.Name),
CloudProviderAccessKey: ct.SecretKeyRef{
Name: providerSecret.Name,
Namespace: providerSecret.Namespace,
Key: "access_key",
},
CloudProviderSecretKey: ct.SecretKeyRef{
Name: providerSecret.Name,
Namespace: providerSecret.Namespace,
Key: "secret_key",
},
}

ps, err := d.findProviderSecret(ctx, cluster.Spec.CredentialsRef.Name)
if err != nil {
return nil, errors.NewE(err)
Expand Down Expand Up @@ -127,6 +74,10 @@ func (d *domain) CreateNodePool(ctx InfraContext, clusterName string, nodepool e
}(),
}
}
default:
{
return nil, errors.Newf("cloudprovider: %s, currently not supported", nodepool.Spec.CloudProvider)
}
}

nodepool.AccountName = ctx.AccountName
Expand Down
23 changes: 23 additions & 0 deletions apps/infra/internal/domain/templates/embed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package templates

import (
"embed"
"path/filepath"

"github.com/kloudlite/operator/pkg/templates"
)

//go:embed *
var templatesDir embed.FS

type templateFile string

const (
HelmKloudliteAgent templateFile = "./helm-charts-kloudlite-agent.yml.tpl"
)

func Read(t templateFile) ([]byte, error) {
return templatesDir.ReadFile(filepath.Join(string(t)))
}

var ParseBytes = templates.ParseBytes
Loading