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
337 changes: 334 additions & 3 deletions apps/console/internal/app/graph/generated/generated.go

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions apps/console/internal/app/graph/schema.graphqls
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ type Mutation {

core_updateVPNDevicePorts(deviceName: String!,ports: [PortIn!]!): Boolean! @isLoggedInAndVerified @hasAccount
core_updateVPNDeviceEnv(deviceName: String!,projectName: String!, envName: String!): Boolean! @isLoggedInAndVerified @hasAccount
core_updateVpnDeviceNs(deviceName: String!,ns: String!): Boolean! @isLoggedInAndVerified @hasAccount
core_updateVpnClusterName(deviceName: String!,clusterName: String!): Boolean! @isLoggedInAndVerified @hasAccount

core_deleteVPNDevice(deviceName: String!): Boolean! @isLoggedInAndVerified @hasAccount
}
Expand Down
40 changes: 30 additions & 10 deletions apps/console/internal/app/graph/schema.resolvers.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
type ConsoleVPNDevice @shareable {
accountName: String!
apiVersion: String
clusterName: String
createdBy: Github__com___kloudlite___api___common__CreatedOrUpdatedBy!
creationTime: Date!
displayName: String!
Expand Down Expand Up @@ -33,6 +34,7 @@ type ConsoleVPNDevicePaginatedRecords @shareable {

input ConsoleVPNDeviceIn {
apiVersion: String
clusterName: String
displayName: String!
environmentName: String
kind: String
Expand Down
3 changes: 3 additions & 0 deletions apps/console/internal/domain/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,9 @@ type Domain interface {
OnVPNDeviceApplyError(ctx ConsoleContext, errMsg string, name string, opts UpdateAndDeleteOpts) error
OnVPNDeviceDeleteMessage(ctx ConsoleContext, device entities.ConsoleVPNDevice) error
OnVPNDeviceUpdateMessage(ctx ConsoleContext, device entities.ConsoleVPNDevice, status types.ResourceStatus, opts UpdateAndDeleteOpts, clusterName string) error

UpdateVpnDeviceCluster(ctx ConsoleContext, devName string, clusterName string) error
UpdateVpnDeviceNs(ctx ConsoleContext, devName string, namespace string) error
}

type PublishMsg string
Expand Down
43 changes: 42 additions & 1 deletion apps/console/internal/domain/domain.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
msgTypes "github.com/kloudlite/api/pkg/messaging/types"
"github.com/kloudlite/api/pkg/types"

// "github.com/kloudlite/operator/pkg/constants"
"github.com/kloudlite/api/constants"

t "github.com/kloudlite/api/apps/tenant-agent/types"
Expand Down Expand Up @@ -91,6 +90,47 @@ type K8sContext interface {
GetAccountName() string
}

func (d *domain) applyK8sResourceOnCluster(ctx K8sContext, clusterName string, obj client.Object, recordVersion int) error {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (llm): The new function applyK8sResourceOnCluster is a good addition for applying resources directly to a specified cluster. Ensure that the clusterName is validated before applying the resource to avoid potential issues with non-existent or incorrect cluster names.


if clusterName == "" {
d.logger.Infof("skipping apply of k8s resource %s/%s, cluster name not provided", obj.GetNamespace(), obj.GetName())
return nil
}

if obj.GetObjectKind().GroupVersionKind().Empty() {
return errors.Newf("object GVK is not set, can not apply")
}

ann := obj.GetAnnotations()
if ann == nil {
ann = make(map[string]string, 1)
}
ann[constants.RecordVersionKey] = fmt.Sprintf("%d", recordVersion)
obj.SetAnnotations(ann)

m, err := fn.K8sObjToMap(obj)
if err != nil {
return errors.NewE(err)
}
b, err := json.Marshal(t.AgentMessage{
AccountName: ctx.GetAccountName(),
ClusterName: clusterName,
Action: t.ActionApply,
Object: m,
})
if err != nil {
return errors.NewE(err)
}

subject := common.GetTenantClusterMessagingTopic(ctx.GetAccountName(), clusterName)

err = d.producer.Produce(ctx, msgTypes.ProduceMsg{
Subject: subject,
Payload: b,
})
return errors.NewE(err)
}

func (d *domain) applyK8sResource(ctx K8sContext, projectName string, obj client.Object, recordVersion int) error {
clusterName, err := d.getClusterAttachedToProject(ctx, projectName)
if err != nil {
Expand Down Expand Up @@ -440,6 +480,7 @@ func cloneResource[T repos.Entity](ctx ResourceContext, d *domain, repoName repo
return errors.NewE(err)
}
}

if err := d.applyK8sResource(ctx, ctx.ProjectName, obj, 0); err != nil {
return errors.NewE(err)
}
Expand Down
2 changes: 2 additions & 0 deletions apps/console/internal/domain/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ func (d *domain) CreateProject(ctx ConsoleContext, project entities.Project) (*e

project.IncrementRecordVersion()

// TODO: check if provided cluster is exists in account

project.CreatedBy = common.CreatedOrUpdatedBy{
UserId: ctx.UserId,
UserName: ctx.UserName,
Expand Down
99 changes: 90 additions & 9 deletions apps/console/internal/domain/vpn-device.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ func (d *domain) getClusterFromDevice(ctx ConsoleContext, device *entities.Conso
return "", errors.Newf("device is nil")
}

if device.ProjectName == nil && device.ClusterName != nil {
return *device.ClusterName, nil
}

if device.ProjectName == nil {
return "", errors.NewE(errors.Newf("project name is nil"))
}
Expand All @@ -62,13 +66,14 @@ func (d *domain) updateVpnOnCluster(ctx ConsoleContext, ndev, xdev *entities.Con
return errors.NewE(err)
}

if ndev.ProjectName != nil && ndev.EnvironmentName != nil {
if (ndev.ProjectName != nil && ndev.EnvironmentName != nil) || ndev.ClusterName != nil {
if err := d.applyVPNDevice(ctx, ndev); err != nil {
return errors.NewE(err)
}
}

if (xdev.ProjectName != nil) && (*xdev.ProjectName != *ndev.ProjectName) {
if (xdev.ProjectName != nil && (ndev.ProjectName == nil || *xdev.ProjectName != *ndev.ProjectName)) ||
(xdev.ClusterName != nil && (ndev.ClusterName == nil || *xdev.ClusterName != *ndev.ClusterName)) {
xdev.Spec.Disabled = true
if err := d.applyVPNDevice(ctx, xdev); err != nil {
return errors.NewE(err)
Expand Down Expand Up @@ -143,6 +148,14 @@ func (d *domain) applyVPNDevice(ctx ConsoleContext, device *entities.ConsoleVPND
if err := d.applyK8sResource(ctx, *device.ProjectName, &device.Device, device.RecordVersion); err != nil {
return errors.NewE(err)
}

return nil
}

if device.ClusterName != nil {
if err := d.applyK8sResourceOnCluster(ctx, *device.ClusterName, &device.Device, device.RecordVersion); err != nil {
return errors.NewE(err)
}
}

return nil
Expand Down Expand Up @@ -219,7 +232,39 @@ func (d *domain) CreateVPNDevice(ctx ConsoleContext, device entities.ConsoleVPND
return nDevice, nil
}

func (d *domain) UpdateVPNDevice(ctx ConsoleContext, device entities.ConsoleVPNDevice) (*entities.ConsoleVPNDevice, error) {
func (d *domain) UpdateVpnDeviceNs(ctx ConsoleContext, devName string, namespace string) (device error) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (llm): The function UpdateVpnDeviceNs is introduced to update the namespace of a VPN device. It's crucial to ensure that the namespace provided is valid and exists within the cluster to avoid any inconsistencies.

if err := d.canPerformActionInDevice(ctx, iamT.UpdateVPNDevice, devName); err != nil {
return errors.NewE(err)
}

xDevice, err := d.findVPNDevice(ctx, devName)
if err != nil {
return errors.NewE(err)
}

patchForUpdate := common.PatchForUpdate(
ctx,
xDevice,
common.PatchOpts{
XPatch: repos.Document{
fc.ConsoleVPNDeviceSpecActiveNamespace: namespace,
},
})

upDevice, err := d.vpnDeviceRepo.PatchById(ctx, xDevice.Id, patchForUpdate)
if err != nil {
return errors.NewE(err)
}
d.resourceEventPublisher.PublishConsoleEvent(ctx, entities.ResourceTypeVPNDevice, devName, PublishUpdate)

if err := d.applyVPNDevice(ctx, upDevice); err != nil {
return errors.NewE(err)
}

return nil
}

func (d *domain) updateVpnDevice(ctx ConsoleContext, device entities.ConsoleVPNDevice, projectName, envName, clusterName *string) (*entities.ConsoleVPNDevice, error) {
if err := d.canPerformActionInDevice(ctx, iamT.UpdateVPNDevice, device.Name); err != nil {
return nil, errors.NewE(err)
}
Expand All @@ -233,23 +278,35 @@ func (d *domain) UpdateVPNDevice(ctx ConsoleContext, device entities.ConsoleVPND

device.Spec.ActiveNamespace = nil

if device.ProjectName != nil && device.EnvironmentName != nil {
activeNamespace, err := d.envTargetNamespace(ctx, *device.ProjectName, *device.EnvironmentName)
if clusterName != nil && !slices.Contains(linkedClusters, *clusterName) {
linkedClusters = append(linkedClusters, *clusterName)
}

if projectName != nil && envName != nil {
activeNamespace, err := d.envTargetNamespace(ctx, *projectName, *envName)
if err != nil {
return nil, errors.NewE(err)
}
device.Spec.ActiveNamespace = &activeNamespace

clusterName, err := d.getClusterAttachedToProject(ctx, *device.ProjectName)
cName, err := d.getClusterAttachedToProject(ctx, *projectName)
if err != nil {
return nil, errors.NewE(err)
}

if clusterName != nil && !slices.Contains(linkedClusters, *clusterName) {
linkedClusters = append(linkedClusters, *clusterName)
if cName != nil && !slices.Contains(linkedClusters, *cName) {
linkedClusters = append(linkedClusters, *cName)
}
}

device.ClusterName = nil
if clusterName != nil {
device.ClusterName = clusterName

device.ProjectName = nil
device.EnvironmentName = nil
}

patchForUpdate := common.PatchForUpdate(
ctx,
&device,
Expand All @@ -258,6 +315,7 @@ func (d *domain) UpdateVPNDevice(ctx ConsoleContext, device entities.ConsoleVPND
fc.ConsoleVPNDeviceSpec: device.Spec,
fields.ProjectName: device.ProjectName,
fields.EnvironmentName: device.EnvironmentName,
fields.ClusterName: device.ClusterName,
fc.ConsoleVPNDeviceLinkedClusters: linkedClusters,
},
})
Expand All @@ -279,6 +337,10 @@ func (d *domain) UpdateVPNDevice(ctx ConsoleContext, device entities.ConsoleVPND
return upDevice, nil
}

func (d *domain) UpdateVPNDevice(ctx ConsoleContext, device entities.ConsoleVPNDevice) (*entities.ConsoleVPNDevice, error) {
return d.updateVpnDevice(ctx, device, device.ProjectName, device.EnvironmentName, nil)
}

func (d *domain) DeleteVPNDevice(ctx ConsoleContext, name string) error {
if err := d.canPerformActionInDevice(ctx, iamT.DeleteVPNDevice, name); err != nil {
return errors.NewE(err)
Expand Down Expand Up @@ -356,13 +418,32 @@ func (d *domain) UpdateVpnDeviceEnvironment(ctx ConsoleContext, devName string,
xdevice.ProjectName = &projectName
xdevice.EnvironmentName = &envName

_, err = d.UpdateVPNDevice(ctx, *xdevice)
_, err = d.updateVpnDevice(ctx, *xdevice, xdevice.ProjectName, xdevice.EnvironmentName, nil)
if err != nil {
return errors.NewE(err)
}
return nil
}

func (d *domain) UpdateVpnDeviceCluster(ctx ConsoleContext, devName string, clusterName string) error {
d.canPerformActionInAccount(ctx, iamT.GetCluster)

xdevice, err := d.findVPNDevice(ctx, devName)
if err != nil {
return errors.NewE(err)
}

// TODO: check if cluster exists in account

xdevice.ClusterName = &clusterName
_, err = d.updateVpnDevice(ctx, *xdevice, nil, nil, &clusterName)
if err != nil {
return errors.NewE(err)
}

return nil
}

func (d *domain) OnVPNDeviceUpdateMessage(ctx ConsoleContext, device entities.ConsoleVPNDevice, status types.ResourceStatus, opts UpdateAndDeleteOpts, clusterName string) error {
xdevice, err := d.findVPNDevice(ctx, device.Name)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions apps/console/internal/entities/vpn-device.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ type ConsoleVPNDevice struct {
AccountName string `json:"accountName" graphql:"noinput"`
ProjectName *string `json:"projectName,omitempty"`
EnvironmentName *string `json:"environmentName,omitempty"`
ClusterName *string `json:"clusterName,omitempty"`

WireguardConfig t.EncodedString `json:"wireguardConfig,omitempty" graphql:"noinput" struct-json-path:",ignore-nesting"`

Expand Down
4 changes: 4 additions & 0 deletions apps/infra/internal/domain/clusters.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ func (d *domain) createTokenSecret(ctx InfraContext, ps *entities.CloudProviderS
}

func (d *domain) GetClusterAdminKubeconfig(ctx InfraContext, clusterName string) (*string, error) {
if err := d.canPerformActionInAccount(ctx, iamT.UpdateCluster); err != nil {
return nil, errors.NewE(err)
}

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