From 5ae3d3151c4a0e31e344d3f46a525504d86e888c Mon Sep 17 00:00:00 2001 From: nxtcoder17 Date: Tue, 6 Aug 2024 12:23:24 +0530 Subject: [PATCH] fix(clone-environment): also clones imported managed resources --- apps/console/internal/app/dns-server.go | 7 +- apps/console/internal/domain/environment.go | 27 +++- .../domain/imported-managed-resource.go | 139 +++++++++++------- apps/console/internal/domain/secret.go | 17 ++- apps/console/internal/entities/secret.go | 8 +- apps/iam/main.go | 2 +- pkg/logging/slog-logger.go | 5 + 7 files changed, 133 insertions(+), 72 deletions(-) diff --git a/apps/console/internal/app/dns-server.go b/apps/console/internal/app/dns-server.go index 5ad42ef95..603310786 100644 --- a/apps/console/internal/app/dns-server.go +++ b/apps/console/internal/app/dns-server.go @@ -66,11 +66,16 @@ func (h *dnsHandler) resolver(ctx context.Context, domain string, qtype uint16) m.RecursionDesired = true question := m.Question[0] - sp := strings.SplitN(question.Name, fmt.Sprintf(".%s", h.kloudliteDNSSuffix), 2) + sp := strings.SplitN(strings.ToLower(question.Name), fmt.Sprintf(".%s", h.kloudliteDNSSuffix), 2) if len(sp) < 2 { return nil, fmt.Errorf("failed to split into 2 over .%s", h.kloudliteDNSSuffix) } + if strings.HasSuffix(sp[0], ".local") { + // INFO: domains ending with .local are supposed to be reserved for local machine only + return h.newRR(question.Name, 7*24*60*60, "127.0.0.1") + } + comps := strings.Split(sp[0], ".") accountName := comps[len(comps)-1] hostname := strings.Join(comps[:len(comps)-1], ".") diff --git a/apps/console/internal/domain/environment.go b/apps/console/internal/domain/environment.go index ce18b88ce..476941dda 100644 --- a/apps/console/internal/domain/environment.go +++ b/apps/console/internal/domain/environment.go @@ -319,8 +319,13 @@ func (d *domain) CloneEnvironment(ctx ConsoleContext, args CloneEnvironmentArgs) } secrets, err := d.secretRepo.Find(ctx, repos.Query{ - Filter: filters, - Sort: nil, + Filter: d.secretRepo.MergeMatchFilters(filters, map[string]repos.MatchFilter{ + fc.SecretFor: { + MatchType: repos.MatchTypeExact, + Exact: nil, + }, + }), + Sort: nil, }) if err != nil { return nil, errors.NewE(err) @@ -333,6 +338,7 @@ func (d *domain) CloneEnvironment(ctx ConsoleContext, args CloneEnvironmentArgs) if err != nil { return nil, errors.NewE(err) } + routers, err := d.routerRepo.Find(ctx, repos.Query{ Filter: filters, Sort: nil, @@ -341,6 +347,14 @@ func (d *domain) CloneEnvironment(ctx ConsoleContext, args CloneEnvironmentArgs) return nil, errors.NewE(err) } + mresources, err := d.importedMresRepo.Find(ctx, repos.Query{ + Filter: filters, + Sort: nil, + }) + if err != nil { + return nil, errors.NewE(err) + } + resourceMetadata := func(dn string) common.ResourceMetadata { return common.ResourceMetadata{ DisplayName: dn, @@ -449,6 +463,15 @@ func (d *domain) CloneEnvironment(ctx ConsoleContext, args CloneEnvironmentArgs) } } + for i := range mresources { + if _, err := d.createAndApplyImportedManagedResource(resCtx, CreateAndApplyImportedManagedResourceArgs{ + ImportedManagedResourceName: mresources[i].Name, + ManagedResourceRefID: mresources[i].ManagedResourceRef.ID, + }); err != nil { + return nil, err + } + } + if err := d.syncImagePullSecretsToEnvironment(ctx, args.DestinationEnvName); err != nil { return nil, err } diff --git a/apps/console/internal/domain/imported-managed-resource.go b/apps/console/internal/domain/imported-managed-resource.go index 810850f82..18f1796e5 100644 --- a/apps/console/internal/domain/imported-managed-resource.go +++ b/apps/console/internal/domain/imported-managed-resource.go @@ -23,63 +23,12 @@ func (d *domain) ImportManagedResource(ctx ManagedResourceContext, mresName stri return nil, errors.Newf("synced output secret not found") } - outputSecret := mr.SyncedOutputSecretRef - - outputSecret.ObjectMeta = metav1.ObjectMeta{ - Name: importName, - Namespace: d.getEnvironmentTargetNamespace(*ctx.EnvironmentName), - } - - imr, err := d.importedMresRepo.Create(ctx, &entities.ImportedManagedResource{ - Name: importName, - ManagedResourceRef: entities.ManagedResourceRef{ - ID: mr.Id, - Name: mresName, - Namespace: mr.Namespace, - }, - SecretRef: common_types.SecretRef{ - Name: importName, - Namespace: outputSecret.Namespace, - }, - ResourceMetadata: common.ResourceMetadata{ - DisplayName: importName, - CreatedBy: common.CreatedOrUpdatedBy{ - UserId: ctx.UserId, - UserName: ctx.UserName, - UserEmail: ctx.UserEmail, - }, - LastUpdatedBy: common.CreatedOrUpdatedBy{ - UserId: ctx.UserId, - UserName: ctx.UserName, - UserEmail: ctx.UserEmail, - }, - }, - AccountName: ctx.AccountName, - EnvironmentName: *ctx.EnvironmentName, - SyncStatus: t.GenSyncStatus(t.SyncActionApply, mr.RecordVersion), - }) - if err != nil { - return nil, errors.NewE(err) - } - - if _, err := d.createSecret(ResourceContext{ConsoleContext: ctx.ConsoleContext, EnvironmentName: *ctx.EnvironmentName}, entities.Secret{ - Secret: *outputSecret, - AccountName: ctx.AccountName, - EnvironmentName: *ctx.EnvironmentName, - For: &entities.SecretCreatedFor{ - RefId: imr.Id, - ResourceType: entities.ResourceTypeImportedManagedResource, - Name: mresName, - Namespace: mr.Namespace, - }, - IsReadOnly: true, - }); err != nil { - return nil, errors.NewE(err) - } - - d.resourceEventPublisher.PublishEnvironmentResourceEvent(ctx.ConsoleContext, imr.EnvironmentName, entities.ResourceTypeManagedResource, imr.ManagedResourceRef.Name, PublishUpdate) - - return imr, nil + return d.createAndApplyImportedManagedResource( + ResourceContext{ConsoleContext: ctx.ConsoleContext, EnvironmentName: *ctx.EnvironmentName}, + CreateAndApplyImportedManagedResourceArgs{ + ImportedManagedResourceName: importName, + ManagedResourceRefID: mr.Id, + }) } func (d *domain) DeleteImportedManagedResource(ctx ResourceContext, importName string) error { @@ -150,6 +99,82 @@ func (d *domain) findImportedMRes(ctx ResourceContext, importName string) (*enti return imr, nil } +type CreateAndApplyImportedManagedResourceArgs struct { + ImportedManagedResourceName string + ManagedResourceRefID repos.ID +} + +func (d *domain) createAndApplyImportedManagedResource(ctx ResourceContext, args CreateAndApplyImportedManagedResourceArgs) (*entities.ImportedManagedResource, error) { + mr, err := d.mresRepo.FindById(ctx, args.ManagedResourceRefID) + if err != nil { + return nil, err + } + + if mr.SyncedOutputSecretRef == nil { + return nil, errors.Newf("synced output secret not found") + } + + outputSecret := mr.SyncedOutputSecretRef + + envTargetNamespace := d.getEnvironmentTargetNamespace(ctx.EnvironmentName) + + outputSecret.ObjectMeta = metav1.ObjectMeta{ + Name: args.ImportedManagedResourceName, + Namespace: envTargetNamespace, + } + + imr, err := d.importedMresRepo.Create(ctx, &entities.ImportedManagedResource{ + Name: args.ImportedManagedResourceName, + ManagedResourceRef: entities.ManagedResourceRef{ + ID: mr.Id, + Name: mr.Name, + Namespace: mr.Namespace, + }, + SecretRef: common_types.SecretRef{ + Name: args.ImportedManagedResourceName, + Namespace: envTargetNamespace, + }, + ResourceMetadata: common.ResourceMetadata{ + DisplayName: args.ImportedManagedResourceName, + CreatedBy: common.CreatedOrUpdatedBy{ + UserId: ctx.UserId, + UserName: ctx.UserName, + UserEmail: ctx.UserEmail, + }, + LastUpdatedBy: common.CreatedOrUpdatedBy{ + UserId: ctx.UserId, + UserName: ctx.UserName, + UserEmail: ctx.UserEmail, + }, + }, + AccountName: ctx.AccountName, + EnvironmentName: ctx.EnvironmentName, + SyncStatus: t.GenSyncStatus(t.SyncActionApply, mr.RecordVersion), + }) + if err != nil { + return nil, errors.NewE(err) + } + + if _, err := d.createSecret(ctx, entities.Secret{ + Secret: *outputSecret, + AccountName: ctx.AccountName, + EnvironmentName: ctx.EnvironmentName, + For: &entities.SecretCreatedFor{ + RefId: imr.Id, + ResourceType: entities.ResourceTypeImportedManagedResource, + Name: imr.Name, + Namespace: mr.Namespace, + }, + IsReadOnly: true, + }); err != nil { + return nil, errors.NewE(err) + } + + d.resourceEventPublisher.PublishEnvironmentResourceEvent(ctx.ConsoleContext, imr.EnvironmentName, entities.ResourceTypeImportedManagedResource, imr.Name, PublishUpdate) + + return imr, nil +} + func (d *domain) OnImportedManagedResourceDeleteMessage(ctx ConsoleContext, imrId repos.ID) error { return d.importedMresRepo.DeleteById(ctx, imrId) } diff --git a/apps/console/internal/domain/secret.go b/apps/console/internal/domain/secret.go index 492e25c90..87194c51d 100644 --- a/apps/console/internal/domain/secret.go +++ b/apps/console/internal/domain/secret.go @@ -250,17 +250,20 @@ func (d *domain) deleteSecret(ctx ResourceContext, name string) error { return errors.NewE(err) } - usecret, err := d.secretRepo.Patch( - ctx, - ctx.DBFilters().Add(fields.MetadataName, name), - common.PatchForMarkDeletion(), - ) + defer func() { + d.resourceEventPublisher.PublishResourceEvent(ctx, entities.ResourceTypeSecret, name, PublishUpdate) + }() + + filters := ctx.DBFilters().Add(fields.MetadataName, name) + + usecret, err := d.secretRepo.Patch(ctx, filters, common.PatchForMarkDeletion()) if err != nil { + if errors.Is(err, repos.ErrNoDocuments) { + return nil + } return errors.NewE(err) } - d.resourceEventPublisher.PublishResourceEvent(ctx, entities.ResourceTypeSecret, usecret.Name, PublishUpdate) - if err := d.deleteK8sResource(ctx, usecret.EnvironmentName, &usecret.Secret); err != nil { if errors.Is(err, ErrNoClusterAttached) { return d.secretRepo.DeleteById(ctx, usecret.Id) diff --git a/apps/console/internal/entities/secret.go b/apps/console/internal/entities/secret.go index 5bcb1fb2b..133c62709 100644 --- a/apps/console/internal/entities/secret.go +++ b/apps/console/internal/entities/secret.go @@ -27,10 +27,10 @@ type Secret struct { } type SecretCreatedFor struct { - RefId repos.ID `json:"refId"` - ResourceType ResourceType `json:"resourceType"` - Name string `json:"name"` - Namespace string `json:"namespace"` + RefId repos.ID `json:"refId"` + ResourceType ResourceType `json:"resourceType"` + Name string `json:"name"` + Namespace string `json:"namespace"` } func (s *Secret) GetDisplayName() string { diff --git a/apps/iam/main.go b/apps/iam/main.go index b6594807e..2e356368a 100644 --- a/apps/iam/main.go +++ b/apps/iam/main.go @@ -28,6 +28,7 @@ func main() { fx.Provide(func() logging.Logger { return logger }), + fx.Provide(func() (*env.Env, error) { return env.LoadEnv() }), @@ -45,5 +46,4 @@ func main() { common.PrintReadyBanner() <-app.Done() - } diff --git a/pkg/logging/slog-logger.go b/pkg/logging/slog-logger.go index 1e0e02d29..2b220328a 100644 --- a/pkg/logging/slog-logger.go +++ b/pkg/logging/slog-logger.go @@ -21,6 +21,11 @@ type SlogOptions struct { } func NewSlogLogger(opts SlogOptions) *slog.Logger { + // INFO: force colored output, otherwise honor the env-var `CLICOLOR_FORCE` + if _, ok := os.LookupEnv("CLICOLOR_FORCE"); !ok { + os.Setenv("CLICOLOR_FORCE", "1") + } + if opts.Writer == nil { opts.Writer = os.Stderr }