Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Validate TypeInstance input #629

Merged
merged 10 commits into from
Feb 18, 2022
Merged
Show file tree
Hide file tree
Changes from 5 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
1 change: 1 addition & 0 deletions cmd/argo-actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ The following environment variables can be set:
|--------------------------|----------|-------------------------------------------------|--------------------------------------------------------|
| APP_ACTION | yes | | Defines action to perform |
| APP_LOCAL_HUB_ENDPOINT | no | http://capact-hub-local.capact-system/graphql | Defines local Hub Endpoint |
| APP_PUBLIC_HUB_ENDPOINT | no | http://capact-hub-public.capact-system/graphql | Defines public Hub Endpoint |
| APP_DOWNLOAD_CONFIG | no | | For download action defines Type Instances to download |
| APP_LOGGER_DEV_MODE | no | `false` | Enable additional log messages |

Expand Down
27 changes: 17 additions & 10 deletions cmd/argo-actions/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,23 @@ import (

"capact.io/capact/internal/logger"
argoactions "capact.io/capact/pkg/argo-actions"
hubclient "capact.io/capact/pkg/hub/client"
"capact.io/capact/pkg/hub/client/local"
"capact.io/capact/pkg/hub/client/public"

"github.com/vrischmann/envconfig"
"go.uber.org/zap"
)

// Config for the argo-actions command.
type Config struct {
Action string
DownloadConfig []argoactions.DownloadConfig `envconfig:"optional"`
UploadConfig argoactions.UploadConfig `envconfig:"optional"`
UpdateConfig argoactions.UpdateConfig `envconfig:"optional"`
LocalHubEndpoint string `envconfig:"default=http://capact-hub-local.capact-system/graphql"`
Logger logger.Config
Action string
DownloadConfig []argoactions.DownloadConfig `envconfig:"optional"`
UploadConfig argoactions.UploadConfig `envconfig:"optional"`
UpdateConfig argoactions.UpdateConfig `envconfig:"optional"`
LocalHubEndpoint string `envconfig:"default=http://capact-hub-local.capact-system/graphql"`
PublicHubEndpoint string `envconfig:"default=http://capact-hub-public.capact-system/graphql"`
Comment on lines +25 to +26
Copy link
Member

Choose a reason for hiding this comment

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

As discussed previously, please make sure the Environmental variables are set properly during Engine Rendering both for download, update and create TypeInstances (see the pkg/sdk/renderer/argo/typeinstance_handler.go).

Copy link
Member

Choose a reason for hiding this comment

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

What about this comment? I don't see any render logic changed 🤔

Logger logger.Config
}

func main() {
Expand All @@ -37,20 +40,24 @@ func main() {
logger, err := logger.New(cfg.Logger)
exitOnError(err, "while creating zap logger")

client := local.NewDefaultClient(cfg.LocalHubEndpoint)
// TODO: Consider using connection `hubclient.New` and route requests through Gateway
client := hubclient.Client{
Local: local.NewDefaultClient(cfg.LocalHubEndpoint),
Public: public.NewDefaultClient(cfg.PublicHubEndpoint),
}

switch cfg.Action {
case argoactions.DownloadAction:
log := logger.With(zap.String("Action", argoactions.DownloadAction))
action = argoactions.NewDownloadAction(log, client, cfg.DownloadConfig)
action = argoactions.NewDownloadAction(log, &client, cfg.DownloadConfig)

case argoactions.UploadAction:
log := logger.With(zap.String("Action", argoactions.UploadAction))
action = argoactions.NewUploadAction(log, client, cfg.UploadConfig)
action = argoactions.NewUploadAction(log, &client, cfg.UploadConfig)

case argoactions.UpdateAction:
log := logger.With(zap.String("Action", argoactions.UpdateAction))
action = argoactions.NewUpdateAction(log, client, cfg.UpdateConfig)
action = argoactions.NewUpdateAction(log, &client, cfg.UpdateConfig)

default:
err := fmt.Errorf("Invalid action: %s", cfg.Action)
Expand Down
22 changes: 15 additions & 7 deletions cmd/cli/cmd/typeinstance/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"capact.io/capact/internal/cli/heredoc"
"capact.io/capact/internal/cli/printer"
gqllocalapi "capact.io/capact/pkg/hub/api/graphql/local"
"capact.io/capact/pkg/sdk/validation"

"github.com/pkg/errors"
"github.com/spf13/cobra"
Expand Down Expand Up @@ -85,6 +86,12 @@ func NewCreate() *cobra.Command {
func createTI(ctx context.Context, opts createOptions, resourcePrinter *printer.ResourcePrinter) error {
typeInstanceToCreate := &gqllocalapi.CreateTypeInstancesInput{}

server := config.GetDefaultContext()
hubCli, err := client.NewHub(server)
if err != nil {
return err
}

for _, path := range opts.TypeInstancesFiles {
out, err := loadCreateTypeInstanceFromFile(path)
if err != nil {
Expand All @@ -94,18 +101,19 @@ func createTI(ctx context.Context, opts createOptions, resourcePrinter *printer.
typeInstanceToCreate = mergeCreateTypeInstances(typeInstanceToCreate, out)
}

validationResult, err := validation.ValidateTypeInstancesToCreate(ctx, hubCli, typeInstanceToCreate)
if err != nil {
return errors.Wrap(err, "while validating TypeInstances")
}
if validationResult.Len() > 0 {
return validationResult.ErrorOrNil()
}

// HACK: UsesRelations are required on GQL side so at least empty array needs to be send
if typeInstanceToCreate.UsesRelations == nil {
typeInstanceToCreate.UsesRelations = []*gqllocalapi.TypeInstanceUsesRelationInput{}
}

server := config.GetDefaultContext()

hubCli, err := client.NewHub(server)
if err != nil {
return err
}

createdTI, err := hubCli.CreateTypeInstances(ctx, typeInstanceToCreate)
if err != nil {
return err
Expand Down
10 changes: 10 additions & 0 deletions cmd/cli/cmd/typeinstance/edit.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ import (
"capact.io/capact/internal/cli/client"
"capact.io/capact/internal/cli/config"
gqllocalapi "capact.io/capact/pkg/hub/api/graphql/local"
"capact.io/capact/pkg/sdk/validation"

"github.com/AlecAivazis/survey/v2"
"github.com/MakeNowJust/heredoc"
"github.com/fatih/color"
"github.com/pkg/errors"
"github.com/spf13/cobra"
"sigs.k8s.io/yaml"
)
Expand Down Expand Up @@ -58,6 +60,14 @@ func editTI(ctx context.Context, opts editOptions, w io.Writer) error {
return err
}

validationResult, err := validation.ValidateTypeInstanceToUpdate(ctx, hubCli, typeInstanceToUpdate)
if err != nil {
return errors.Wrap(err, "while validating TypeInstance")
}
if validationResult.Len() > 0 {
return validationResult.ErrorOrNil()
}

_, err = hubCli.UpdateTypeInstances(ctx, typeInstanceToUpdate)
if err != nil {
return err
Expand Down
5 changes: 4 additions & 1 deletion cmd/k8s-engine/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ type Config struct {

Logger logger.Config

LocalHubEndpoint string `envconfig:"default=http://capact-hub-local.capact-system/graphql"`
PublicHubEndpoint string `envconfig:"default=http://capact-hub-public.capact-system/graphql"`

GraphQLGateway struct {
Endpoint string `envconfig:"default=http://capact-gateway/graphql"`
Username string
Expand Down Expand Up @@ -107,7 +110,7 @@ func main() {
exitOnError(err, "while creating manager")

hubClient := getHubClient(&cfg)
typeInstanceHandler := argo.NewTypeInstanceHandler(cfg.HubActionsImage)
typeInstanceHandler := argo.NewTypeInstanceHandler(cfg.HubActionsImage, cfg.LocalHubEndpoint, cfg.PublicHubEndpoint)
interfaceIOValidator := actionvalidation.NewValidator(hubClient)
policyIOValidator := policyvalidation.NewValidator(hubClient)
wfValidator := renderer.NewWorkflowInputValidator(interfaceIOValidator, policyIOValidator)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ spec:
value: "{{ .Values.global.gateway.auth.username }}"
- name: APP_GRAPHQLGATEWAY_PASSWORD
value: "{{ .Values.global.gateway.auth.password }}"
- name: APP_LOCAL_HUB_ENDPOINT
value: "http://capact-hub-local.{{.Release.Namespace}}.svc.cluster.local/graphql"
- name: APP_PUBLIC_HUB_ENDPOINT
value: "http://capact-hub-public.{{.Release.Namespace}}.svc.cluster.local/graphql"
- name: APP_BUILTIN_RUNNER_IMAGE
value: "{{ .Values.global.containerRegistry.path }}/{{ .Values.builtInRunner.image.name }}:{{ .Values.global.containerRegistry.overrideTag | default .Chart.AppVersion }}"
- name: APP_BUILTIN_RUNNER_TIMEOUT
Expand Down
6 changes: 3 additions & 3 deletions pkg/argo-actions/download_type_instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"context"
"fmt"

"capact.io/capact/pkg/hub/client/local"
hubclient "capact.io/capact/pkg/hub/client"
"capact.io/capact/pkg/runner"
"github.com/pkg/errors"
"go.uber.org/zap"
Expand All @@ -25,11 +25,11 @@ type DownloadConfig struct {
type Download struct {
log *zap.Logger
cfg []DownloadConfig
client *local.Client
client *hubclient.Client
}

// NewDownloadAction returns a new Download instance.
func NewDownloadAction(log *zap.Logger, client *local.Client, cfg []DownloadConfig) Action {
func NewDownloadAction(log *zap.Logger, client *hubclient.Client, cfg []DownloadConfig) Action {
return &Download{
log: log,
cfg: cfg,
Expand Down
19 changes: 15 additions & 4 deletions pkg/argo-actions/update_type_instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ import (
"path/filepath"

graphqllocal "capact.io/capact/pkg/hub/api/graphql/local"
"capact.io/capact/pkg/hub/client/local"
hubclient "capact.io/capact/pkg/hub/client"
"capact.io/capact/pkg/sdk/validation"
"github.com/pkg/errors"
"go.uber.org/zap"
"sigs.k8s.io/yaml"
Expand All @@ -26,12 +27,12 @@ type UpdateConfig struct {
// It is used to update existing TypeInstances in the Local Hub.
type Update struct {
log *zap.Logger
client *local.Client
client *hubclient.Client
cfg UpdateConfig
}

// NewUpdateAction returns a new Update instance.
func NewUpdateAction(log *zap.Logger, client *local.Client, cfg UpdateConfig) Action {
func NewUpdateAction(log *zap.Logger, client *hubclient.Client, cfg UpdateConfig) Action {
return &Update{
log: log,
client: client,
Expand Down Expand Up @@ -83,6 +84,16 @@ func (u *Update) Do(ctx context.Context) error {
return errors.Wrap(err, "while rendering UpdateTypeInstancesInput")
}

u.log.Info("Validating TypeInstances")

validationResult, err := validation.ValidateTypeInstanceToUpdate(ctx, u.client, payload)
if err != nil {
return errors.Wrap(err, "while validating TypeInstance")
}
if validationResult.Len() > 0 {
return validationResult.ErrorOrNil()
}

u.log.Info("Updating TypeInstances in Hub...", zap.Int("TypeInstance count", len(payload)))

uploadOutput, err := u.updateTypeInstances(ctx, payload)
Expand Down Expand Up @@ -110,5 +121,5 @@ func (u *Update) render(payload []graphqllocal.UpdateTypeInstancesInput, values
}

func (u *Update) updateTypeInstances(ctx context.Context, in []graphqllocal.UpdateTypeInstancesInput) ([]graphqllocal.TypeInstance, error) {
return u.client.UpdateTypeInstances(ctx, in)
return u.client.Local.UpdateTypeInstances(ctx, in)
}
20 changes: 16 additions & 4 deletions pkg/argo-actions/upload_type_instances.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ import (
"path/filepath"

graphqllocal "capact.io/capact/pkg/hub/api/graphql/local"
"capact.io/capact/pkg/hub/client/local"
hubclient "capact.io/capact/pkg/hub/client"
"capact.io/capact/pkg/sdk/validation"

"github.com/pkg/errors"
"go.uber.org/zap"
"sigs.k8s.io/yaml"
Expand All @@ -26,12 +28,12 @@ type UploadConfig struct {
// It is used to upload TypeInstances to the Local Hub.
type Upload struct {
log *zap.Logger
client *local.Client
client *hubclient.Client
cfg UploadConfig
}

// NewUploadAction returns a new Upload instance.
func NewUploadAction(log *zap.Logger, client *local.Client, cfg UploadConfig) Action {
func NewUploadAction(log *zap.Logger, client *hubclient.Client, cfg UploadConfig) Action {
return &Upload{
log: log,
client: client,
Expand Down Expand Up @@ -83,6 +85,16 @@ func (u *Upload) Do(ctx context.Context) error {
return errors.Wrap(err, "while rendering CreateTypeInstancesInput")
}

u.log.Info("Validating TypeInstances")

validationResult, err := validation.ValidateTypeInstancesToCreate(ctx, u.client, payload)
if err != nil {
return errors.Wrap(err, "while validating TypeInstances")
}
if validationResult.Len() > 0 {
return validationResult.ErrorOrNil()
mkuziemko marked this conversation as resolved.
Show resolved Hide resolved
}

u.log.Info("Uploading TypeInstances to Hub...", zap.Int("TypeInstance count", len(payload.TypeInstances)))

uploadOutput, err := u.uploadTypeInstances(ctx, payload)
Expand Down Expand Up @@ -112,5 +124,5 @@ func (u *Upload) render(payload *graphqllocal.CreateTypeInstancesInput, values m
}

func (u *Upload) uploadTypeInstances(ctx context.Context, in *graphqllocal.CreateTypeInstancesInput) ([]graphqllocal.CreateTypeInstanceOutput, error) {
return u.client.CreateTypeInstances(ctx, in)
return u.client.Local.CreateTypeInstances(ctx, in)
}
10 changes: 10 additions & 0 deletions pkg/hub/client/public/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"regexp"
"strings"

"capact.io/capact/pkg/httputil"
gqlpublicapi "capact.io/capact/pkg/hub/api/graphql/public"
"github.com/avast/retry-go"

Expand All @@ -25,6 +26,15 @@ func NewClient(cli *graphql.Client) *Client {
return &Client{client: cli}
}

// NewDefaultClient creates ready to use client with default values.
func NewDefaultClient(endpoint string, opts ...httputil.ClientOption) *Client {
httpClient := httputil.NewClient(opts...)
clientOpt := graphql.WithHTTPClient(httpClient)
client := graphql.NewClient(endpoint, clientOpt)

return NewClient(client)
}

// FindInterfaceRevision returns the InterfaceRevision for the given InterfaceReference.
// It will return nil, if the InterfaceRevision is not found.
func (c *Client) FindInterfaceRevision(ctx context.Context, ref gqlpublicapi.InterfaceReference, opts ...InterfaceRevisionOption) (*gqlpublicapi.InterfaceRevision, error) {
Expand Down
8 changes: 8 additions & 0 deletions pkg/sdk/apis/0.0.1/types/types.extend.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
// Package types holds manually added types.
package types

import (
"fmt"
)

// OCFPathPrefix defines path prefix that all OCF manifest must have.
const OCFPathPrefix = "cap."

Expand All @@ -20,6 +24,10 @@ type ManifestRef struct {
Revision string `json:"revision"` // Version of the manifest content in the SemVer format.
}

func (in *ManifestRef) String() string {
return fmt.Sprintf("%s:%s", in.Path, in.Revision)
}

// ManifestRefWithOptRevision specifies type by path and optional revision.
// +kubebuilder:object:generate=true
type ManifestRefWithOptRevision struct {
Expand Down
2 changes: 1 addition & 1 deletion pkg/sdk/renderer/argo/dedicated_renderer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ func createFakeDedicatedRendererObject(t *testing.T) *dedicatedRenderer {
require.NoError(t, err)

genUUID := func() string { return "uuid" }
typeInstanceHandler := NewTypeInstanceHandler("alpine:3.7")
typeInstanceHandler := NewTypeInstanceHandler("alpine:3.7", "", "")
typeInstanceHandler.SetGenUUID(genUUID)

policyIOValidator := policyvalidation.NewValidator(fakeCli)
Expand Down
8 changes: 4 additions & 4 deletions pkg/sdk/renderer/argo/renderer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ func TestRenderHappyPath(t *testing.T) {

policy := policy.NewAllowAll()
genUUID := func() string { return "uuid" } // it has to be static because of parallel testing
typeInstanceHandler := NewTypeInstanceHandler("alpine:3.7")
typeInstanceHandler := NewTypeInstanceHandler("alpine:3.7", "http://capact-hub-local.capact-system/graphql ", "http://capact-hub-public.capact-system/graphql")
mkuziemko marked this conversation as resolved.
Show resolved Hide resolved
typeInstanceHandler.SetGenUUID(genUUID)

ownerID := "default/action"
Expand Down Expand Up @@ -294,7 +294,7 @@ func TestRenderHappyPathWithCustomPolicies(t *testing.T) {
tt := test
t.Run(tt.name, func(t *testing.T) {
genUUID := genUUIDFn(strconv.Itoa(tc))
typeInstanceHandler := NewTypeInstanceHandler("alpine:3.7")
typeInstanceHandler := NewTypeInstanceHandler("alpine:3.7", "http://capact-hub-local.capact-system/graphql ", "http://capact-hub-public.capact-system/graphql")
typeInstanceHandler.SetGenUUID(genUUID)

interfaceIOValidator := actionvalidation.NewValidator(fakeCli)
Expand Down Expand Up @@ -341,7 +341,7 @@ func TestRendererMaxDepth(t *testing.T) {
require.NoError(t, err)

policy := policy.NewAllowAll()
typeInstanceHandler := NewTypeInstanceHandler("alpine:3.7")
typeInstanceHandler := NewTypeInstanceHandler("alpine:3.7", "http://capact-hub-local.capact-system/graphql ", "http://capact-hub-public.capact-system/graphql")
typeInstanceHandler.SetGenUUID(genUUIDFn(""))

interfaceIOValidator := actionvalidation.NewValidator(fakeCli)
Expand Down Expand Up @@ -380,7 +380,7 @@ func TestRendererDenyAllPolicy(t *testing.T) {
require.NoError(t, err)

policy := policy.NewDenyAll()
typeInstanceHandler := NewTypeInstanceHandler("alpine:3.7")
typeInstanceHandler := NewTypeInstanceHandler("alpine:3.7", "http://capact-hub-local.capact-system/graphql ", "http://capact-hub-public.capact-system/graphql")
typeInstanceHandler.SetGenUUID(genUUIDFn(""))

interfaceIOValidator := actionvalidation.NewValidator(fakeCli)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1238,6 +1238,10 @@ args:
value: /upload/payload
- name: APP_UPLOAD_CONFIG_TYPE_INSTANCES_DIR
value: /upload/typeInstances
- name: APP_LOCAL_HUB_ENDPOINT
value: 'http://capact-hub-local.capact-system/graphql '
- name: APP_PUBLIC_HUB_ENDPOINT
value: http://capact-hub-public.capact-system/graphql
image: alpine:3.7
imagePullPolicy: IfNotPresent
name: ""
Expand Down
Loading