diff --git a/README.md b/README.md index 4ae2bfd00..10a75eeca 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,17 @@ To download azion CLI through Homebrew, run: brew install azion `````` +##### Test Azion CLI with docker +You can find the URL for each package in our Releases page https://github.com/aziontech/azion/releases +```sh +docker run -it --rm alpine:latest sh -c ' + cd && \ + wget https://github.com/aziontech/azion/releases/download/1.28.1/azion_1.28.1_linux_arm64.apk && \ + apk add --allow-untrusted azion_1.28.1_linux_arm64.apk && \ + azion version; \ + exec sh' +``` + ## Building Locally ```sh diff --git a/go.mod b/go.mod index 7d98c4f51..21360a251 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.22.4 require ( github.com/AlecAivazis/survey/v2 v2.3.7 github.com/MakeNowJust/heredoc v1.0.0 - github.com/aziontech/azionapi-go-sdk v0.130.0 + github.com/aziontech/azionapi-go-sdk v0.133.0 github.com/aziontech/go-thoth v0.0.0-20240228144710-d061a88cc39f github.com/aziontech/tablecli v0.0.0-20240513193320-c4dbf16b013a github.com/fatih/color v1.17.0 diff --git a/go.sum b/go.sum index 27bf860e2..b27c05944 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,8 @@ github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFI github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aziontech/azionapi-go-sdk v0.130.0 h1:mKoOzPC6GJCRl5f7FZsyflc3JRKZ9nMRNMO+dly71E4= -github.com/aziontech/azionapi-go-sdk v0.130.0/go.mod h1:cA5DY/VP4X5Eu11LpQNzNn83ziKjja7QVMIl4J45feA= +github.com/aziontech/azionapi-go-sdk v0.133.0 h1:xwDJd0kY3oQBMwnSZifVry43x46qnhOaQ3vnAmjmWsQ= +github.com/aziontech/azionapi-go-sdk v0.133.0/go.mod h1:cA5DY/VP4X5Eu11LpQNzNn83ziKjja7QVMIl4J45feA= github.com/aziontech/go-thoth v0.0.0-20240228144710-d061a88cc39f h1:b0IX6tpiiG+QzCVOBqwYEHP5gPeeESq57A5ZXiYyDS4= github.com/aziontech/go-thoth v0.0.0-20240228144710-d061a88cc39f/go.mod h1:v4AMg2JrM68ckr2nt7c7PRuOELek/JbVRa62+inlprQ= github.com/aziontech/tablecli v0.0.0-20240513193320-c4dbf16b013a h1:jKR7y/1ePDPZkfKgqj7gUK9XB7KRHsyHci8tJXD3YTM= diff --git a/messages/build/messages.go b/messages/build/messages.go index b82317584..908588a26 100644 --- a/messages/build/messages.go +++ b/messages/build/messages.go @@ -17,4 +17,5 @@ var ( FlagPolyfill = "Use node polyfills in build" FlagEntry = "Code entrypoint; (default: ./main.js)" IsFirewall = "Indicates whether the function to be run is intended for the Edge Firewall" + ProjectConfFlag = "Relative path to where your custom azion.json and args.json files are stored" ) diff --git a/messages/delete/edge_application/messages.go b/messages/delete/edge_application/messages.go index 8e1e85b78..38714f431 100644 --- a/messages/delete/edge_application/messages.go +++ b/messages/delete/edge_application/messages.go @@ -11,4 +11,5 @@ var ( CascadeSuccess = "Remote resources deleted successfully" FlagId = "Unique identifier of the Edge Application" AskInput = "Enter the ID of the Edge Application you wish to delete:" + CONFDIRFLAG = "Relative path to where your custom azion.json and args.json files are stored" ) diff --git a/messages/deploy/messages.go b/messages/deploy/messages.go index e5ae5e7c1..f35e0a97d 100644 --- a/messages/deploy/messages.go +++ b/messages/deploy/messages.go @@ -2,40 +2,42 @@ package deploy var ( // deploy cmd - DeployUsage = "deploy" - DeployShortDescription = "Deploys an Edge Application" - DeployLongDescription = "Deploys an Edge Application" - DeploySuccessful = "Your Edge Application was deployed successfully\n" - SimpleDeploySuccessful = "Your simple Edge Application was deployed successfully\n" - DeployOutputDomainSuccess = "\nTo visualize your application access the Domain: %v\n" - EdgeApplicationDeployDomainHint = "You may now edit your Domain and add your own CNAMES. To do this you may run 'azion domain update' command and also configure your DNS\n" - DeployOutputCachePurge = "Domain cache was purged\n" - DeployOutputEdgeFunctionCreate = "Created Edge Function %v with ID %v\n" - DeployOutputEdgeFunctionUpdate = "Updated Edge Function %v with ID %v\n" - DeployOutputEdgeApplicationCreate = "Created Edge Application %v with ID %v\n" - DeployOutputEdgeApplicationUpdate = "Updated Edge Application %v with ID %v\n" - DeployOutputDomainCreate = "Created Domain %v with ID %v\n" - DeployOutputDomainUpdate = "Updated Domain %v with ID %v\n" - EdgeApplicationDeployPathFlag = "Path to where your static files are stored" - OriginsSuccessful = "Created Origin for Edge Application\n" - OriginsUpdateSuccessful = "Updated Origin for Edge Application %v with ID %v \n" - CacheSettingsSuccessful = "Created Cache Settings for Edge Application\n" - BucketSuccessful = "Created Bucket %s\n" - RulesEngineSuccessful = "Created Rules Engine for Edge Application\n" - DeployFlagHelp = "Displays more information about the deploy command" - DeployFlagAuto = "If sent, the entire flow of the command will be run without interruptions" - DeployFlagNoPrompt = "If sent, whenever the CLI would display an interactive prompt due to an error, it instead just returns the error" - DeployPropagation = "Your application is being deployed to all Azion Edge Locations and it might take a few minutes.\n" - UploadStart = "Uploading static files\n" - UploadSuccessful = "\nUpload completed successfully!\n" - BucketInUse = "This bucket's name is already in use, please try another one\n" - AppInUse = "This Edge Application's name is already in use, please try another one\n" - DomainInUse = "This domain's name is already in use, please try another one\n" - FuncInUse = "This Edge Function's name is already in use, please try another one\n" - FuncInstInUse = "This function instance's name is already in use, please try another one\n" - AskInputName = "Type the new name:" - ProjectNameMessage = "Using the same name as your project to create the bucket\n" - AskCreateCacheSettings = `Azion CLI offers to create the following Cache Settings specifications: + DeployUsage = "deploy" + DeployShortDescription = "Deploys an Edge Application" + DeployLongDescription = "Deploys an Edge Application" + DeploySuccessful = "Your Edge Application was deployed successfully\n" + SimpleDeploySuccessful = "Your simple Edge Application was deployed successfully\n" + DeployOutputDomainSuccess = "\nTo visualize your application access the Domain: %v\n" + EdgeApplicationDeployDomainHint = "You may now edit your Domain and add your own CNAMES. To do this you may run 'azion domain update' command and also configure your DNS\n" + DeployOutputCachePurge = "Domain cache was purged\n" + DeployOutputEdgeFunctionCreate = "Created Edge Function %v with ID %v\n" + DeployOutputEdgeFunctionUpdate = "Updated Edge Function %v with ID %v\n" + DeployOutputEdgeApplicationCreate = "Created Edge Application %v with ID %v\n" + DeployOutputEdgeApplicationUpdate = "Updated Edge Application %v with ID %v\n" + DeployOutputDomainCreate = "Created Domain %v with ID %v\n" + DeployOutputDomainUpdate = "Updated Domain %v with ID %v\n" + EdgeApplicationDeployPathFlag = "Path to where your static files are stored" + EdgeApplicationDeployProjectConfFlag = "Relative path to where your custom azion.json and args.json files are stored" + OriginsSuccessful = "Created Origin for Edge Application\n" + OriginsUpdateSuccessful = "Updated Origin for Edge Application %v with ID %v \n" + CacheSettingsSuccessful = "Created Cache Settings for Edge Application\n" + BucketSuccessful = "Created Bucket %s\n" + RulesEngineSuccessful = "Created Rules Engine for Edge Application\n" + DeployFlagHelp = "Displays more information about the deploy command" + DeployFlagAuto = "If sent, the entire flow of the command will be run without interruptions" + DeployFlagNoPrompt = "If sent, whenever the CLI would display an interactive prompt due to an error, it instead just returns the error" + DeployFlagSkipBuild = "If sent, the build command will not be called during the deploy process" + DeployPropagation = "Your application is being deployed to all Azion Edge Locations and it might take a few minutes.\n" + UploadStart = "Uploading static files\n" + UploadSuccessful = "\nUpload completed successfully!\n" + BucketInUse = "This bucket's name is already in use, please try another one\n" + AppInUse = "This Edge Application's name is already in use, please try another one\n" + DomainInUse = "This domain's name is already in use, please try another one\n" + FuncInUse = "This Edge Function's name is already in use, please try another one\n" + FuncInstInUse = "This function instance's name is already in use, please try another one\n" + AskInputName = "Type the new name:" + ProjectNameMessage = "Using the same name as your project to create the bucket\n" + AskCreateCacheSettings = `Azion CLI offers to create the following Cache Settings specifications: - Browser Cache Settings: Override Cache Settings - Maximum TTL for Browser Cache Settings (in seconds): 7200 - Edge Application Cache Settings: Override Cache Settings diff --git a/messages/link/messages.go b/messages/link/messages.go index c92f2ed0b..ac11e4541 100644 --- a/messages/link/messages.go +++ b/messages/link/messages.go @@ -33,5 +33,6 @@ var ( ) const ( - FLAG_REMOTE = "Clones a remote repository to be linked to an Azion Edge Application" + FLAG_REMOTE = "Clones a remote repository to be linked to an Azion Edge Application" + FLAGPATHCONF = "Relative path to where your custom azion.json and args.json files are stored" ) diff --git a/messages/manifest/errors.go b/messages/manifest/errors.go index 8cbfa4c0f..8dee1b711 100644 --- a/messages/manifest/errors.go +++ b/messages/manifest/errors.go @@ -7,4 +7,10 @@ var ( ErrorCacheNotFound = errors.New("Could not find this cache setting") ErrorFunctionNotFound = errors.New("Could not find this edge function") ErrorOriginNotFound = errors.New("Could not find this origin") + ErrorCreateOrigin = errors.New("Failed to create the origin") + ErrorCreateCache = errors.New("Failed to create the cache setting") + ErrorCreateRule = errors.New("Failed to create the rule in Rules Engine") + ErrorUpdateOrigin = errors.New("Failed to update the origin") + ErrorUpdateCache = errors.New("Failed to update the cache setting") + ErrorUpdateRule = errors.New("Failed to update the rule in Rules Engine") ) diff --git a/messages/sync/errors.go b/messages/sync/errors.go new file mode 100644 index 000000000..a9777a095 --- /dev/null +++ b/messages/sync/errors.go @@ -0,0 +1,5 @@ +package sync + +var ( + ERRORSYNC = "Failed to synchronize local resources with remote resources: %s" +) diff --git a/messages/sync/messages.go b/messages/sync/messages.go new file mode 100644 index 000000000..76cd9e0d9 --- /dev/null +++ b/messages/sync/messages.go @@ -0,0 +1,10 @@ +package sync + +const ( + USAGE = "sync" + SHORTDESCRIPTION = "Synchronizes the local azion.json file with remote resources" + LONGDESCRIPTION = "Synchronizes your local file containing your existing application resources configuration with remote resources" + SYNCMESSAGERULE = "Adding out of sync rule '%s' to your azion.json file\n" + HELPFLAG = "Displays more information about the sync command" + CONFDIRFLAG = "Relative path to where your custom azion.json and args.json files are stored" +) diff --git a/pkg/api/rules_engine/rules_engine.go b/pkg/api/rules_engine/rules_engine.go index 1da264401..51d5dbf77 100644 --- a/pkg/api/rules_engine/rules_engine.go +++ b/pkg/api/rules_engine/rules_engine.go @@ -74,7 +74,7 @@ func (c *Client) Create(ctx context.Context, edgeApplicationID int64, phase stri if err != nil { if httpResp != nil { - logger.Debug("Error while updating a Rules Engine", zap.Error(err)) + logger.Debug("Error while creating a Rules Engine", zap.Error(err)) err := utils.LogAndRewindBody(httpResp) if err != nil { return nil, err diff --git a/pkg/cmd/build/build.go b/pkg/cmd/build/build.go index b733f07bf..904fbc816 100644 --- a/pkg/cmd/build/build.go +++ b/pkg/cmd/build/build.go @@ -22,12 +22,10 @@ type BuildCmd struct { CommandRunInteractive func(f *cmdutil.Factory, comm string) error CommandRunner func(f *cmdutil.Factory, comm string, envVars []string) (string, error) FileReader func(path string) ([]byte, error) - ConfigRelativePath string - GetAzionJsonContent func() (*contracts.AzionApplicationOptions, error) - WriteAzionJsonContent func(conf *contracts.AzionApplicationOptions) error + GetAzionJsonContent func(pathConf string) (*contracts.AzionApplicationOptions, error) + WriteAzionJsonContent func(conf *contracts.AzionApplicationOptions, confPath string) error EnvLoader func(path string) ([]string, error) Stat func(path string) (fs.FileInfo, error) - VersionID func() string GetWorkDir func() (string, error) f *cmdutil.Factory } @@ -57,6 +55,7 @@ func NewCobraCmd(build *BuildCmd) *cobra.Command { buildCmd.Flags().StringVar(&fields.NodePolyfills, "use-node-polyfills", "", msg.FlagPolyfill) buildCmd.Flags().StringVar(&fields.OwnWorker, "use-own-worker", "", msg.FlagWorker) buildCmd.Flags().BoolVar(&fields.IsFirewall, "firewall", false, msg.IsFirewall) + buildCmd.Flags().StringVar(&fields.ProjectPath, "config-dir", "azion", msg.ProjectConfFlag) return buildCmd } @@ -74,7 +73,6 @@ func NewBuildCmd(f *cmdutil.Factory) *BuildCmd { CommandRunner: func(f *cmdutil.Factory, comm string, envVars []string) (string, error) { return utils.CommandRunInteractiveWithOutput(f, comm, envVars) }, - ConfigRelativePath: "/azion/config.json", EnvLoader: utils.LoadEnvVarsFromFile, GetAzionJsonContent: utils.GetAzionJsonContent, WriteAzionJsonContent: utils.WriteAzionJsonContent, @@ -82,10 +80,14 @@ func NewBuildCmd(f *cmdutil.Factory) *BuildCmd { Stat: os.Stat, GetWorkDir: utils.GetWorkingDir, f: f, - VersionID: utils.Timestamp, } } func (cmd *BuildCmd) Run(fields *contracts.BuildInfo) error { return cmd.run(fields) } + +func (cmd *BuildCmd) ExternalRun(fields *contracts.BuildInfo, confPath string) error { + fields.ProjectPath = confPath + return cmd.run(fields) +} diff --git a/pkg/cmd/build/run.go b/pkg/cmd/build/run.go index 2f1676d90..ac832d56d 100644 --- a/pkg/cmd/build/run.go +++ b/pkg/cmd/build/run.go @@ -7,7 +7,6 @@ import ( msg "github.com/aziontech/azion-cli/messages/build" "github.com/aziontech/azion-cli/pkg/contracts" "github.com/aziontech/azion-cli/pkg/logger" - "github.com/aziontech/azion-cli/utils" "go.uber.org/zap" ) @@ -25,7 +24,7 @@ func (cmd *BuildCmd) run(fields *contracts.BuildInfo) error { func RunBuildCmdLine(cmd *BuildCmd, fields *contracts.BuildInfo) error { var err error - conf, err := cmd.GetAzionJsonContent() + conf, err := cmd.GetAzionJsonContent(fields.ProjectPath) if err != nil { logger.Debug("Error while building your project", zap.Error(err)) return msg.ErrorBuilding @@ -65,49 +64,6 @@ func RunBuildCmdLine(cmd *BuildCmd, fields *contracts.BuildInfo) error { vulcanParams += " --firewall " } - err = checkArgsJson(cmd) - if err != nil { - return err - } - - if conf.Preset == "simple" { - logger.FInfo(cmd.Io.Out, msg.BuildSimple) - return nil - } - - if conf.Preset == "static" { - versionID := cmd.VersionID() - conf.Prefix = versionID - - err = cmd.WriteAzionJsonContent(conf) - if err != nil { - return nil - } - logger.FInfo(cmd.Io.Out, msg.BuildSimple) - return nil - } - - if conf.Preset != "nextjs" { - return vulcan(cmd, conf, vulcanParams) - } + return vulcan(cmd, conf, vulcanParams, fields) - return utils.ErrorUnsupportedType -} - -func checkArgsJson(cmd *BuildCmd) error { - workingDir, err := cmd.GetWorkDir() - if err != nil { - return err - } - - workDirPath := workingDir + "/azion/args.json" - _, err = cmd.FileReader(workDirPath) - if err != nil { - if err := cmd.WriteFile(workDirPath, []byte("{}"), 0644); err != nil { - logger.Debug("Error while trying to create args.json file", zap.Error(err)) - return fmt.Errorf(utils.ErrorCreateFile.Error(), workDirPath) - } - } - - return nil } diff --git a/pkg/cmd/build/vulcan.go b/pkg/cmd/build/vulcan.go index faafeb2d5..3e6457e4a 100644 --- a/pkg/cmd/build/vulcan.go +++ b/pkg/cmd/build/vulcan.go @@ -12,7 +12,7 @@ import ( "go.uber.org/zap" ) -func vulcan(cmd *BuildCmd, conf *contracts.AzionApplicationOptions, vulcanParams string) error { +func vulcan(cmd *BuildCmd, conf *contracts.AzionApplicationOptions, vulcanParams string, fields *contracts.BuildInfo) error { // checking if vulcan major is correct vulcanVer, err := cmd.CommandRunner(cmd.f, "npm show edge-functions version", []string{}) if err != nil { @@ -31,11 +31,7 @@ func vulcan(cmd *BuildCmd, conf *contracts.AzionApplicationOptions, vulcanParams return fmt.Errorf(msg.ErrorVulcanExecute.Error(), err.Error()) } - versionID := cmd.VersionID() - - conf.Prefix = versionID - - err = cmd.WriteAzionJsonContent(conf) + err = cmd.WriteAzionJsonContent(conf, fields.ProjectPath) if err != nil { logger.Debug("Error while writing azion.json file", zap.Error(err)) return utils.ErrorWritingAzionJsonFile diff --git a/pkg/cmd/delete/edge_application/cascade.go b/pkg/cmd/delete/edge_application/cascade.go index 665513cbb..da6fb38eb 100644 --- a/pkg/cmd/delete/edge_application/cascade.go +++ b/pkg/cmd/delete/edge_application/cascade.go @@ -13,7 +13,7 @@ import ( ) func (del *DeleteCmd) Cascade(ctx context.Context) error { - azionJson, err := del.GetAzion() + azionJson, err := del.GetAzion(ProjectConf) if err != nil { if errors.Is(err, os.ErrNotExist) { return msg.ErrorMissingAzionJson diff --git a/pkg/cmd/delete/edge_application/edge_application.go b/pkg/cmd/delete/edge_application/edge_application.go index 6caea6941..cb8eb95bf 100644 --- a/pkg/cmd/delete/edge_application/edge_application.go +++ b/pkg/cmd/delete/edge_application/edge_application.go @@ -21,9 +21,11 @@ import ( "go.uber.org/zap" ) +var ProjectConf string + type DeleteCmd struct { Io *iostreams.IOStreams - GetAzion func() (*contracts.AzionApplicationOptions, error) + GetAzion func(confPath string) (*contracts.AzionApplicationOptions, error) f *cmdutil.Factory UpdateJson func(cmd *DeleteCmd) error } @@ -61,6 +63,7 @@ func NewCobraCmd(delete *DeleteCmd) *cobra.Command { cmd.Flags().Int64Var(&application_id, "application-id", 0, msg.FlagId) cmd.Flags().Bool("cascade", true, msg.CascadeFlag) cmd.Flags().BoolP("help", "h", false, msg.HelpFlag) + cmd.Flags().StringVar(&ProjectConf, "config-dir", "azion", msg.CONFDIRFLAG) return cmd } diff --git a/pkg/cmd/delete/edge_application/edge_application_test.go b/pkg/cmd/delete/edge_application/edge_application_test.go index 44a5baf3d..5d5d627f5 100644 --- a/pkg/cmd/delete/edge_application/edge_application_test.go +++ b/pkg/cmd/delete/edge_application/edge_application_test.go @@ -89,7 +89,7 @@ func TestCreate(t *testing.T) { f, stdout, _ := testutils.NewFactory(mock) del := NewDeleteCmd(f) - del.GetAzion = func() (*contracts.AzionApplicationOptions, error) { + del.GetAzion = func(confPath string) (*contracts.AzionApplicationOptions, error) { return options, nil } del.UpdateJson = func(cmd *DeleteCmd) error { diff --git a/pkg/cmd/deploy/bucket.go b/pkg/cmd/deploy/bucket.go index 40c32eae7..fe06e6bc5 100644 --- a/pkg/cmd/deploy/bucket.go +++ b/pkg/cmd/deploy/bucket.go @@ -47,7 +47,7 @@ func (cmd *DeployCmd) doBucket(client *api.Client, ctx context.Context, conf *co } logger.FInfo(cmd.Io.Out, fmt.Sprintf(msg.BucketSuccessful, conf.Bucket)) - return cmd.WriteAzionJsonContent(conf) + return cmd.WriteAzionJsonContent(conf, ProjectConf) } func askForInput(msg string, defaultIn string) (string, error) { diff --git a/pkg/cmd/deploy/deploy.go b/pkg/cmd/deploy/deploy.go index 6d16ffa57..8aa135632 100644 --- a/pkg/cmd/deploy/deploy.go +++ b/pkg/cmd/deploy/deploy.go @@ -30,8 +30,8 @@ type DeployCmd struct { GetWorkDir func() (string, error) FileReader func(path string) ([]byte, error) WriteFile func(filename string, data []byte, perm fs.FileMode) error - GetAzionJsonContent func() (*contracts.AzionApplicationOptions, error) - WriteAzionJsonContent func(conf *contracts.AzionApplicationOptions) error + GetAzionJsonContent func(pathConfig string) (*contracts.AzionApplicationOptions, error) + WriteAzionJsonContent func(conf *contracts.AzionApplicationOptions, confConf string) error EnvLoader func(path string) ([]string, error) BuildCmd func(f *cmdutil.Factory) *build.BuildCmd Open func(name string) (*os.File, error) @@ -39,12 +39,15 @@ type DeployCmd struct { F *cmdutil.Factory Unmarshal func(data []byte, v interface{}) error Interpreter func() *manifestInt.ManifestInterpreter + VersionID func() string } var ( - Path string - Auto bool - NoPrompt bool + Path string + Auto bool + NoPrompt bool + SkipBuild bool + ProjectConf string ) func NewDeployCmd(f *cmdutil.Factory) *DeployCmd { @@ -62,6 +65,7 @@ func NewDeployCmd(f *cmdutil.Factory) *DeployCmd { Unmarshal: json.Unmarshal, F: f, Interpreter: manifestInt.NewManifestInterpreter, + VersionID: utils.Timestamp, } } @@ -73,10 +77,10 @@ func NewCobraCmd(deploy *DeployCmd) *cobra.Command { SilenceUsage: true, SilenceErrors: true, Example: heredoc.Doc(` - $ azion deploy --help - $ azion deploy --path dist/storage - $ azion deploy --auto - `), + $ azion deploy --help + $ azion deploy --path dist/storage + $ azion deploy --auto + `), RunE: func(cmd *cobra.Command, args []string) error { return deploy.Run(deploy.F) }, @@ -85,6 +89,8 @@ func NewCobraCmd(deploy *DeployCmd) *cobra.Command { deployCmd.Flags().StringVar(&Path, "path", "", msg.EdgeApplicationDeployPathFlag) deployCmd.Flags().BoolVar(&Auto, "auto", false, msg.DeployFlagAuto) deployCmd.Flags().BoolVar(&NoPrompt, "no-prompt", false, msg.DeployFlagNoPrompt) + deployCmd.Flags().BoolVar(&SkipBuild, "skip-build", false, msg.DeployFlagSkipBuild) + deployCmd.Flags().StringVar(&ProjectConf, "config-dir", "azion", msg.EdgeApplicationDeployProjectConfFlag) return deployCmd } @@ -92,6 +98,11 @@ func NewCmd(f *cmdutil.Factory) *cobra.Command { return NewCobraCmd(NewDeployCmd(f)) } +func (cmd *DeployCmd) ExternalRun(f *cmdutil.Factory, configPath string) error { + ProjectConf = configPath + return cmd.Run(f) +} + func (cmd *DeployCmd) Run(f *cmdutil.Factory) error { logger.Debug("Running deploy command") ctx := context.Background() @@ -101,16 +112,27 @@ func (cmd *DeployCmd) Run(f *cmdutil.Factory) error { return err } - buildCmd := cmd.BuildCmd(f) - err = buildCmd.Run(&contracts.BuildInfo{}) + if !SkipBuild { + buildCmd := cmd.BuildCmd(f) + err = buildCmd.ExternalRun(&contracts.BuildInfo{}, ProjectConf) + if err != nil { + logger.Debug("Error while running build command called by deploy command", zap.Error(err)) + return err + } + } + + conf, err := cmd.GetAzionJsonContent(ProjectConf) if err != nil { - logger.Debug("Error while running build command called by deploy command", zap.Error(err)) + logger.Debug("Failed to get Azion JSON content", zap.Error(err)) return err } - conf, err := cmd.GetAzionJsonContent() + versionID := cmd.VersionID() + + conf.Prefix = versionID + + err = checkArgsJson(cmd, ProjectConf) if err != nil { - logger.Debug("Failed to get Azion JSON content", zap.Error(err)) return err } @@ -208,7 +230,7 @@ func (cmd *DeployCmd) Run(f *cmdutil.Factory) error { } } - err = interpreter.CreateResources(conf, manifestStructure, f) + err = interpreter.CreateResources(conf, manifestStructure, f, ProjectConf) if err != nil { return err } diff --git a/pkg/cmd/deploy/requests.go b/pkg/cmd/deploy/requests.go index 8be787c81..edf0e86eb 100644 --- a/pkg/cmd/deploy/requests.go +++ b/pkg/cmd/deploy/requests.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "path" "strconv" "strings" @@ -57,7 +58,7 @@ func (cmd *DeployCmd) doFunction(clients *Clients, ctx context.Context, conf *co conf.Function.ID = functionId } - err = cmd.WriteAzionJsonContent(conf) + err = cmd.WriteAzionJsonContent(conf, ProjectConf) if err != nil { logger.Debug("Error while writing azion.json file", zap.Error(err)) return err @@ -85,7 +86,7 @@ func (cmd *DeployCmd) doFunction(clients *Clients, ctx context.Context, conf *co conf.Function.InstanceID = instance.GetId() break } - err = cmd.WriteAzionJsonContent(conf) + err = cmd.WriteAzionJsonContent(conf, ProjectConf) if err != nil { logger.Debug("Error while writing azion.json file", zap.Error(err)) return err @@ -137,7 +138,7 @@ func (cmd *DeployCmd) doApplication(client *apiapp.Client, ctx context.Context, break } - err := cmd.WriteAzionJsonContent(conf) + err := cmd.WriteAzionJsonContent(conf, ProjectConf) if err != nil { logger.Debug("Error while writing azion.json file", zap.Error(err)) return err @@ -191,7 +192,7 @@ func (cmd *DeployCmd) doDomain(client *apidom.Client, ctx context.Context, conf break } - err = cmd.WriteAzionJsonContent(conf) + err = cmd.WriteAzionJsonContent(conf, ProjectConf) if err != nil { logger.Debug("Error while writing azion.json file", zap.Error(err)) return err @@ -596,3 +597,22 @@ func checkToken(f *cmdutil.Factory) error { return nil } + +func checkArgsJson(cmd *DeployCmd, projectPath string) error { + workingDir, err := cmd.GetWorkDir() + if err != nil { + return err + } + + workingDirPath := path.Join(workingDir, projectPath, "args.json") + + _, err = cmd.FileReader(workingDirPath) + if err != nil { + if err := cmd.WriteFile(workingDirPath, []byte("{}"), 0644); err != nil { + logger.Debug("Error while trying to create args.json file", zap.Error(err)) + return fmt.Errorf(utils.ErrorCreateFile.Error(), workingDirPath) + } + } + + return nil +} diff --git a/pkg/cmd/edge_functions_instances/create/.fixtures/create.json b/pkg/cmd/edge_functions_instances/create/.fixtures/create.json deleted file mode 100644 index 72e65f3bd..000000000 --- a/pkg/cmd/edge_functions_instances/create/.fixtures/create.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "edge_function_id": 1483, - "name": "Azion - Hello World test", - "args": {} -} \ No newline at end of file diff --git a/pkg/cmd/edge_functions_instances/create/.fixtures/resp.json b/pkg/cmd/edge_functions_instances/create/.fixtures/resp.json deleted file mode 100644 index 02162bbfa..000000000 --- a/pkg/cmd/edge_functions_instances/create/.fixtures/resp.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "results": { - "edge_function_id": 1483, - "name": "Azion - Hello World test", - "args": {}, - "id": 27245 - }, - "schema_version": 3 -} \ No newline at end of file diff --git a/pkg/cmd/edge_functions_instances/create/create.go b/pkg/cmd/edge_functions_instances/create/create.go deleted file mode 100644 index eebaac5c2..000000000 --- a/pkg/cmd/edge_functions_instances/create/create.go +++ /dev/null @@ -1,84 +0,0 @@ -package create - -import ( - "context" - "fmt" - "os" - - "github.com/MakeNowJust/heredoc" - msg "github.com/aziontech/azion-cli/messages/edge_functions_instances" - api "github.com/aziontech/azion-cli/pkg/api/edge_applications" - "github.com/aziontech/azion-cli/pkg/cmdutil" - "github.com/aziontech/azion-cli/utils" - "github.com/spf13/cobra" -) - -type Fields struct { - ApplicationID int64 - Name string - EdgeFunctionId int64 - Args string - Path string -} - -func NewCmd(f *cmdutil.Factory) *cobra.Command { - fields := &Fields{} - - cmd := &cobra.Command{ - Use: msg.EdgeFuncInstanceCreateUsage, - Short: msg.EdgeFuncInstanceCreateShortDescription, - Long: msg.EdgeFuncInstanceCreateLongDescription, - SilenceUsage: true, - SilenceErrors: true, - Example: heredoc.Doc(` - $ azion edge_functions_instances create --application-id 1673635839 --function-id 12314 --name "ffcafe222sdsdffdf" - $ azion edge_functions_instances create -a 1673635839 -f 12314 --name "ffcafe222sdsdffdf" - $ azion edge_functions_instances create -a 1673635839 --in "create.json" - `), - RunE: func(cmd *cobra.Command, args []string) error { - request := api.CreateInstanceRequest{} - if cmd.Flags().Changed("in") { - var ( - file *os.File - err error - ) - if fields.Path == "-" { - file = os.Stdin - } else { - file, err = os.Open(fields.Path) - if err != nil { - return fmt.Errorf("%w: %s", utils.ErrorOpeningFile, fields.Path) - } - } - err = cmdutil.UnmarshallJsonFromReader(file, &request) - if err != nil { - return utils.ErrorUnmarshalReader - } - } else { - if !cmd.Flags().Changed("application-id") || !cmd.Flags().Changed("function-id") || !cmd.Flags().Changed("name") { - return msg.ErrorMandatoryCreateFlags - } - request.SetName(fields.Name) - request.SetEdgeFunctionId(fields.EdgeFunctionId) - request.SetArgs(fields.Args) - } - - client := api.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) - response, err := client.CreateFuncInstances(context.Background(), &request, fields.ApplicationID) - if err != nil { - return fmt.Errorf(msg.ErrorCreate.Error(), err) - } - fmt.Fprintf(f.IOStreams.Out, msg.EdgeFuncInstanceCreateOutputSuccess, response.GetId()) - return nil - }, - } - - flags := cmd.Flags() - flags.Int64VarP(&fields.ApplicationID, "application-id", "a", 0, msg.EdgeFuncInstanceCreateFlagEdgeApplicationId) - flags.Int64VarP(&fields.EdgeFunctionId, "function-id", "f", 0, msg.EdgeFuncInstanceCreateFlagEdgeFunctionID) - flags.StringVar(&fields.Name, "name", "", msg.EdgeFuncInstanceCreateFlagName) - flags.StringVar(&fields.Args, "args", "", msg.EdgeFuncInstanceCreateFlagArgs) - flags.StringVar(&fields.Path, "in", "", msg.EdgeFuncInstanceCreateFlagIn) - flags.BoolP("help", "h", false, msg.EdgeFuncInstanceCreateHelpFlag) - return cmd -} diff --git a/pkg/cmd/edge_functions_instances/create/create_test.go b/pkg/cmd/edge_functions_instances/create/create_test.go deleted file mode 100644 index b7b94c85c..000000000 --- a/pkg/cmd/edge_functions_instances/create/create_test.go +++ /dev/null @@ -1,90 +0,0 @@ -package create - -import ( - "fmt" - "github.com/aziontech/azion-cli/pkg/logger" - "go.uber.org/zap/zapcore" - "net/http" - "testing" - - msg "github.com/aziontech/azion-cli/messages/edge_functions_instances" - - "github.com/aziontech/azion-cli/pkg/httpmock" - "github.com/aziontech/azion-cli/pkg/testutils" - "github.com/stretchr/testify/require" -) - -func TestCreate(t *testing.T) { - logger.New(zapcore.DebugLevel) - t.Run("create new domains", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("POST", "edge_applications/1673635841/functions_instances"), - httpmock.JSONFromFile(".fixtures/resp.json"), - ) - - f, stdout, _ := testutils.NewFactory(mock) - cmd := NewCmd(f) - cmd.SetArgs([]string{ - "--application-id", "1673635841", - "--function-id", "1483", - "--name", "Azion - Hello World test", - }) - - err := cmd.Execute() - require.NoError(t, err) - require.Equal(t, fmt.Sprintf(msg.EdgeFuncInstanceCreateOutputSuccess, 27245), stdout.String()) - }) - - t.Run("create with file", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("POST", "edge_applications/1673635841/functions_instances"), - httpmock.JSONFromFile(".fixtures/resp.json"), - ) - - f, stdout, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - cmd.SetArgs([]string{ - "--application-id", "1673635841", - "--in", ".fixtures/create.json", - }) - - err := cmd.Execute() - require.NoError(t, err) - require.Equal(t, fmt.Sprintf(msg.EdgeFuncInstanceCreateOutputSuccess, 27245), stdout.String()) - }) - - t.Run("bad request status 400", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("POST", "edge_applications/1673635841/functions_instances"), - httpmock.StatusStringResponse(http.StatusBadRequest, "Invalid"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - err := cmd.Execute() - require.Error(t, err) - }) - - t.Run("internal server error 500", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("POST", "edge_applications/1673635841/origin"), - httpmock.StatusStringResponse(http.StatusInternalServerError, "Invalid"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - err := cmd.Execute() - require.Error(t, err) - }) -} diff --git a/pkg/cmd/edge_functions_instances/delete/delete.go b/pkg/cmd/edge_functions_instances/delete/delete.go deleted file mode 100644 index b08bc8bbe..000000000 --- a/pkg/cmd/edge_functions_instances/delete/delete.go +++ /dev/null @@ -1,51 +0,0 @@ -package delete - -import ( - "context" - "fmt" - - "github.com/MakeNowJust/heredoc" - msg "github.com/aziontech/azion-cli/messages/edge_functions_instances" - api "github.com/aziontech/azion-cli/pkg/api/edge_applications" - "github.com/aziontech/azion-cli/pkg/cmdutil" - "github.com/spf13/cobra" -) - -func NewCmd(f *cmdutil.Factory) *cobra.Command { - var functionInstID string - var applicationID string - - cmd := &cobra.Command{ - Use: msg.EdgeFuncInstanceDeleteUsage, - Short: msg.EdgeFuncInstanceDeleteShortDescription, - Long: msg.EdgeFuncInstanceDeleteLongDescription, - SilenceUsage: true, - SilenceErrors: true, - Example: heredoc.Doc(` - $ azion edge_functions_instances delete --application-id 1673635839 --instance-id 12312 - $ azion edge_functions_instances delete -a 1673635839 -i 12312 - `), - RunE: func(cmd *cobra.Command, args []string) error { - if !cmd.Flags().Changed("application-id") || !cmd.Flags().Changed("instance-id") { - return msg.ErrorMissingArgumentsDelete - } - client := api.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) - - ctx := context.Background() - - err := client.DeleteFunctionInstance(ctx, applicationID, functionInstID) - if err != nil { - return fmt.Errorf(msg.ErrorFailToDeleteFuncInst.Error(), err) - } - - out := f.IOStreams.Out - fmt.Fprintf(out, msg.EdgeFuncInstanceDeleteOutputSuccess, functionInstID) - return nil - }, - } - - cmd.Flags().StringVarP(&applicationID, "application-id", "a", "", msg.ApplicationFlagId) - cmd.Flags().StringVarP(&functionInstID, "instance-id", "i", "", msg.EdgeFuncInstanceFlagId) - cmd.Flags().BoolP("help", "h", false, msg.EdgeFuncInstanceDeleteHelpFlag) - return cmd -} diff --git a/pkg/cmd/edge_functions_instances/delete/delete_test.go b/pkg/cmd/edge_functions_instances/delete/delete_test.go deleted file mode 100644 index 7afaf06c2..000000000 --- a/pkg/cmd/edge_functions_instances/delete/delete_test.go +++ /dev/null @@ -1,54 +0,0 @@ -package delete - -import ( - "fmt" - "github.com/aziontech/azion-cli/pkg/logger" - "go.uber.org/zap/zapcore" - "testing" - - msg "github.com/aziontech/azion-cli/messages/edge_functions_instances" - "github.com/aziontech/azion-cli/pkg/httpmock" - "github.com/aziontech/azion-cli/pkg/testutils" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestCreate(t *testing.T) { - logger.New(zapcore.DebugLevel) - t.Run("delete instance by id", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("DELETE", "edge_applications/1234/functions_instances/4321"), - httpmock.StatusStringResponse(204, ""), - ) - - f, stdout, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - cmd.SetArgs([]string{"--application-id", "1234", "--instance-id", "4321"}) - - _, err := cmd.ExecuteC() - require.NoError(t, err) - - assert.Equal(t, fmt.Sprintf(msg.EdgeFuncInstanceDeleteOutputSuccess, "4321"), stdout.String()) - }) - - t.Run("try delete instance that is not found", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("DELETE", "edge_applications/1234/functions_instances/4321"), - httpmock.StatusStringResponse(404, "Not Found"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - - cmd.SetArgs([]string{"-a", "1234", "-i", "4321"}) - - _, err := cmd.ExecuteC() - require.Error(t, err) - }) -} diff --git a/pkg/cmd/edge_functions_instances/describe/describe.go b/pkg/cmd/edge_functions_instances/describe/describe.go deleted file mode 100644 index 04d7d6745..000000000 --- a/pkg/cmd/edge_functions_instances/describe/describe.go +++ /dev/null @@ -1,101 +0,0 @@ -package describe - -import ( - "context" - "encoding/json" - "fmt" - "path/filepath" - - "github.com/fatih/color" - - "github.com/MakeNowJust/heredoc" - "github.com/aziontech/tablecli" - msg "github.com/aziontech/azion-cli/messages/edge_functions_instances" - - api "github.com/aziontech/azion-cli/pkg/api/edge_applications" - "github.com/aziontech/azion-cli/pkg/cmdutil" - "github.com/aziontech/azion-cli/pkg/contracts" - "github.com/aziontech/azion-cli/utils" - "github.com/spf13/cobra" -) - -var ( - applicationID int64 - instanceID int64 -) - -func NewCmd(f *cmdutil.Factory) *cobra.Command { - opts := &contracts.DescribeOptions{} - cmd := &cobra.Command{ - Use: msg.EdgeFuncInstanceDescribeUsage, - Short: msg.EdgeFuncInstanceDescribeShortDescription, - Long: msg.EdgeFuncInstanceDescribeLongDescription, - SilenceUsage: true, - SilenceErrors: true, - Example: heredoc.Doc(` - $ azion edge_functions_instances describe --application-id 1674767911 --instance-id 31223 - $ azion edge_functions_instances describe --application-id 1674767911 --instance-id 31223 --format json - $ azion edge_functions_instances describe --application-id 1674767911 --instance-id 31223 --out "./tmp/test.json" - `), - RunE: func(cmd *cobra.Command, args []string) error { - if !cmd.Flags().Changed("application-id") || !cmd.Flags().Changed("instance-id") { - return msg.ErrorMandatoryFlags - } - - client := api.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) - ctx := context.Background() - instance, err := client.GetFuncInstance(ctx, applicationID, instanceID) - if err != nil { - return fmt.Errorf(msg.ErrorGetEdgeFuncInstances.Error(), err) - } - - out := f.IOStreams.Out - formattedFuction, err := format(cmd, instance) - if err != nil { - return utils.ErrorFormatOut - } - - if cmd.Flags().Changed("out") { - err := cmdutil.WriteDetailsToFile(formattedFuction, opts.OutPath, out) - if err != nil { - return fmt.Errorf("%s: %w", utils.ErrorWriteFile, err) - } - fmt.Fprintf(out, msg.EdgeFuncInstanceFileWritten, filepath.Clean(opts.OutPath)) - } else { - _, err := out.Write(formattedFuction[:]) - if err != nil { - return err - } - } - - return nil - }, - } - - cmd.Flags().Int64VarP(&applicationID, "application-id", "a", 0, msg.ApplicationFlagId) - cmd.Flags().Int64VarP(&instanceID, "instance-id", "i", 0, msg.EdgeFuncInstanceFlagId) - cmd.Flags().StringVar(&opts.OutPath, "out", "", msg.EdgeFuncInstanceDescribeFlagOut) - cmd.Flags().StringVar(&opts.Format, "format", "", msg.EdgeFuncInstanceDescribeFlagFormat) - cmd.Flags().BoolP("help", "h", false, msg.EdgeFuncInstanceDescribeHelpFlag) - - return cmd -} - -func format(cmd *cobra.Command, instance api.FunctionsInstancesResponse) ([]byte, error) { - format, err := cmd.Flags().GetString("format") - if err != nil { - return nil, err - } - - if format == "json" || cmd.Flags().Changed("out") { - return json.MarshalIndent(instance, "", " ") - } - - tbl := tablecli.New("", "") - tbl.WithFirstColumnFormatter(color.New(color.FgGreen).SprintfFunc()) - tbl.AddRow("Edge Function Instance ID: ", instance.GetId()) - tbl.AddRow("Instance Name: ", instance.GetName()) - tbl.AddRow("Edge Function ID: ", instance.GetEdgeFunctionId()) - tbl.AddRow("Args: ", instance.GetArgs()) - return tbl.GetByteFormat(), nil -} diff --git a/pkg/cmd/edge_functions_instances/describe/describe_test.go b/pkg/cmd/edge_functions_instances/describe/describe_test.go deleted file mode 100644 index 84f22e29e..000000000 --- a/pkg/cmd/edge_functions_instances/describe/describe_test.go +++ /dev/null @@ -1,98 +0,0 @@ -package describe - -import ( - "github.com/aziontech/azion-cli/pkg/logger" - "go.uber.org/zap/zapcore" - "log" - "net/http" - "os" - "testing" - - msg "github.com/aziontech/azion-cli/messages/edge_functions_instances" - "github.com/aziontech/azion-cli/pkg/httpmock" - "github.com/aziontech/azion-cli/pkg/testutils" - "github.com/stretchr/testify/require" -) - -func TestDescribe(t *testing.T) { - logger.New(zapcore.DebugLevel) - t.Run("describe a function instance", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_applications/1678743802/functions_instances/9767"), - httpmock.JSONFromFile("./fixtures/instance.json"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - cmd.SetArgs([]string{"-a", "1678743802", "-i", "9767"}) - - err := cmd.Execute() - require.NoError(t, err) - }) - t.Run("not found", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_applications/1678743802/rules_engine/request/rules/666"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) - - f, _, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - - err := cmd.Execute() - require.Error(t, err) - }) - - t.Run("missing mandatory flag", func(t *testing.T) { - mock := &httpmock.Registry{} - mock.Register( - httpmock.REST("GET", "edge_applications/1678743802/functions_instances/9767"), - httpmock.StatusStringResponse(http.StatusNotFound, "Not Found"), - ) - - f, _, _ := testutils.NewFactory(mock) - cmd := NewCmd(f) - cmd.SetArgs([]string{}) - - err := cmd.Execute() - require.ErrorIs(t, err, msg.ErrorMandatoryFlags) - }) - - t.Run("export to a file", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_applications/1678743802/functions_instances/9767"), - httpmock.JSONFromFile("./fixtures/instance.json"), - ) - - f, stdout, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - path := "./out.json" - cmd.SetArgs([]string{"-a", "1678743802", "-i", "9767", "--out", path}) - - err := cmd.Execute() - if err != nil { - log.Println("error executing cmd err: ", err.Error()) - } - - _, err = os.ReadFile(path) - if err != nil { - t.Fatalf("error reading `out.json`: %v", err) - } - defer func() { - _ = os.Remove(path) - }() - - require.NoError(t, err) - - require.Equal(t, `File successfully written to: out.json -`, stdout.String()) - }) -} diff --git a/pkg/cmd/edge_functions_instances/describe/fixtures/instance.json b/pkg/cmd/edge_functions_instances/describe/fixtures/instance.json deleted file mode 100644 index d74d7eab1..000000000 --- a/pkg/cmd/edge_functions_instances/describe/fixtures/instance.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "results": { - "id": 9767, - "edge_function_id": 8375, - "name": "wasa", - "args": {} - }, - "schema_version": 3 - } \ No newline at end of file diff --git a/pkg/cmd/edge_functions_instances/edge_functions_instances.go b/pkg/cmd/edge_functions_instances/edge_functions_instances.go deleted file mode 100644 index 28a27d423..000000000 --- a/pkg/cmd/edge_functions_instances/edge_functions_instances.go +++ /dev/null @@ -1,36 +0,0 @@ -package edge_functions_instances - -import ( - "github.com/MakeNowJust/heredoc" - msg "github.com/aziontech/azion-cli/messages/edge_functions_instances" - "github.com/aziontech/azion-cli/pkg/cmd/edge_functions_instances/create" - "github.com/aziontech/azion-cli/pkg/cmd/edge_functions_instances/delete" - "github.com/aziontech/azion-cli/pkg/cmd/edge_functions_instances/describe" - "github.com/aziontech/azion-cli/pkg/cmd/edge_functions_instances/list" - "github.com/aziontech/azion-cli/pkg/cmd/edge_functions_instances/update" - "github.com/aziontech/azion-cli/pkg/cmdutil" - "github.com/spf13/cobra" -) - -func NewCmd(f *cmdutil.Factory) *cobra.Command { - funcInstCmd := &cobra.Command{ - Use: msg.EdgeFuncInstanceUsage, - Short: msg.EdgeFuncInstanceShortDescription, - Long: msg.EdgeFuncInstanceLongDescription, - Example: heredoc.Doc(` - $ azion edge_functions_instances --help - `), - RunE: func(cmd *cobra.Command, args []string) error { - return cmd.Help() - }, - } - - funcInstCmd.AddCommand(delete.NewCmd(f)) - funcInstCmd.AddCommand(create.NewCmd(f)) - funcInstCmd.AddCommand(describe.NewCmd(f)) - funcInstCmd.AddCommand(list.NewCmd(f)) - funcInstCmd.AddCommand(update.NewCmd(f)) - - funcInstCmd.Flags().BoolP("help", "h", false, msg.EdgeFuncInstanceFlagHelp) - return funcInstCmd -} diff --git a/pkg/cmd/edge_functions_instances/list/.fixtures/no_resp.json b/pkg/cmd/edge_functions_instances/list/.fixtures/no_resp.json deleted file mode 100644 index 8e5297f29..000000000 --- a/pkg/cmd/edge_functions_instances/list/.fixtures/no_resp.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "count": 0, - "total_pages": 1, - "schema_version": 3, - "links": { - "previous": null, - "next": null - }, - "results": [] -} - diff --git a/pkg/cmd/edge_functions_instances/list/.fixtures/resp.json b/pkg/cmd/edge_functions_instances/list/.fixtures/resp.json deleted file mode 100644 index 8a75c401a..000000000 --- a/pkg/cmd/edge_functions_instances/list/.fixtures/resp.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "count": 2, - "total_pages": 1, - "schema_version": 3, - "links": { - "previous": null, - "next": null - }, - "results": [ - { - "id": 1674040168, - "edge_function_id": 104014, - "name": "asdfasdfsadf", - "args": {} - } - ] -} diff --git a/pkg/cmd/edge_functions_instances/list/list.go b/pkg/cmd/edge_functions_instances/list/list.go deleted file mode 100644 index 2b2c434de..000000000 --- a/pkg/cmd/edge_functions_instances/list/list.go +++ /dev/null @@ -1,107 +0,0 @@ -package list - -import ( - "context" - "fmt" - "strings" - - "github.com/fatih/color" - - "github.com/MakeNowJust/heredoc" - table "github.com/aziontech/tablecli" - msg "github.com/aziontech/azion-cli/messages/edge_functions_instances" - api "github.com/aziontech/azion-cli/pkg/api/edge_applications" - "github.com/aziontech/azion-cli/pkg/cmdutil" - "github.com/aziontech/azion-cli/pkg/contracts" - "github.com/spf13/cobra" -) - -func NewCmd(f *cmdutil.Factory) *cobra.Command { - opts := &contracts.ListOptions{} - var edgeApplicationID int64 = 0 - cmd := &cobra.Command{ - Use: msg.EdgeFunctionsInstancesListUsage, - Short: msg.EdgeFunctionsInstancesListLongDescription, - Long: msg.EdgeFunctionsInstancesListLongDescription, - SilenceUsage: true, - SilenceErrors: true, Example: heredoc.Doc(` - $ azion edge_functions_instances list --application-id 1234123423 --details - $ azion edge_functions_instances list --application-id 1234123423 --order-by "id" - $ azion edge_functions_instances list --application-id 1234123423 --page 1 - $ azion edge_functions_instances list --application-id 1234123423 --page_size 5 - $ azion edge_functions_instances list -a 1234123423 --sort "asc" - $ azion edge_functions_instances list -a 1234123423" - `), - - RunE: func(cmd *cobra.Command, args []string) error { - var numberPage int64 = opts.Page - if !cmd.Flags().Changed("application-id") { - return msg.ErrorMandatoryListFlags - } - if !cmd.Flags().Changed("page") && !cmd.Flags().Changed("page_size") { - for { - pages, err := PrintTable(cmd, f, opts, &numberPage, edgeApplicationID) - if numberPage > pages && err == nil { - return nil - } - if err != nil { - return fmt.Errorf(msg.ErrorGetFunctions.Error(), err) - } - } - } - - if _, err := PrintTable(cmd, f, opts, &numberPage, edgeApplicationID); err != nil { - return fmt.Errorf(msg.ErrorGetFunctions.Error(), err) - } - return nil - }, - } - - cmdutil.AddAzionApiFlags(cmd, opts) - cmd.Flags().Int64VarP(&edgeApplicationID, "application-id", "a", 0, msg.EdgeApplicationFlagId) - cmd.Flags().BoolP("help", "h", false, msg.EdgeFunctionsInstancesListHelpFlag) - return cmd -} - -func PrintTable(cmd *cobra.Command, f *cmdutil.Factory, opts *contracts.ListOptions, numberPage *int64, edgeApplicationID int64) (int64, error) { - client := api.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) - ctx := context.Background() - - applications, err := client.EdgeFuncInstancesList(ctx, opts, edgeApplicationID) - if err != nil { - return 0, fmt.Errorf(msg.ErrorGetFunctions.Error(), err) - } - - tbl := table.New("ID", "NAME") - table.DefaultWriter = f.IOStreams.Out - if cmd.Flags().Changed("details") { - tbl = table.New("ID", "EDGE FUNCTIONS ID", "NAME", "ARGS") - } - - headerFmt := color.New(color.FgBlue, color.Underline).SprintfFunc() - columnFmt := color.New(color.FgGreen).SprintfFunc() - tbl.WithHeaderFormatter(headerFmt).WithFirstColumnFormatter(columnFmt) - - for _, v := range applications.Results { - if cmd.Flags().Changed("details") { - tbl.AddRow(v.Id, v.EdgeFunctionId, v.Name, v.Args) - } else { - tbl.AddRow(v.Id, v.Name) - } - } - - format := strings.Repeat("%s", len(tbl.GetHeader())) + "\n" - tbl.CalculateWidths([]string{}) - if *numberPage == 1 { - tbl.PrintHeader(format) - } - - for _, row := range tbl.GetRows() { - tbl.PrintRow(format, row) - } - - *numberPage += 1 - opts.Page = *numberPage - f.IOStreams.Out = table.DefaultWriter - return applications.TotalPages, nil -} diff --git a/pkg/cmd/edge_functions_instances/list/list_test.go b/pkg/cmd/edge_functions_instances/list/list_test.go deleted file mode 100644 index c7ddd38df..000000000 --- a/pkg/cmd/edge_functions_instances/list/list_test.go +++ /dev/null @@ -1,48 +0,0 @@ -package list - -import ( - "testing" - - "github.com/aziontech/azion-cli/pkg/httpmock" - "github.com/aziontech/azion-cli/pkg/logger" - "github.com/aziontech/azion-cli/pkg/testutils" - "github.com/stretchr/testify/require" - "go.uber.org/zap/zapcore" -) - -func TestList(t *testing.T) { - logger.New(zapcore.DebugLevel) - t.Run("command list with successes", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_applications/1674040168/functions_instances"), - httpmock.JSONFromFile(".fixtures/resp.json"), - ) - - f, _, _ := testutils.NewFactory(mock) - cmd := NewCmd(f) - - cmd.SetArgs([]string{"-a", "1674040168"}) - - _, err := cmd.ExecuteC() - require.NoError(t, err) - }) - - t.Run("command list response without items", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST("GET", "edge_applications/1674040168/functions_instances"), - httpmock.JSONFromFile(".fixtures/no_resp.json"), - ) - - f, _, _ := testutils.NewFactory(mock) - cmd := NewCmd(f) - - cmd.SetArgs([]string{"-a", "1674040168"}) - - _, err := cmd.ExecuteC() - require.NoError(t, err) - }) -} diff --git a/pkg/cmd/edge_functions_instances/update/fixtures/instance.json b/pkg/cmd/edge_functions_instances/update/fixtures/instance.json deleted file mode 100644 index 31651bb60..000000000 --- a/pkg/cmd/edge_functions_instances/update/fixtures/instance.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "results": { - "id": 9810, - "edge_function_id": 8065, - "name": "updated", - "args": {} - }, - "schema_version": 3 - } \ No newline at end of file diff --git a/pkg/cmd/edge_functions_instances/update/fixtures/update.json b/pkg/cmd/edge_functions_instances/update/fixtures/update.json deleted file mode 100644 index a984bcfd0..000000000 --- a/pkg/cmd/edge_functions_instances/update/fixtures/update.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "args": {}, - "edge_function_id": 8065, - "id": 9810, - "name": "atualizeipelofile" - } \ No newline at end of file diff --git a/pkg/cmd/edge_functions_instances/update/update.go b/pkg/cmd/edge_functions_instances/update/update.go deleted file mode 100644 index f140c02ac..000000000 --- a/pkg/cmd/edge_functions_instances/update/update.go +++ /dev/null @@ -1,97 +0,0 @@ -package update - -import ( - "context" - "fmt" - "os" - - "github.com/MakeNowJust/heredoc" - - msg "github.com/aziontech/azion-cli/messages/edge_functions_instances" - api "github.com/aziontech/azion-cli/pkg/api/edge_applications" - - "github.com/aziontech/azion-cli/pkg/cmdutil" - "github.com/aziontech/azion-cli/utils" - "github.com/spf13/cobra" -) - -type Fields struct { - ApplicationID string - Name string - FunctionID int64 - InstanceID string - Path string - Args string -} - -func NewCmd(f *cmdutil.Factory) *cobra.Command { - fields := &Fields{} - - cmd := &cobra.Command{ - Use: msg.EdgeFuncInstanceUpdateUsage, - Short: msg.EdgeFuncInstanceUpdateShortDescription, - Long: msg.EdgeFuncInstanceUpdateLongDescription, - SilenceUsage: true, - SilenceErrors: true, - Example: heredoc.Doc(` - $ azion edge_functions_instances update -a 1674767911 -i 43121 -f 1209 - $ azion edge_functions_instances update --application-id 1674767911 --instance-id 2121 --function-id 1212 --name updated - $ azion edge_functions_instances update -a 1674767911 -i 43121 --in "update.json" - `), - RunE: func(cmd *cobra.Command, args []string) error { - if cmd.Flags().Changed("in") && (!cmd.Flags().Changed("application-id") || !cmd.Flags().Changed("instance-id")) { - return msg.ErrorMandatoryUpdateFlagsIn - } - request := api.UpdateInstanceRequest{} - if cmd.Flags().Changed("in") { - var ( - file *os.File - err error - ) - if fields.Path == "-" { - file = os.Stdin - } else { - file, err = os.Open(fields.Path) - if err != nil { - return fmt.Errorf("%w: %s", utils.ErrorOpeningFile, fields.Path) - } - } - err = cmdutil.UnmarshallJsonFromReader(file, &request) - if err != nil { - return utils.ErrorUnmarshalReader - } - } else { - if !cmd.Flags().Changed("application-id") || !cmd.Flags().Changed("instance-id") || !cmd.Flags().Changed("function-id") { - return msg.ErrorMandatoryUpdateFlags - } - if cmd.Flags().Changed("name") { - request.SetName(fields.Name) - } - if cmd.Flags().Changed("function-id") { - request.SetEdgeFunctionId(fields.FunctionID) - } - if cmd.Flags().Changed("args") { - request.SetArgs(fields.Args) - } - } - - client := api.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) - response, err := client.UpdateInstance(context.Background(), &request, fields.ApplicationID, fields.InstanceID) - if err != nil { - return fmt.Errorf(msg.ErrorUpdateFuncInstance.Error(), err) - } - fmt.Fprintf(f.IOStreams.Out, msg.EdgeFuncInstanceUpdateOutputSuccess, response.GetId()) - return nil - }, - } - - flags := cmd.Flags() - flags.StringVarP(&fields.ApplicationID, "application-id", "a", "0", msg.EdgeFuncInstanceUpdateFlagEdgeApplicationId) - flags.StringVar(&fields.Name, "name", "", msg.EdgeFuncInstanceUpdateFlagName) - flags.StringVar(&fields.Args, "args", "", msg.EdgeFuncInstanceUpdateFlagArgs) - flags.Int64VarP(&fields.FunctionID, "function-id", "f", 0, msg.EdgeFuncInstanceUpdateFlagFunctionID) - flags.StringVarP(&fields.InstanceID, "instance-id", "i", "0", msg.EdgeFuncInstanceUpdateFlagInstanceID) - flags.StringVar(&fields.Path, "in", "", msg.EdgeFuncInstanceUpdateFlagIn) - flags.BoolP("help", "h", false, msg.EdgeFuncInstanceUpdateHelpFlag) - return cmd -} diff --git a/pkg/cmd/edge_functions_instances/update/update_test.go b/pkg/cmd/edge_functions_instances/update/update_test.go deleted file mode 100644 index b5f93dde7..000000000 --- a/pkg/cmd/edge_functions_instances/update/update_test.go +++ /dev/null @@ -1,73 +0,0 @@ -package update - -import ( - "fmt" - "github.com/aziontech/azion-cli/pkg/logger" - "go.uber.org/zap/zapcore" - "net/http" - "testing" - - msg "github.com/aziontech/azion-cli/messages/edge_functions_instances" - "github.com/aziontech/azion-cli/pkg/httpmock" - "github.com/aziontech/azion-cli/pkg/testutils" - "github.com/stretchr/testify/require" -) - -func TestUpdate(t *testing.T) { - logger.New(zapcore.DebugLevel) - t.Run("update instance", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST(http.MethodPatch, "edge_applications/1678743802/functions_instances/9810"), - httpmock.JSONFromFile("./fixtures/instance.json"), - ) - - f, stdout, _ := testutils.NewFactory(mock) - cmd := NewCmd(f) - - cmd.SetArgs([]string{ - "--application-id", "1678743802", - "--instance-id", "9810", - "--function-id", "8065", - "--name", "updated", - }) - - err := cmd.Execute() - require.NoError(t, err) - require.Equal(t, fmt.Sprintf(msg.EdgeFuncInstanceUpdateOutputSuccess, 9810), stdout.String()) - }) - - t.Run("missing flags", func(t *testing.T) { - - f, _, _ := testutils.NewFactory(nil) - - cmd := NewCmd(f) - err := cmd.Execute() - - require.ErrorIs(t, err, msg.ErrorMandatoryUpdateFlags) - }) - - t.Run("update with file", func(t *testing.T) { - mock := &httpmock.Registry{} - - mock.Register( - httpmock.REST(http.MethodPatch, "edge_applications/1673635839/functions_instances/9810"), - httpmock.JSONFromFile("./fixtures/instance.json"), - ) - - f, stdout, _ := testutils.NewFactory(mock) - - cmd := NewCmd(f) - cmd.SetArgs([]string{ - "--application-id", "1673635839", - "--in", "./fixtures/update.json", - "--instance-id", "9810", - }) - - err := cmd.Execute() - - require.NoError(t, err) - require.Equal(t, fmt.Sprintf(msg.EdgeFuncInstanceUpdateOutputSuccess, 9810), stdout.String()) - }) -} diff --git a/pkg/cmd/link/link.go b/pkg/cmd/link/link.go index 72a3dce09..796f5456f 100644 --- a/pkg/cmd/link/link.go +++ b/pkg/cmd/link/link.go @@ -33,6 +33,7 @@ type LinkInfo struct { GlobalFlagAll bool remote string Auto bool + projectPath string } type LinkCmd struct { @@ -119,6 +120,7 @@ func NewCobraCmd(link *LinkCmd, f *cmdutil.Factory) *cobra.Command { cobraCmd.Flags().StringVar(&info.Mode, "mode", "", msg.EdgeApplicationsLinkFlagMode) cobraCmd.Flags().BoolVar(&info.Auto, "auto", false, msg.LinkFlagAuto) cobraCmd.Flags().StringVar(&info.remote, "remote", "", msg.FLAG_REMOTE) + cobraCmd.Flags().StringVar(&info.projectPath, "config-dir", "azion", msg.FLAGPATHCONF) return cobraCmd } @@ -232,7 +234,7 @@ func (cmd *LinkCmd) run(c *cobra.Command, info *LinkInfo) error { logger.Debug("Running deploy command from link command") deploy := cmd.DeployCmd(cmd.F) - err = deploy.Run(cmd.F) + err = deploy.ExternalRun(cmd.F, info.projectPath) if err != nil { logger.Debug("Error while running deploy command called by link command", zap.Error(err)) return err diff --git a/pkg/cmd/link/template.go b/pkg/cmd/link/template.go index d712b0ff9..e126300e1 100644 --- a/pkg/cmd/link/template.go +++ b/pkg/cmd/link/template.go @@ -2,6 +2,7 @@ package link import ( "encoding/json" + "path" "strings" msg "github.com/aziontech/azion-cli/messages/init" @@ -11,22 +12,22 @@ import ( func (cmd *LinkCmd) createTemplateAzion(info *LinkInfo) error { - err := cmd.Mkdir(info.PathWorkingDir+"/azion", 0755) // 0755 is the permission mode for the new directories + err := cmd.Mkdir(path.Join(info.PathWorkingDir, info.projectPath), 0755) // 0755 is the permission mode for the new directories if err != nil { return msg.ErrorFailedCreatingAzionDirectory } azionJson := &contracts.AzionApplicationOptions{ - Name: info.Name, - Env: "production", + Name: info.Name, + Env: "production", Preset: strings.ToLower(info.Preset), - Mode: strings.ToLower(info.Mode), - Prefix: "", + Mode: strings.ToLower(info.Mode), + Prefix: "", } azionJson.Function.Name = "__DEFAULT__" azionJson.Function.InstanceName = "__DEFAULT__" azionJson.Function.File = "./out/worker.js" - azionJson.Function.Args = "./azion/args.json" + azionJson.Function.Args = path.Join(info.projectPath, "args.json") azionJson.Domain.Name = "__DEFAULT__" azionJson.Application.Name = "__DEFAULT__" azionJson.RtPurge.PurgeOnPublish = true @@ -41,7 +42,7 @@ func (cmd *LinkCmd) createJsonFile(options *contracts.AzionApplicationOptions, i return msg.ErrorUnmarshalAzionFile } - err = cmd.WriteFile(info.PathWorkingDir+"/azion/azion.json", data, 0644) + err = cmd.WriteFile(path.Join(info.PathWorkingDir, info.projectPath, "azion.json"), data, 0644) if err != nil { return utils.ErrorInternalServerError } diff --git a/pkg/cmd/link/utils.go b/pkg/cmd/link/utils.go index 5fbbfa61f..3cead854c 100644 --- a/pkg/cmd/link/utils.go +++ b/pkg/cmd/link/utils.go @@ -28,7 +28,7 @@ func shouldDevDeploy(info *LinkInfo, msg string, defaultYes bool) bool { func shouldFetch(cmd *LinkCmd, info *LinkInfo) (bool, error) { var err error var shouldFetchTemplates bool - if empty, _ := cmd.IsDirEmpty("./azion"); !empty { + if empty, _ := cmd.IsDirEmpty(info.projectPath); !empty { if info.GlobalFlagAll || info.Auto { shouldFetchTemplates = true } else { @@ -36,7 +36,7 @@ func shouldFetch(cmd *LinkCmd, info *LinkInfo) (bool, error) { } if shouldFetchTemplates { - err = cmd.CleanDir("./azion") + err = cmd.CleanDir(info.projectPath) if err != nil { logger.Debug("Error while trying to clean azion directory", zap.Error(err)) return false, err diff --git a/pkg/cmd/root/root.go b/pkg/cmd/root/root.go index 52f0e33f4..da1fced79 100644 --- a/pkg/cmd/root/root.go +++ b/pkg/cmd/root/root.go @@ -19,6 +19,7 @@ import ( logcmd "github.com/aziontech/azion-cli/pkg/cmd/logs" "github.com/aziontech/azion-cli/pkg/cmd/purge" "github.com/aziontech/azion-cli/pkg/cmd/reset" + "github.com/aziontech/azion-cli/pkg/cmd/sync" "github.com/aziontech/azion-cli/pkg/cmd/unlink" "github.com/aziontech/azion-cli/pkg/cmd/update" "github.com/aziontech/azion-cli/pkg/cmd/whoami" @@ -151,6 +152,7 @@ func NewCobraCmd(rootCmd *RootCmd, f *cmdutil.Factory) *cobra.Command { cobraCmd.AddCommand(whoami.NewCmd(f)) cobraCmd.AddCommand(purge.NewCmd(f)) cobraCmd.AddCommand(reset.NewCmd(f)) + cobraCmd.AddCommand(sync.NewCmd(f)) return cobraCmd } diff --git a/pkg/cmd/sync/sync.go b/pkg/cmd/sync/sync.go new file mode 100644 index 000000000..396406e09 --- /dev/null +++ b/pkg/cmd/sync/sync.go @@ -0,0 +1,85 @@ +package sync + +import ( + "github.com/MakeNowJust/heredoc" + msg "github.com/aziontech/azion-cli/messages/sync" + "github.com/aziontech/azion-cli/pkg/cmdutil" + "github.com/aziontech/azion-cli/pkg/contracts" + "github.com/aziontech/azion-cli/pkg/iostreams" + "github.com/aziontech/azion-cli/pkg/logger" + "github.com/aziontech/azion-cli/utils" + "github.com/spf13/cobra" + "go.uber.org/zap" +) + +var ProjectConf string + +type SyncCmd struct { + Io *iostreams.IOStreams + GetAzionJsonContent func(confPath string) (*contracts.AzionApplicationOptions, error) + WriteAzionJsonContent func(conf *contracts.AzionApplicationOptions, confPath string) error + F *cmdutil.Factory +} + +func NewDevCmd(f *cmdutil.Factory) *SyncCmd { + return &SyncCmd{ + F: f, + Io: f.IOStreams, + GetAzionJsonContent: utils.GetAzionJsonContent, + WriteAzionJsonContent: utils.WriteAzionJsonContent, + } +} + +func NewCobraCmd(sync *SyncCmd) *cobra.Command { + syncCmd := &cobra.Command{ + Use: msg.USAGE, + Short: msg.SHORTDESCRIPTION, + Long: msg.LONGDESCRIPTION, + SilenceUsage: true, + SilenceErrors: true, + Example: heredoc.Doc(` + $ azion sync + $ azion sync --help + `), + RunE: func(cmd *cobra.Command, args []string) error { + return sync.Run(sync.F) + }, + } + syncCmd.Flags().BoolP("help", "h", false, msg.HELPFLAG) + syncCmd.Flags().StringVar(&ProjectConf, "config-dir", "azion", msg.CONFDIRFLAG) + return syncCmd +} + +func NewCmd(f *cmdutil.Factory) *cobra.Command { + return NewCobraCmd(NewDevCmd(f)) +} + +func (cmd *SyncCmd) Run(f *cmdutil.Factory) error { + logger.Debug("Running sync command") + + conf, err := cmd.GetAzionJsonContent(ProjectConf) + if err != nil { + logger.Debug("Failed to get Azion JSON content", zap.Error(err)) + return err + } + + ruleIds := make(map[string]contracts.RuleIdsStruct) + for _, ruleConf := range conf.RulesEngine.Rules { + ruleIds[ruleConf.Name] = contracts.RuleIdsStruct{ + Id: ruleConf.Id, + Phase: ruleConf.Phase, + } + } + + info := contracts.SyncOpts{ + RuleIds: ruleIds, + Conf: conf, + } + + err = cmd.SyncResources(f, info) + if err != nil { + return err + } + + return nil +} diff --git a/pkg/cmd/sync/tasks.go b/pkg/cmd/sync/tasks.go new file mode 100644 index 000000000..f23cc56c6 --- /dev/null +++ b/pkg/cmd/sync/tasks.go @@ -0,0 +1,59 @@ +package sync + +import ( + "context" + "fmt" + + msg "github.com/aziontech/azion-cli/messages/sync" + api "github.com/aziontech/azion-cli/pkg/api/edge_applications" + "github.com/aziontech/azion-cli/pkg/cmdutil" + "github.com/aziontech/azion-cli/pkg/contracts" + "github.com/aziontech/azion-cli/pkg/logger" + "go.uber.org/zap" +) + +var ( + C context.Context + Opts *contracts.ListOptions +) + +func (synch *SyncCmd) SyncResources(f *cmdutil.Factory, info contracts.SyncOpts) error { + C = context.Background() + Opts = &contracts.ListOptions{ + PageSize: 1000, + Page: 1, + } + err := synch.syncRules(info, f) + if err != nil { + return fmt.Errorf(msg.ERRORSYNC, err.Error()) + } + return nil +} + +func (synch *SyncCmd) syncRules(info contracts.SyncOpts, f *cmdutil.Factory) error { + + client := api.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) + resp, err := client.ListRulesEngine(C, Opts, info.Conf.Application.ID, "request") + if err != nil { + return err + } + + for _, rule := range resp.Results { + if r := info.RuleIds[rule.Name]; r.Id > 0 || rule.Name == "Default Rule" { + // if remote rule is also on local environment, no action is needed + continue + } + newRule := contracts.AzionJsonDataRules{ + Id: rule.GetId(), + Name: rule.GetName(), + } + info.Conf.RulesEngine.Rules = append(info.Conf.RulesEngine.Rules, newRule) + err := synch.WriteAzionJsonContent(info.Conf, ProjectConf) + if err != nil { + logger.Debug("Error while writing azion.json file", zap.Error(err)) + return err + } + logger.FInfo(synch.Io.Out, fmt.Sprintf(msg.SYNCMESSAGERULE, rule.Name)) + } + return nil +} diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index 30c38ab99..38dbdcc6e 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -8,6 +8,5 @@ var ( ) const ( - PathAzionJson = "/azion/azion.json" - FORMAT_DATE = "2006-01-02 15:04:05 -0700 MST" + FORMAT_DATE = "2006-01-02 15:04:05 -0700 MST" ) diff --git a/pkg/contracts/contracts.go b/pkg/contracts/contracts.go index 8c490c622..089713bba 100644 --- a/pkg/contracts/contracts.go +++ b/pkg/contracts/contracts.go @@ -19,6 +19,7 @@ type BuildInfo struct { Entry string NodePolyfills string OwnWorker string + ProjectPath string IsFirewall bool } @@ -137,8 +138,9 @@ type AzionJsonDataRulesEngine struct { } type AzionJsonDataRules struct { - Id int64 `json:"id"` - Name string `json:"name"` + Id int64 `json:"id"` + Name string `json:"name"` + Phase string `json:"phase"` } type AzionJsonDataCacheSettings struct { @@ -188,11 +190,19 @@ type Origin struct { type RuleEngine struct { Name string `json:"name"` Description *string `json:"description,omitempty"` + Phase string `json:"phase,omitempty"` + Order int64 `json:"order,omitempty"` + IsActive bool `json:"is_active,omitempty"` Criteria [][]sdk.RulesEngineCriteria `json:"criteria,omitempty"` Behaviors []sdk.RulesEngineBehaviorEntry `json:"behaviors,omitempty"` } -type RulesEngineBehaviorEntry struct { - RulesEngineBehaviorObject *sdk.RulesEngineBehaviorObject - RulesEngineBehaviorString *sdk.RulesEngineBehaviorString +type SyncOpts struct { + RuleIds map[string]RuleIdsStruct + Conf *AzionApplicationOptions +} + +type RuleIdsStruct struct { + Id int64 + Phase string } diff --git a/pkg/manifest/fixtures/manifest.json b/pkg/manifest/fixtures/manifest.json index 77be9bfab..0569afae9 100644 --- a/pkg/manifest/fixtures/manifest.json +++ b/pkg/manifest/fixtures/manifest.json @@ -13,6 +13,7 @@ "rules": [ { "name": "nomezinhomatotinho", + "phase": "request", "criteria": [ [ { diff --git a/pkg/manifest/manifest.go b/pkg/manifest/manifest.go index b35d4af77..f9964943d 100644 --- a/pkg/manifest/manifest.go +++ b/pkg/manifest/manifest.go @@ -25,7 +25,7 @@ import ( var ( CacheIds map[string]int64 CacheIdsBackup map[string]int64 - RuleIds map[string]int64 + RuleIds map[string]contracts.RuleIdsStruct OriginKeys map[string]string OriginIds map[string]int64 manifestFilePath = "/.edge/manifest.json" @@ -34,7 +34,7 @@ var ( type ManifestInterpreter struct { FileReader func(path string) ([]byte, error) GetWorkDir func() (string, error) - WriteAzionJsonContent func(conf *contracts.AzionApplicationOptions) error + WriteAzionJsonContent func(conf *contracts.AzionApplicationOptions, confPath string) error } func NewManifestInterpreter() *ManifestInterpreter { @@ -71,7 +71,7 @@ func (man *ManifestInterpreter) ReadManifest(path string, f *cmdutil.Factory) (* return manifest, nil } -func (man *ManifestInterpreter) CreateResources(conf *contracts.AzionApplicationOptions, manifest *contracts.Manifest, f *cmdutil.Factory) error { +func (man *ManifestInterpreter) CreateResources(conf *contracts.AzionApplicationOptions, manifest *contracts.Manifest, f *cmdutil.Factory, projectConf string) error { logger.FInfo(f.IOStreams.Out, msg.CreatingManifest) client := apiEdgeApplications.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) @@ -81,7 +81,7 @@ func (man *ManifestInterpreter) CreateResources(conf *contracts.AzionApplication CacheIds = make(map[string]int64) CacheIdsBackup = make(map[string]int64) - RuleIds = make(map[string]int64) + RuleIds = make(map[string]contracts.RuleIdsStruct) OriginKeys = make(map[string]string) OriginIds = make(map[string]int64) @@ -90,7 +90,10 @@ func (man *ManifestInterpreter) CreateResources(conf *contracts.AzionApplication } for _, ruleConf := range conf.RulesEngine.Rules { - RuleIds[ruleConf.Name] = ruleConf.Id + RuleIds[ruleConf.Name] = contracts.RuleIdsStruct{ + Id: ruleConf.Id, + Phase: ruleConf.Phase, + } } for _, originConf := range conf.Origin { @@ -109,7 +112,7 @@ func (man *ManifestInterpreter) CreateResources(conf *contracts.AzionApplication } updated, err := clientOrigin.Update(ctx, conf.Application.ID, OriginKeys[origin.Name], requestUpdate) if err != nil { - return err + return fmt.Errorf("%w: %s", msg.ErrorUpdateOrigin, err.Error()) } newEntry := contracts.AzionJsonDataOrigin{ @@ -128,7 +131,7 @@ func (man *ManifestInterpreter) CreateResources(conf *contracts.AzionApplication } created, err := clientOrigin.Create(ctx, conf.Application.ID, requestCreate) if err != nil { - return err + return fmt.Errorf("%w: %s", msg.ErrorCreateOrigin, err.Error()) } newOrigin := contracts.AzionJsonDataOrigin{ OriginId: created.GetOriginId(), @@ -144,7 +147,7 @@ func (man *ManifestInterpreter) CreateResources(conf *contracts.AzionApplication } conf.Origin = originConf - err := man.WriteAzionJsonContent(conf) + err := man.WriteAzionJsonContent(conf, projectConf) if err != nil { logger.Debug("Error while writing azion.json file", zap.Error(err)) return err @@ -161,7 +164,7 @@ func (man *ManifestInterpreter) CreateResources(conf *contracts.AzionApplication } updated, err := clientCache.Update(ctx, requestUpdate, conf.Application.ID, id) if err != nil { - return err + return fmt.Errorf("%w: %s", msg.ErrorUpdateCache, err.Error()) } newCache := contracts.AzionJsonDataCacheSettings{ Id: updated.GetId(), @@ -178,7 +181,7 @@ func (man *ManifestInterpreter) CreateResources(conf *contracts.AzionApplication } created, err := clientCache.Create(ctx, requestUpdate, conf.Application.ID) if err != nil { - return err + return fmt.Errorf("%w: %s", msg.ErrorCreateCache, err.Error()) } newCache := contracts.AzionJsonDataCacheSettings{ Id: created.GetId(), @@ -196,7 +199,7 @@ func (man *ManifestInterpreter) CreateResources(conf *contracts.AzionApplication } conf.CacheSettings = cacheConf - err = man.WriteAzionJsonContent(conf) + err = man.WriteAzionJsonContent(conf, projectConf) if err != nil { logger.Debug("Error while writing azion.json file", zap.Error(err)) return err @@ -204,21 +207,24 @@ func (man *ManifestInterpreter) CreateResources(conf *contracts.AzionApplication ruleConf := []contracts.AzionJsonDataRules{} for _, rule := range manifest.Rules { - if id := RuleIds[rule.Name]; id > 0 { + if r := RuleIds[rule.Name]; r.Id > 0 { requestUpdate, err := makeRuleRequestUpdate(rule, conf) if err != nil { return err } - requestUpdate.Id = id - requestUpdate.Phase = "request" + requestUpdate.Id = r.Id + requestUpdate.Phase = rule.Phase + requestUpdate.IsActive = &rule.IsActive + requestUpdate.Order = &rule.Order requestUpdate.IdApplication = conf.Application.ID updated, err := client.UpdateRulesEngine(ctx, requestUpdate) if err != nil { - return err + return fmt.Errorf("%w: %s", msg.ErrorUpdateRule, err.Error()) } newRule := contracts.AzionJsonDataRules{ - Id: updated.GetId(), - Name: updated.GetName(), + Id: updated.GetId(), + Name: updated.GetName(), + Phase: updated.GetPhase(), } ruleConf = append(ruleConf, newRule) delete(RuleIds, rule.Name) @@ -232,20 +238,23 @@ func (man *ManifestInterpreter) CreateResources(conf *contracts.AzionApplication } else { requestCreate.Name = conf.Name + thoth.GenerateName() } - created, err := client.CreateRulesEngine(ctx, conf.Application.ID, "request", requestCreate) + requestCreate.IsActive = &rule.IsActive + requestCreate.Order = &rule.Order + created, err := client.CreateRulesEngine(ctx, conf.Application.ID, rule.Phase, requestCreate) if err != nil { - return err + return fmt.Errorf("%w: %s", msg.ErrorCreateRule, err.Error()) } newRule := contracts.AzionJsonDataRules{ - Id: created.GetId(), - Name: created.GetName(), + Id: created.GetId(), + Name: created.GetName(), + Phase: created.GetPhase(), } ruleConf = append(ruleConf, newRule) } } conf.RulesEngine.Rules = ruleConf - err = man.WriteAzionJsonContent(conf) + err = man.WriteAzionJsonContent(conf, projectConf) if err != nil { logger.Debug("Error while writing azion.json file", zap.Error(err)) return err @@ -266,11 +275,17 @@ func deleteResources(ctx context.Context, f *cmdutil.Factory, conf *contracts.Az clientOrigin := apiOrigin.NewClient(f.HttpClient, f.Config.GetString("api_url"), f.Config.GetString("token")) for _, value := range RuleIds { - err := client.DeleteRulesEngine(ctx, conf.Application.ID, "request", value) + //since until [UXE-3599] was carried out we'd only cared about "request" phase, this check guarantees that if Phase is empty + // we are probably dealing with a rule engine from a previous version + phase := "request" + if value.Phase != "" { + phase = value.Phase + } + err := client.DeleteRulesEngine(ctx, conf.Application.ID, phase, value.Id) if err != nil { return err } - logger.FInfo(f.IOStreams.Out, fmt.Sprintf(msgrule.DeleteOutputSuccess+"\n", value)) + logger.FInfo(f.IOStreams.Out, fmt.Sprintf(msgrule.DeleteOutputSuccess+"\n", value.Id)) } for i, value := range OriginKeys { diff --git a/pkg/manifest/manifest_test.go b/pkg/manifest/manifest_test.go index 4247a5c35..16aad3f1f 100644 --- a/pkg/manifest/manifest_test.go +++ b/pkg/manifest/manifest_test.go @@ -53,14 +53,14 @@ func TestDeployCmd(t *testing.T) { interpreter := NewManifestInterpreter() - interpreter.WriteAzionJsonContent = func(conf *contracts.AzionApplicationOptions) error { + interpreter.WriteAzionJsonContent = func(conf *contracts.AzionApplicationOptions, confPath string) error { return nil } pathManifest := "fixtures/manifest.json" manifest, err := interpreter.ReadManifest(pathManifest, f) require.NoError(t, err) - err = interpreter.CreateResources(options, manifest, f) + err = interpreter.CreateResources(options, manifest, f, "azion") require.NoError(t, err) }) diff --git a/utils/errors.go b/utils/errors.go index c12502c6b..1f68dd292 100644 --- a/utils/errors.go +++ b/utils/errors.go @@ -28,7 +28,6 @@ var ( ErrorNotFound404 = errors.New("The given ID or API's endpoint doesn't exist or isn't available. Check that the identifying information is correct") ErrorFetchingTemplates = errors.New("Failed to fetch templates from the Azion's GitHub remote repository. Verify the connectivity to the repository https://github.com/aziontech/azioncli-template and try again") ErrorMovingFiles = errors.New("Failed to initialize your project with the Azion template. Please verify if you have write permissions to this directory") - ErrorUnsupportedType = errors.New("The project type isn’t supported. Modify the project to a valid type nextjs and try the command again. Use the flags -h or --help with a command or subcommand to display more information and try again") ErrorInvalidOption = errors.New("You must inform 'yes' or 'no' as input, or force --yes or --no by using the flags") ErrorCleaningDirectory = errors.New("Failed to clean the directory's contents because the directory is read-only and/or isn't accessible. Change the attributes of the directory to read/write and/or give access to it") ErrorRunningCommand = errors.New("Failed to run the command specified in the template (config.json)") diff --git a/utils/helpers.go b/utils/helpers.go index 55a024940..b31d2ee8f 100644 --- a/utils/helpers.go +++ b/utils/helpers.go @@ -10,6 +10,7 @@ import ( "net/http" "os" "os/exec" + "path" "strconv" "strings" "time" @@ -208,20 +209,19 @@ func ResponseToBool(response string) (bool, error) { return false, ErrorInvalidOption } -func GetAzionJsonContent() (*contracts.AzionApplicationOptions, error) { - path, err := GetWorkingDir() +func GetAzionJsonContent(confPath string) (*contracts.AzionApplicationOptions, error) { + wd, err := GetWorkingDir() if err != nil { return nil, err } - _, err = os.Stat(path + "/azion/azion.json") + _, err = os.Stat(path.Join(wd, confPath, "azion.json")) if err != nil { logger.Debug("Error reading stats of azion.json file", zap.Error(err)) return nil, ErrorOpeningAzionJsonFile } - jsonConf := path + "/azion/azion.json" - file, err := os.ReadFile(jsonConf) + file, err := os.ReadFile(path.Join(wd, confPath, "azion.json")) if err != nil { logger.Debug("Error reading azion.json file", zap.Error(err)) return nil, ErrorOpeningAzionJsonFile @@ -237,39 +237,17 @@ func GetAzionJsonContent() (*contracts.AzionApplicationOptions, error) { return conf, nil } -func GetAzionJsonSimple() (*contracts.AzionApplicationSimple, error) { - path, err := GetWorkingDir() - if err != nil { - return nil, err - } - jsonConf := path + "/azion/azion.json" - file, err := os.ReadFile(jsonConf) - if err != nil { - return nil, ErrorOpeningAzionJsonFile - } - - conf := &contracts.AzionApplicationSimple{} - err = json.Unmarshal(file, &conf) - if err != nil { - return nil, ErrorUnmarshalAzionJsonFile - } - - return conf, nil -} - -func WriteAzionJsonContent(conf *contracts.AzionApplicationOptions) error { - path, err := GetWorkingDir() +func WriteAzionJsonContent(conf *contracts.AzionApplicationOptions, confPath string) error { + wd, err := GetWorkingDir() if err != nil { return err } - jsonConf := path + "/azion/azion.json" - data, err := json.MarshalIndent(conf, "", " ") if err != nil { return ErrorMarshalAzionJsonFile } - err = os.WriteFile(jsonConf, data, 0644) + err = os.WriteFile(path.Join(wd, confPath, "azion.json"), data, 0644) if err != nil { return ErrorWritingAzionJsonFile } diff --git a/utils/helpers_test.go b/utils/helpers_test.go index 80d211474..40c203ac7 100644 --- a/utils/helpers_test.go +++ b/utils/helpers_test.go @@ -65,7 +65,7 @@ func TestCobraCmd(t *testing.T) { azJsonData.Function.File = "myfile.js" azJsonData.Function.ID = 476 - _ = WriteAzionJsonContent(&azJsonData) + _ = WriteAzionJsonContent(&azJsonData, "azion") require.NoError(t, err) }) @@ -77,7 +77,7 @@ func TestCobraCmd(t *testing.T) { _ = os.MkdirAll(filepath.Dir(jsonConf), os.ModePerm) - azJsonData, err := GetAzionJsonContent() + azJsonData, err := GetAzionJsonContent("azion") require.NoError(t, err) require.Contains(t, azJsonData.Name, "Test01")