diff --git a/.tools/nvim/__http__/console/registry-image.graphql.yml b/.tools/nvim/__http__/console/registry-image.graphql.yml index 398a966dd..f1822e63c 100644 --- a/.tools/nvim/__http__/console/registry-image.graphql.yml +++ b/.tools/nvim/__http__/console/registry-image.graphql.yml @@ -1,6 +1,6 @@ --- global: - image: "test-image:t1.0.0" + image: "imageName1:imageTag1" --- label: List Registry Images @@ -56,8 +56,8 @@ variables: label: Get Registry Image URL query: |+ - query Core_getRegistryImageURL($image: String!, $meta: Map!) { - core_getRegistryImageURL(image: $image, meta: $meta) { + query Core_getRegistryImageURL { + core_getRegistryImageURL { url scriptUrl } diff --git a/apps/console/internal/app/graph/generated/generated.go b/apps/console/internal/app/graph/generated/generated.go index 792f6e81d..d6d3fcf9e 100644 --- a/apps/console/internal/app/graph/generated/generated.go +++ b/apps/console/internal/app/graph/generated/generated.go @@ -799,7 +799,7 @@ type ComplexityRoot struct { CoreGetManagedResouceOutputKeys func(childComplexity int, msvcName *string, envName *string, name string) int CoreGetManagedResource func(childComplexity int, msvcName *string, envName *string, name string) int CoreGetRegistryImage func(childComplexity int, image string) int - CoreGetRegistryImageURL func(childComplexity int, image string, meta map[string]interface{}) int + CoreGetRegistryImageURL func(childComplexity int) int CoreGetRouter func(childComplexity int, envName string, name string) int CoreGetSecret func(childComplexity int, envName string, name string) int CoreGetSecretValues func(childComplexity int, envName string, queries []*domain.SecretKeyRef) int @@ -1100,7 +1100,7 @@ type QueryResolver interface { CoreListImagePullSecrets(ctx context.Context, search *model.SearchImagePullSecrets, pq *repos.CursorPagination) (*model.ImagePullSecretPaginatedRecords, error) CoreGetImagePullSecret(ctx context.Context, name string) (*entities.ImagePullSecret, error) CoreResyncImagePullSecret(ctx context.Context, name string) (bool, error) - CoreGetRegistryImageURL(ctx context.Context, image string, meta map[string]interface{}) (*model.RegistryImageURL, error) + CoreGetRegistryImageURL(ctx context.Context) (*model.RegistryImageURL, error) CoreGetRegistryImage(ctx context.Context, image string) (*entities.RegistryImage, error) CoreListRegistryImages(ctx context.Context, pq *repos.CursorPagination) (*model.RegistryImagePaginatedRecords, error) CoreListApps(ctx context.Context, envName string, search *model.SearchApps, pq *repos.CursorPagination) (*model.AppPaginatedRecords, error) @@ -4691,12 +4691,7 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in break } - args, err := ec.field_Query_core_getRegistryImageURL_args(context.TODO(), rawArgs) - if err != nil { - return 0, false - } - - return e.complexity.Query.CoreGetRegistryImageURL(childComplexity, args["image"].(string), args["meta"].(map[string]interface{})), true + return e.complexity.Query.CoreGetRegistryImageURL(childComplexity), true case "Query.core_getRouter": if e.complexity.Query.CoreGetRouter == nil { @@ -5882,7 +5877,7 @@ type Query { core_getImagePullSecret(name: String!): ImagePullSecret @isLoggedInAndVerified @hasAccount core_resyncImagePullSecret(name: String!): Boolean! @isLoggedInAndVerified @hasAccount - core_getRegistryImageURL(image: String!, meta: Map!): RegistryImageURL! @isLoggedInAndVerified @hasAccount + core_getRegistryImageURL: RegistryImageURL! @isLoggedInAndVerified @hasAccount core_getRegistryImage(image: String!,): RegistryImage @isLoggedInAndVerified @hasAccount core_listRegistryImages(pq: CursorPaginationIn): RegistryImagePaginatedRecords @isLoggedInAndVerified @hasAccount @@ -8629,30 +8624,6 @@ func (ec *executionContext) field_Query_core_getManagedResource_args(ctx context return args, nil } -func (ec *executionContext) field_Query_core_getRegistryImageURL_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { - var err error - args := map[string]interface{}{} - var arg0 string - if tmp, ok := rawArgs["image"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("image")) - arg0, err = ec.unmarshalNString2string(ctx, tmp) - if err != nil { - return nil, err - } - } - args["image"] = arg0 - var arg1 map[string]interface{} - if tmp, ok := rawArgs["meta"]; ok { - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("meta")) - arg1, err = ec.unmarshalNMap2map(ctx, tmp) - if err != nil { - return nil, err - } - } - args["meta"] = arg1 - return args, nil -} - func (ec *executionContext) field_Query_core_getRegistryImage_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) { var err error args := map[string]interface{}{} @@ -32591,7 +32562,7 @@ func (ec *executionContext) _Query_core_getRegistryImageURL(ctx context.Context, resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { directive0 := func(rctx context.Context) (interface{}, error) { ctx = rctx // use context from middleware stack in children - return ec.resolvers.Query().CoreGetRegistryImageURL(rctx, fc.Args["image"].(string), fc.Args["meta"].(map[string]interface{})) + return ec.resolvers.Query().CoreGetRegistryImageURL(rctx) } directive1 := func(ctx context.Context) (interface{}, error) { if ec.directives.IsLoggedInAndVerified == nil { @@ -32633,7 +32604,7 @@ func (ec *executionContext) _Query_core_getRegistryImageURL(ctx context.Context, return ec.marshalNRegistryImageURL2ᚖgithubᚗcomᚋkloudliteᚋapiᚋappsᚋconsoleᚋinternalᚋappᚋgraphᚋmodelᚐRegistryImageURL(ctx, field.Selections, res) } -func (ec *executionContext) fieldContext_Query_core_getRegistryImageURL(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Query_core_getRegistryImageURL(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Query", Field: field, @@ -32649,17 +32620,6 @@ func (ec *executionContext) fieldContext_Query_core_getRegistryImageURL(ctx cont return nil, fmt.Errorf("no field named %q was found under type RegistryImageURL", field.Name) }, } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_core_getRegistryImageURL_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } return fc, nil } @@ -54773,12 +54733,12 @@ func (ec *executionContext) marshalNManagedResourceKeyValueRef2ᚖgithubᚗcom return ec._ManagedResourceKeyValueRef(ctx, sel, v) } -func (ec *executionContext) unmarshalNMap2map(ctx context.Context, v interface{}) (map[string]interface{}, error) { +func (ec *executionContext) unmarshalNMap2map(ctx context.Context, v interface{}) (map[string]any, error) { res, err := graphql.UnmarshalMap(v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNMap2map(ctx context.Context, sel ast.SelectionSet, v map[string]interface{}) graphql.Marshaler { +func (ec *executionContext) marshalNMap2map(ctx context.Context, sel ast.SelectionSet, v map[string]any) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { ec.Errorf(ctx, "the requested element is null which the schema does not allow") diff --git a/apps/console/internal/app/graph/schema.graphqls b/apps/console/internal/app/graph/schema.graphqls index 2cc5fa3b0..a22396f28 100644 --- a/apps/console/internal/app/graph/schema.graphqls +++ b/apps/console/internal/app/graph/schema.graphqls @@ -116,7 +116,7 @@ type Query { core_getImagePullSecret(name: String!): ImagePullSecret @isLoggedInAndVerified @hasAccount core_resyncImagePullSecret(name: String!): Boolean! @isLoggedInAndVerified @hasAccount - core_getRegistryImageURL(image: String!, meta: Map!): RegistryImageURL! @isLoggedInAndVerified @hasAccount + core_getRegistryImageURL: RegistryImageURL! @isLoggedInAndVerified @hasAccount core_getRegistryImage(image: String!,): RegistryImage @isLoggedInAndVerified @hasAccount core_listRegistryImages(pq: CursorPaginationIn): RegistryImagePaginatedRecords @isLoggedInAndVerified @hasAccount diff --git a/apps/console/internal/app/graph/schema.resolvers.go b/apps/console/internal/app/graph/schema.resolvers.go index 1e3c9e648..f19a2e098 100644 --- a/apps/console/internal/app/graph/schema.resolvers.go +++ b/apps/console/internal/app/graph/schema.resolvers.go @@ -526,12 +526,12 @@ func (r *queryResolver) CoreResyncImagePullSecret(ctx context.Context, name stri } // CoreGetRegistryImageURL is the resolver for the core_getRegistryImageURL field. -func (r *queryResolver) CoreGetRegistryImageURL(ctx context.Context, image string, meta map[string]interface{}) (*model.RegistryImageURL, error) { +func (r *queryResolver) CoreGetRegistryImageURL(ctx context.Context) (*model.RegistryImageURL, error) { cc, err := toConsoleContext(ctx) if err != nil { return nil, errors.NewE(err) } - imageURL, err := r.Domain.GetRegistryImageURL(cc, image, meta) + imageURL, err := r.Domain.GetRegistryImageURL(cc) if err != nil { return nil, errors.NewE(err) } diff --git a/apps/console/internal/domain/api.go b/apps/console/internal/domain/api.go index 52b574555..422cc6057 100644 --- a/apps/console/internal/domain/api.go +++ b/apps/console/internal/domain/api.go @@ -168,7 +168,7 @@ type Domain interface { ResyncEnvironment(ctx ConsoleContext, name string) error - GetRegistryImageURL(ctx ConsoleContext, image string, meta map[string]any) (*entities.RegistryImageURL, error) + GetRegistryImageURL(ctx ConsoleContext) (*entities.RegistryImageURL, error) GetRegistryImage(ctx ConsoleContext, image string) (*entities.RegistryImage, error) DeleteRegistryImage(ctx ConsoleContext, image string) error CreateRegistryImage(ctx context.Context, accountName string, image string, meta map[string]any) (*entities.RegistryImage, error) diff --git a/apps/console/internal/domain/registry-image.go b/apps/console/internal/domain/registry-image.go index ffdd4fef2..9e1304b19 100644 --- a/apps/console/internal/domain/registry-image.go +++ b/apps/console/internal/domain/registry-image.go @@ -4,7 +4,6 @@ import ( "context" "crypto/sha256" "encoding/base64" - "encoding/json" "fmt" "github.com/kloudlite/api/apps/console/internal/entities" fc "github.com/kloudlite/api/apps/console/internal/entities/field-constants" @@ -46,19 +45,12 @@ func getImageNameTag(image string) (string, string) { return parts[0], "latest" } -func (d *domain) GetRegistryImageURL(ctx ConsoleContext, image string, meta map[string]any) (*entities.RegistryImageURL, error) { +func (d *domain) GetRegistryImageURL(ctx ConsoleContext) (*entities.RegistryImageURL, error) { encodedToken := encodeAccessToken(ctx.AccountName, d.envVars.WebhookTokenHashingSecret) - imageName, imageTag := getImageNameTag(image) - - metaJSON, err := json.Marshal(meta) - if err != nil { - return nil, err - } - return &entities.RegistryImageURL{ - URL: fmt.Sprintf(`curl -X POST "%s" -H "Authorization: %s" -H "Content-Type: application/json" -d '{"image": "%s:%s", "meta": %s}'`, d.envVars.WebhookURL, encodedToken, imageName, imageTag, metaJSON), - ScriptURL: "", + URL: fmt.Sprintf(`curl -X POST "%s" -H "Authorization: %s" -H "Content-Type: application/json" -d '{"image": "imageName:imageTag", "meta": {"repository": "github", "registry": "docker", "author":"kloudlite"}}'`, d.envVars.WebhookURL, encodedToken), + ScriptURL: fmt.Sprintf(`curl "%s" | authorization=%s image=imageName:imageTag meta="repository=github,registry=docker,author=kloudlite" sh`, d.envVars.WebhookURL, encodedToken), }, nil } diff --git a/apps/console/internal/entities/field-constants/generated_constants.go b/apps/console/internal/entities/field-constants/generated_constants.go index 5cec8a8d9..e6aa1acf7 100644 --- a/apps/console/internal/entities/field-constants/generated_constants.go +++ b/apps/console/internal/entities/field-constants/generated_constants.go @@ -207,6 +207,12 @@ const ( RegistryImageMeta = "meta" ) +// constant vars generated for struct RegistryImageURL +const ( + RegistryImageURLScriptUrl = "scriptUrl" + RegistryImageURLUrl = "url" +) + // constant vars generated for struct ResourceMapping const ( ResourceMappingBaseEntity = "BaseEntity" diff --git a/apps/webhook/internal/app/image-hook.go b/apps/webhook/internal/app/image-hook.go index d03e07631..e22406e73 100644 --- a/apps/webhook/internal/app/image-hook.go +++ b/apps/webhook/internal/app/image-hook.go @@ -15,7 +15,9 @@ import ( types2 "github.com/kloudlite/api/pkg/messaging/types" "github.com/pkg/errors" "go.uber.org/fx" + "io" "net/http" + "os" "strings" "time" ) @@ -67,7 +69,7 @@ func LoadImageHook() fx.Option { app := server.Raw() - app.Post("/image", func(ctx *fiber.Ctx) error { + app.Post("/image-metadata", func(ctx *fiber.Ctx) error { logger := logr.WithName("image-hook") headers := ctx.GetReqHeaders() @@ -138,6 +140,22 @@ func LoadImageHook() fx.Option { ).Infof("queued webhook") return ctx.Status(http.StatusAccepted).JSON(map[string]string{"status": "ok"}) }) + + app.Get("/image-metadata", func(c *fiber.Ctx) error { + f, err := os.Open("kl-image-script.sh") + if err != nil { + return c.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("Error opening script: %s", err.Error())) + } + defer f.Close() + all, err := io.ReadAll(f) + if err != nil { + return c.Status(fiber.StatusInternalServerError).SendString(fmt.Sprintf("Error reading script: %s", err.Error())) + } + script := string(all) + script = strings.ReplaceAll(script, "$WEBHOOK_URL", envVars.WebhookURL) + return c.SendString(script) + }) + return nil }) } diff --git a/apps/webhook/internal/env/env.go b/apps/webhook/internal/env/env.go index 772b771be..53569c800 100644 --- a/apps/webhook/internal/env/env.go +++ b/apps/webhook/internal/env/env.go @@ -12,6 +12,7 @@ type Env struct { CommsService string `env:"COMMS_SERVICE" required:"true"` DiscordWebhookUrl string `env:"DISCORD_WEBHOOK_URL" required:"false"` + WebhookURL string `env:"WEBHOOK_URL" required:"true"` WebhookTokenHashingSecret string `env:"WEBHOOK_TOKEN_HASHING_SECRET" required:"true"` } diff --git a/apps/webhook/kl-image-script.sh b/apps/webhook/kl-image-script.sh new file mode 100755 index 000000000..bec6a7fc5 --- /dev/null +++ b/apps/webhook/kl-image-script.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +meta=$(echo "$meta" | tr -d ' ') + +json_data='{"image": "'"$image"'", "meta": {' + +IFS=',' read -r -a array <<< "$meta" +for element in "${array[@]}" +do + key=$(echo "$element" | cut -d '=' -f 1) + value=$(echo "$element" | cut -d '=' -f 2) + json_data+='"'"$key"'":"'"$value"'",' +done + +json_data=${json_data%,}'}}' + +curl -X POST $WEBHOOK_URL -H "Authorization: $authorization" -H "Content-Type: application/json" -d "$json_data"