Skip to content

Commit

Permalink
Merge pull request #941 from aziontech/dev
Browse files Browse the repository at this point in the history
Deploy to Production - 2024/09/02
  • Loading branch information
PatrickMenoti authored Sep 2, 2024
2 parents 3a86f0b + e350d21 commit 62eabfe
Show file tree
Hide file tree
Showing 25 changed files with 1,780 additions and 21 deletions.
16 changes: 9 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
[![CLI Reference](https://img.shields.io/badge/cli-reference-green.svg)](https://github.com/aziontech/azion-cli/wiki/azion)
[![Go Report Card](https://goreportcard.com/badge/github.com/aziontech/azion-cli)](https://goreportcard.com/report/github.com/aziontech/azion-cli)

Azion CLI: efficient creation and management of applications on Azion Edge Platform.
## Efficient creation and management of applications on Azion Edge Platform.

**Azion CLI** is a user-friendly way to work with the Azion Edge Platform, allowing you to create and manage applications through simple commands. It makes possible the initialization, build, and deployment of applications, from simple static pages to different frameworks, such as:
**Azion CLI** is a user-friendly way to work with the Azion Edge Platform, allowing you to create and manage applications through simple commands.

It makes possible the initialization, build, and deployment of applications, from simple static pages to different frameworks, such as:

- Next.js
- Vue
Expand Down Expand Up @@ -48,13 +50,14 @@ 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
## Using 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 && \
wget https://github.com/aziontech/azion/releases/download/1.36.1/azion_1.36.1_linux_arm64.apk && \
apk add --allow-untrusted azion_1.36.1_linux_arm64.apk && \
azion version; \
exec sh'
```
Expand All @@ -71,7 +74,6 @@ $ make cross-build

---


## How to Use

### Authentication
Expand Down
18 changes: 18 additions & 0 deletions messages/deploy-remote/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package deployremote

import "errors"

var (
ErrorOpeningAzionFile = errors.New("Failed to open the azion.json file. The file doesn't exist, is corrupted, or has an invalid JSON format. Verify if the file format is JSON or fix its content according to the JSON format specification at https://www.json.org/json-en.html")
ErrorCodeFlag = errors.New("Failed to read the code file. Verify if the file name and its path are correct and the file content has a valid code format")
ErrorArgsFlag = errors.New("Failed to read the args file. Verify if the file name and its path are correct and the file's content has a valid JSON format")
ErrorParseArgs = errors.New("Failed to parse JSON args. Verify if the file's content has a valid JSON format")
ErrorCreateFunction = errors.New("Failed to create Edge Function: %s. Check your settings and try again. If the error persists, contact Azion support")
ErrorUpdateFunction = errors.New("Failed to update the Edge Function: %s. Check your settings and try again. If the error persists, contact Azion support")
ErrorCreateApplication = errors.New("Failed to create the Edge Application: %s. Check your settings and try again. If the error persists, contact Azion support")
ErrorUpdateApplication = errors.New("Failed to update the Edge Application: %s. Check your settings and try again. If the error persists, contact Azion support")
ErrorCreateInstance = errors.New("Failed to create the Edge Function Instance: %s. Check your settings and try again. If the error persists, contact Azion support")
ErrorCreateDomain = errors.New("Failed to create the Domain: %s. Check your settings and try again. If the error persists, contact Azion support")
ErrorUpdateDomain = errors.New("Failed to update the Domain: %s. Check your settings and try again. If the error persists, contact Azion support")
ErrorInvalidToken = errors.New("The configured token is invalid. You must create a new token and configure it to use with the CLI.")
)
55 changes: 55 additions & 0 deletions messages/deploy-remote/messages.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package deployremote

var (
// deploy cmd
DeployUsage = "deploy-remote"
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"
DeployOutputCachePurgeUrl = "The file cache has been purged: '%s'\n"
DeployOutputCachePurgeWildCard = "The url cache has been purged: '%s'\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"
EdgeApplicationDeploySync = "Synchronizes the local azion.json file with remote resources"
EnvFlag = "Relative path to where your custom .env file is 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
- Maximum TTL for Edge Application Cache Settings (in seconds): 7200
Do you wish to create a Cache Settings configuration with the above specifications? (y/N)`
SkipUpload = "Your project does not contain a '.edge/storage' folder. Skipping upload of static files"
NameInUseBucket = "Bucket name is already in use. Trying to create bucket with the following name: %s\n"
NameInUseApplication = "Edge Application name is already in use. Trying to create Edge Application with the following name: %s\n"
NameInUseDomain = "Domain name is already in use. Trying to create Domain with the following name: %s\n"
)
81 changes: 81 additions & 0 deletions pkg/cmd/deploy_remote/bucket.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package deploy

import (
"context"
"errors"
"fmt"
"regexp"

"github.com/aziontech/azionapi-go-sdk/storage"

"github.com/AlecAivazis/survey/v2"
msg "github.com/aziontech/azion-cli/messages/deploy"
api "github.com/aziontech/azion-cli/pkg/api/storage"
"github.com/aziontech/azion-cli/pkg/contracts"
"github.com/aziontech/azion-cli/pkg/logger"
"github.com/aziontech/azion-cli/utils"
)

func (cmd *DeployCmd) doBucket(
client *api.Client,
ctx context.Context,
conf *contracts.AzionApplicationOptions,
msgs *[]string) error {
if conf.Bucket != "" || (conf.Preset == "javascript" || conf.Preset == "typescript") {
return nil
}

logger.FInfoFlags(cmd.Io.Out, msg.ProjectNameMessage, cmd.F.Format, cmd.F.Out)
*msgs = append(*msgs, msg.ProjectNameMessage)
nameBucket := replaceInvalidChars(conf.Name)

err := client.CreateBucket(ctx, api.RequestBucket{
BucketCreate: storage.BucketCreate{Name: nameBucket, EdgeAccess: storage.READ_WRITE}})
if err != nil {
// If the name is already in use, try 10 times with different names
for i := 0; i < 10; i++ {
nameB := fmt.Sprintf("%s-%s", nameBucket, utils.Timestamp())
msgf := fmt.Sprintf(msg.NameInUseBucket, nameB)
logger.FInfoFlags(cmd.Io.Out, msgf, cmd.F.Format, cmd.F.Out)
*msgs = append(*msgs, msgf)
err := client.CreateBucket(ctx, api.RequestBucket{
BucketCreate: storage.BucketCreate{Name: nameB, EdgeAccess: storage.READ_WRITE}})
if err != nil {
if errors.Is(err, utils.ErrorNameInUse) && i < 9 {
continue
}
return err
}
conf.Bucket = nameB
break
}
} else {
conf.Bucket = nameBucket
}

msgf := fmt.Sprintf(msg.BucketSuccessful, conf.Bucket)
logger.FInfoFlags(cmd.Io.Out, msgf, cmd.F.Format, cmd.F.Out)
*msgs = append(*msgs, msgf)
return cmd.WriteAzionJsonContent(conf, ProjectConf)
}

func askForInput(msg string, defaultIn string) (string, error) {
var userInput string
prompt := &survey.Input{
Message: msg,
Default: defaultIn,
}

// Prompt the user for input
err := survey.AskOne(prompt, &userInput, survey.WithKeepFilter(true))
if err != nil {
return "", err
}
return userInput, nil
}

// replaceInvalidChars Regular expression to find disallowed characters: "[^a-zA-Z0-9]+" replace invalid characters with -
func replaceInvalidChars(str string) string {
re := regexp.MustCompile(`(?i)(?:azion-|b2-)|[^a-z0-9\-]`)
return re.ReplaceAllString(str, "")
}
61 changes: 61 additions & 0 deletions pkg/cmd/deploy_remote/bucket_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package deploy

import (
"testing"
)

func Test_replaceInvalidChars(t *testing.T) {
tests := []struct {
name string
args string
want string
}{
{
name: "case 01",
args: "asdfadsf-asdfsdf_a",
want: "asdfadsf-asdfsdfa",
},
{
name: "case 02",
args: "asdfad}}.sf-asdfsdf_a",
want: "asdfadsf-asdfsdfa",
},
{
name: "case 03",
args: "asdfad..asdfsdf\\/",
want: "asdfadasdfsdf",
},
{
name: "case 04",
args: "asdfad#!@asdfadsf-asdf/***((ˆ",
want: "asdfadasdfadsf-asdf",
},
{
name: "case 05",
args: "azion-asdfad#!@asdfadsf-asdf/***((ˆ",
want: "asdfadasdfadsf-asdf",
},
{
name: "case 06",
args: "b2-asdfad#!@asdfadsf-asdf/***((ˆ",
want: "asdfadasdfadsf-asdf",
},
{
name: "case 07",
args: "azion-b2-asdfad#!@asdfadsf-asdf/***((ˆ",
want: "asdfadasdfadsf-asdf",
},
{
name: "case 08",
args: "b2-azion-asdfad#!@asdfadsf-asdf/***((ˆ",
want: "asdfadasdfadsf-asdf",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := replaceInvalidChars(tt.args); got != tt.want {
t.Errorf("replaceInvalidChars() = %v, want %v", got, tt.want)
}
})
}
}
35 changes: 35 additions & 0 deletions pkg/cmd/deploy_remote/clients.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package deploy

import (
apiDomain "github.com/aziontech/azion-cli/pkg/api/domain"
apiEdgeApplications "github.com/aziontech/azion-cli/pkg/api/edge_applications"
apiEdgeFunction "github.com/aziontech/azion-cli/pkg/api/edge_function"
apiOrigin "github.com/aziontech/azion-cli/pkg/api/origin"
apiStorage "github.com/aziontech/azion-cli/pkg/api/storage"
"github.com/aziontech/azion-cli/pkg/cmdutil"
)

type Clients struct {
EdgeFunction *apiEdgeFunction.Client
EdgeApplication *apiEdgeApplications.Client
Domain *apiDomain.Client
Origin *apiOrigin.Client
Bucket *apiStorage.Client
Storage *apiStorage.Client
}

func NewClients(f *cmdutil.Factory) *Clients {
httpClient := f.HttpClient
apiURL := f.Config.GetString("api_url")
storageURL := f.Config.GetString("storage_url")
token := f.Config.GetString("token")

return &Clients{
EdgeFunction: apiEdgeFunction.NewClient(httpClient, apiURL, token),
EdgeApplication: apiEdgeApplications.NewClient(httpClient, apiURL, token),
Domain: apiDomain.NewClient(httpClient, apiURL, token),
Origin: apiOrigin.NewClient(httpClient, apiURL, token),
Bucket: apiStorage.NewClient(httpClient, storageURL, token),
Storage: apiStorage.NewClient(httpClient, storageURL, token),
}
}
Loading

0 comments on commit 62eabfe

Please sign in to comment.