Skip to content

Commit

Permalink
Merge pull request #164 from amazeeio/activestandby
Browse files Browse the repository at this point in the history
Add support for running active/standby switch
shreddedbacon authored Feb 21, 2021
2 parents cbe39aa + eb0667f commit c3ee9e4
Showing 19 changed files with 403 additions and 37 deletions.
3 changes: 3 additions & 0 deletions cmd/get.go
Original file line number Diff line number Diff line change
@@ -163,6 +163,9 @@ func init() {
getCmd.AddCommand(getProjectCmd)
getCmd.AddCommand(getProjectKeyCmd)
getCmd.AddCommand(getUserKeysCmd)
getCmd.AddCommand(getTaskByID)
getTaskByID.Flags().IntP("id", "I", 0, "ID of the task")
getTaskByID.Flags().BoolP("logs", "L", false, "Show the task logs if available")
getProjectKeyCmd.Flags().BoolVarP(&revealValue, "reveal", "", false, "Reveal the variable values")
getDeploymentCmd.Flags().StringVarP(&remoteID, "remoteid", "R", "", "The remote ID of the deployment")
}
2 changes: 2 additions & 0 deletions cmd/project.go
Original file line number Diff line number Diff line change
@@ -132,6 +132,7 @@ func init() {
updateProjectCmd.Flags().StringVarP(&projectPatch.Name, "name", "N", "", "Change the name of the project by specifying a new name (careful!)")
updateProjectCmd.Flags().StringVarP(&projectPatch.Pullrequests, "pullrequests", "m", "", "Which Pull Requests should be deployed")
updateProjectCmd.Flags().StringVarP(&projectPatch.ProductionEnvironment, "productionEnvironment", "E", "", "Which environment(the name) should be marked as the production environment")
updateProjectCmd.Flags().StringVar(&projectPatch.StandbyProductionEnvironment, "standbyProductionEnvironment", "", "Which environment(the name) should be marked as the standby production environment")
updateProjectCmd.Flags().StringVarP(&projectPatch.OpenshiftProjectPattern, "openshiftProjectPattern", "o", "", "Pattern of OpenShift Project/Namespace that should be generated")

updateProjectCmd.Flags().IntVarP(&projectAutoIdle, "autoIdle", "a", 0, "Auto idle setting of the project")
@@ -152,6 +153,7 @@ func init() {
addProjectCmd.Flags().StringVarP(&projectPatch.Branches, "branches", "b", "", "Which branches should be deployed")
addProjectCmd.Flags().StringVarP(&projectPatch.Pullrequests, "pullrequests", "m", "", "Which Pull Requests should be deployed")
addProjectCmd.Flags().StringVarP(&projectPatch.ProductionEnvironment, "productionEnvironment", "E", "", "Which environment(the name) should be marked as the production environment")
addProjectCmd.Flags().StringVar(&projectPatch.StandbyProductionEnvironment, "standbyProductionEnvironment", "", "Which environment(the name) should be marked as the standby production environment")
addProjectCmd.Flags().StringVarP(&projectPatch.OpenshiftProjectPattern, "openshiftProjectPattern", "o", "", "Pattern of OpenShift Project/Namespace that should be generated")

addProjectCmd.Flags().IntVarP(&projectAutoIdle, "autoIdle", "a", 0, "Auto idle setting of the project")
1 change: 1 addition & 0 deletions cmd/run.go
Original file line number Diff line number Diff line change
@@ -19,4 +19,5 @@ func init() {
runCmd.AddCommand(runDrushArchiveDump)
runCmd.AddCommand(runDrushCacheClear)
runCmd.AddCommand(runDrushSQLDump)
runCmd.AddCommand(runActiveStandbySwitch)
}
107 changes: 107 additions & 0 deletions cmd/tasks.go
Original file line number Diff line number Diff line change
@@ -2,17 +2,124 @@ package cmd

import (
"bufio"
"context"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"os"

"github.com/amazeeio/lagoon-cli/internal/lagoon"
"github.com/amazeeio/lagoon-cli/internal/lagoon/client"
"github.com/amazeeio/lagoon-cli/pkg/api"
"github.com/amazeeio/lagoon-cli/pkg/output"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var getTaskByID = &cobra.Command{
Use: "task-by-id",
Short: "Get information about a task by its ID",
Long: `Get information about a task by its ID`,
Aliases: []string{"t", "tbi"},
PreRunE: func(_ *cobra.Command, _ []string) error {
return validateTokenE(viper.GetString("current"))
},
RunE: func(cmd *cobra.Command, args []string) error {
debug, err := cmd.Flags().GetBool("debug")
if err != nil {
return err
}

taskID, err := cmd.Flags().GetInt("id")
if err != nil {
return err
}
showLogs, err := cmd.Flags().GetBool("logs")
if err != nil {
return err
}
if taskID == 0 {
return fmt.Errorf("Missing arguments: ID is not defined")
}
current := viper.GetString("current")
lc := client.New(
viper.GetString("lagoons."+current+".graphql"),
viper.GetString("lagoons."+current+".token"),
viper.GetString("lagoons."+current+".version"),
lagoonCLIVersion,
debug)
result, err := lagoon.TaskByID(context.TODO(), taskID, lc)
if err != nil {
return err
}
dataMain := output.Table{
Header: []string{
"ID",
"Name",
"Status",
"Created",
"Started",
"Completed",
},
Data: []output.Data{
{
fmt.Sprintf("%d", result.ID),
returnNonEmptyString(result.Name),
returnNonEmptyString(result.Status),
returnNonEmptyString(result.Created),
returnNonEmptyString(result.Started),
returnNonEmptyString(result.Completed),
},
},
}
if showLogs {
dataMain.Header = append(dataMain.Header, "Logs")
dataMain.Data[0] = append(dataMain.Data[0], returnNonEmptyString(result.Logs))
}
output.RenderOutput(dataMain, outputOptions)
return nil
},
}

var runActiveStandbySwitch = &cobra.Command{
Use: "activestandby",
Short: "Run the active/standby switch for a project",
Long: `Run the active/standby switch for a project
You should only run this once and then check the status of the task that gets created.
If the task fails or fails to update, contact your Lagoon administrator for assistance.`,
Aliases: []string{"as", "standby"},
PreRunE: func(_ *cobra.Command, _ []string) error {
return validateTokenE(viper.GetString("current"))
},
RunE: func(cmd *cobra.Command, args []string) error {
debug, err := cmd.Flags().GetBool("debug")
if err != nil {
return err
}
if cmdProjectName == "" {
return fmt.Errorf("Missing arguments: Project name is not defined")
}
if yesNo(fmt.Sprintf("You are attempting to run the active/standby switch for project '%s', are you sure?", cmdProjectName)) {
current := viper.GetString("current")
lc := client.New(
viper.GetString("lagoons."+current+".graphql"),
viper.GetString("lagoons."+current+".token"),
viper.GetString("lagoons."+current+".version"),
lagoonCLIVersion,
debug)
result, err := lagoon.ActiveStandbySwitch(context.TODO(), cmdProjectName, lc)
if err != nil {
return err
}
fmt.Println(fmt.Sprintf(`Created a new task with ID %d
You can use the following command to query the task status:
lagoon -l %s get task-by-id --id %d --logs`, result.ID, current, result.ID))
}
return nil
},
}

var runDrushArchiveDump = &cobra.Command{
Use: "drush-archivedump",
Aliases: []string{"dard"},
37 changes: 19 additions & 18 deletions docs/commands/lagoon_add_project.md
Original file line number Diff line number Diff line change
@@ -13,24 +13,25 @@ lagoon add project [flags]
### Options

```
-D, --activeSystemsDeploy string Which internal Lagoon System is responsible for deploying
-M, --activeSystemsMisc string Which internal Lagoon System is responsible for miscellaneous tasks
-P, --activeSystemsPromote string Which internal Lagoon System is responsible for promoting
-R, --activeSystemsRemove string Which internal Lagoon System is responsible for removing
-T, --activeSystemsTask string Which internal Lagoon System is responsible for tasks
-a, --autoIdle int Auto idle setting of the project
-b, --branches string Which branches should be deployed
-L, --developmentEnvironmentsLimit int How many environments can be deployed at one time
-g, --gitUrl string GitURL of the project
-h, --help help for project
-j, --json string JSON string to patch
-S, --openshift int Reference to OpenShift Object this Project should be deployed to
-o, --openshiftProjectPattern string Pattern of OpenShift Project/Namespace that should be generated
-I, --privateKey string Private key to use for the project
-E, --productionEnvironment string Which environment(the name) should be marked as the production environment
-m, --pullrequests string Which Pull Requests should be deployed
-C, --storageCalc int Should storage for this environment be calculated
-s, --subfolder string Set if the .lagoon.yml should be found in a subfolder useful if you have multiple Lagoon projects per Git Repository
-D, --activeSystemsDeploy string Which internal Lagoon System is responsible for deploying
-M, --activeSystemsMisc string Which internal Lagoon System is responsible for miscellaneous tasks
-P, --activeSystemsPromote string Which internal Lagoon System is responsible for promoting
-R, --activeSystemsRemove string Which internal Lagoon System is responsible for removing
-T, --activeSystemsTask string Which internal Lagoon System is responsible for tasks
-a, --autoIdle int Auto idle setting of the project
-b, --branches string Which branches should be deployed
-L, --developmentEnvironmentsLimit int How many environments can be deployed at one time
-g, --gitUrl string GitURL of the project
-h, --help help for project
-j, --json string JSON string to patch
-S, --openshift int Reference to OpenShift Object this Project should be deployed to
-o, --openshiftProjectPattern string Pattern of OpenShift Project/Namespace that should be generated
-I, --privateKey string Private key to use for the project
-E, --productionEnvironment string Which environment(the name) should be marked as the production environment
-m, --pullrequests string Which Pull Requests should be deployed
--standbyProductionEnvironment string Which environment(the name) should be marked as the standby production environment
-C, --storageCalc int Should storage for this environment be calculated
-s, --subfolder string Set if the .lagoon.yml should be found in a subfolder useful if you have multiple Lagoon projects per Git Repository
```

### Options inherited from parent commands
1 change: 1 addition & 0 deletions docs/commands/lagoon_get.md
Original file line number Diff line number Diff line change
@@ -37,5 +37,6 @@ Get info on a resource
* [lagoon get environment](lagoon_get_environment.md) - Get details about an environment
* [lagoon get project](lagoon_get_project.md) - Get details about a project
* [lagoon get project-key](lagoon_get_project-key.md) - Get a projects public key
* [lagoon get task-by-id](lagoon_get_task-by-id.md) - Get information about a task by its ID
* [lagoon get user-sshkeys](lagoon_get_user-sshkeys.md) - Get a users SSH keys

41 changes: 41 additions & 0 deletions docs/commands/lagoon_get_task-by-id.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## lagoon get task-by-id

Get information about a task by its ID

### Synopsis

Get information about a task by its ID

```
lagoon get task-by-id [flags]
```

### Options

```
-h, --help help for task-by-id
-I, --id int ID of the task
-L, --logs Show the task logs if available
```

### Options inherited from parent commands

```
--config-file string Path to the config file to use (must be *.yml or *.yaml)
--debug Enable debugging output (if supported)
-e, --environment string Specify an environment to use
--force Force yes on prompts (if supported)
-l, --lagoon string The Lagoon instance to interact with
--no-header No header on table (if supported)
--output-csv Output as CSV (if supported)
--output-json Output as JSON (if supported)
--pretty Make JSON pretty (if supported)
-p, --project string Specify a project to use
--skip-update-check Skip checking for updates
-i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication
```

### SEE ALSO

* [lagoon get](lagoon_get.md) - Get info on a resource

1 change: 1 addition & 0 deletions docs/commands/lagoon_run.md
Original file line number Diff line number Diff line change
@@ -32,6 +32,7 @@ Run a task against an environment
### SEE ALSO

* [lagoon](lagoon.md) - Command line integration for Lagoon
* [lagoon run activestandby](lagoon_run_activestandby.md) - Run the active/standby switch for a project
* [lagoon run custom](lagoon_run_custom.md) - Run a custom command on an environment
* [lagoon run drush-archivedump](lagoon_run_drush-archivedump.md) - Run a drush archive dump on an environment
* [lagoon run drush-cacheclear](lagoon_run_drush-cacheclear.md) - Run a drush cache clear on an environment
41 changes: 41 additions & 0 deletions docs/commands/lagoon_run_activestandby.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## lagoon run activestandby

Run the active/standby switch for a project

### Synopsis

Run the active/standby switch for a project
You should only run this once and then check the status of the task that gets created.
If the task fails or fails to update, contact your Lagoon administrator for assistance.

```
lagoon run activestandby [flags]
```

### Options

```
-h, --help help for activestandby
```

### Options inherited from parent commands

```
--config-file string Path to the config file to use (must be *.yml or *.yaml)
--debug Enable debugging output (if supported)
-e, --environment string Specify an environment to use
--force Force yes on prompts (if supported)
-l, --lagoon string The Lagoon instance to interact with
--no-header No header on table (if supported)
--output-csv Output as CSV (if supported)
--output-json Output as JSON (if supported)
--pretty Make JSON pretty (if supported)
-p, --project string Specify a project to use
--skip-update-check Skip checking for updates
-i, --ssh-key string Specify path to a specific SSH key to use for lagoon authentication
```

### SEE ALSO

* [lagoon run](lagoon_run.md) - Run a task against an environment

39 changes: 20 additions & 19 deletions docs/commands/lagoon_update_project.md
Original file line number Diff line number Diff line change
@@ -13,25 +13,26 @@ lagoon update project [flags]
### Options

```
-D, --activeSystemsDeploy string Which internal Lagoon System is responsible for deploying
-M, --activeSystemsMisc string Which internal Lagoon System is responsible for miscellaneous tasks
-P, --activeSystemsPromote string Which internal Lagoon System is responsible for promoting
-R, --activeSystemsRemove string Which internal Lagoon System is responsible for removing
-T, --activeSystemsTask string Which internal Lagoon System is responsible for tasks
-a, --autoIdle int Auto idle setting of the project
-b, --branches string Which branches should be deployed
-L, --developmentEnvironmentsLimit int How many environments can be deployed at one time
-g, --gitUrl string GitURL of the project
-h, --help help for project
-j, --json string JSON string to patch
-N, --name string Change the name of the project by specifying a new name (careful!)
-S, --openshift int Reference to OpenShift Object this Project should be deployed to
-o, --openshiftProjectPattern string Pattern of OpenShift Project/Namespace that should be generated
-I, --privateKey string Private key to use for the project
-E, --productionEnvironment string Which environment(the name) should be marked as the production environment
-m, --pullrequests string Which Pull Requests should be deployed
-C, --storageCalc int Should storage for this environment be calculated
-s, --subfolder string Set if the .lagoon.yml should be found in a subfolder useful if you have multiple Lagoon projects per Git Repository
-D, --activeSystemsDeploy string Which internal Lagoon System is responsible for deploying
-M, --activeSystemsMisc string Which internal Lagoon System is responsible for miscellaneous tasks
-P, --activeSystemsPromote string Which internal Lagoon System is responsible for promoting
-R, --activeSystemsRemove string Which internal Lagoon System is responsible for removing
-T, --activeSystemsTask string Which internal Lagoon System is responsible for tasks
-a, --autoIdle int Auto idle setting of the project
-b, --branches string Which branches should be deployed
-L, --developmentEnvironmentsLimit int How many environments can be deployed at one time
-g, --gitUrl string GitURL of the project
-h, --help help for project
-j, --json string JSON string to patch
-N, --name string Change the name of the project by specifying a new name (careful!)
-S, --openshift int Reference to OpenShift Object this Project should be deployed to
-o, --openshiftProjectPattern string Pattern of OpenShift Project/Namespace that should be generated
-I, --privateKey string Private key to use for the project
-E, --productionEnvironment string Which environment(the name) should be marked as the production environment
-m, --pullrequests string Which Pull Requests should be deployed
--standbyProductionEnvironment string Which environment(the name) should be marked as the standby production environment
-C, --storageCalc int Should storage for this environment be calculated
-s, --subfolder string Set if the .lagoon.yml should be found in a subfolder useful if you have multiple Lagoon projects per Git Repository
```

### Options inherited from parent commands
15 changes: 15 additions & 0 deletions internal/lagoon/client/_lgraphql/switchActiveStandby.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{{ if apiVerGreaterThanOrEqual . "1.9.0" }}
mutation (
$project: String!
) {
switchActiveStandby(
input: {
project:{
name: $project
}
}
) {
id
}
}
{{ end }}
18 changes: 18 additions & 0 deletions internal/lagoon/client/_lgraphql/taskByID.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{{ if apiVerGreaterThanOrEqual . "1.9.0" }}
query (
$id: Int!
){
taskById(id: $id){
id
name
command
status
started
completed
created
logs
remoteId
service
}
}
{{ end }}
46 changes: 46 additions & 0 deletions internal/lagoon/client/lgraphql/lgraphql.go
18 changes: 18 additions & 0 deletions internal/lagoon/client/mutation.go
Original file line number Diff line number Diff line change
@@ -272,3 +272,21 @@ func (c *Client) DeployEnvironmentBranch(ctx context.Context,
}
return c.client.Run(ctx, req, &out)
}

// RunActiveStandbySwitch deploys a branch.
func (c *Client) RunActiveStandbySwitch(ctx context.Context,
project string, out *schema.Task) error {
req, err := c.newVersionedRequest("_lgraphql/switchActiveStandby.graphql", map[string]interface{}{
"project": project,
})
if err != nil {
return err
}

// return c.client.Run(ctx, req, &out)
return c.client.Run(ctx, req, &struct {
Response *schema.Task `json:"switchActiveStandby"`
}{
Response: out,
})
}
20 changes: 20 additions & 0 deletions internal/lagoon/client/query.go
Original file line number Diff line number Diff line change
@@ -96,3 +96,23 @@ func (c *Client) LagoonSchema(
Response: lagoonSchema,
})
}

// GetTaskByID queries the Lagoon API for a task by its ID, and
// unmarshals the response.
func (c *Client) GetTaskByID(
ctx context.Context, id int, task *schema.Task) error {

req, err := c.newVersionedRequest("_lgraphql/taskByID.graphql",
map[string]interface{}{
"id": id,
})
if err != nil {
return err
}

return c.client.Run(ctx, req, &struct {
Response *schema.Task `json:"taskById"`
}{
Response: task,
})
}
6 changes: 6 additions & 0 deletions internal/lagoon/lagoonversion.go
Original file line number Diff line number Diff line change
@@ -76,6 +76,12 @@ func determineLagoonVersion(lagoonVersion string, lagoonSchema schema.LagoonSche
return lagoonVersion, err
}
}
if field.Name == "taskById" {
lagoonVersion, err = greaterThanOrEqualVersion(lagoonVersion, "v1.9.0")
if err != nil {
return lagoonVersion, err
}
}
}
}
if schemaType.Name == "NotificationMicrosoftTeams" {
26 changes: 26 additions & 0 deletions internal/lagoon/tasks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Package lagoon implements high-level functions for interacting with the
// Lagoon API.
package lagoon

import (
"context"

"github.com/amazeeio/lagoon-cli/internal/schema"
)

// Tasks interface contains methods for running tasks in projects and environments in lagoon.
type Tasks interface {
RunActiveStandbySwitch(ctx context.Context, project string, result *schema.Task) error
GetTaskByID(ctx context.Context, id int, result *schema.Task) error
}

// ActiveStandbySwitch runs the activestandby switch.
func ActiveStandbySwitch(ctx context.Context, project string, t Tasks) (*schema.Task, error) {
result := schema.Task{}
return &result, t.RunActiveStandbySwitch(ctx, project, &result)
}

func TaskByID(ctx context.Context, id int, t Tasks) (*schema.Task, error) {
result := schema.Task{}
return &result, t.GetTaskByID(ctx, id, &result)
}
16 changes: 16 additions & 0 deletions internal/schema/tasks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package schema

// Task is based on the Lagoon API type.
type Task struct {
ID uint `json:"id,omitempty"`
Name string `json:"name,omitempty"`
Status string `json:"status,omitempty"`
Created string `json:"created,omitempty"`
Started string `json:"started,omitempty"`
Completed string `json:"completed,omitempty"`
Service string `json:"service,omitempty"`
Command string `json:"command,omitempty"`
RemoteID string `json:"remoteId,omitempty"`
Logs string `json:"logs,omitempty"`
Environment Environment `json:"environment,omitempty"`
}
2 changes: 2 additions & 0 deletions pkg/api/types.go
Original file line number Diff line number Diff line change
@@ -237,6 +237,7 @@ type Project struct {
Branches string `json:"branches,omitempty"`
Pullrequests string `json:"pullrequests,omitempty"`
ProductionEnvironment string `json:"productionEnvironment,omitempty"`
StandbyProductionEnvironment string `json:"standbyProductionEnvironment,omitempty"`
AutoIdle *int `json:"autoIdle,omitempty"`
StorageCalc *int `json:"storageCalc,omitempty"`
OpenshiftProjectPattern string `json:"openshiftProjectPattern,omitempty"`
@@ -264,6 +265,7 @@ type ProjectPatch struct {
Branches string `json:"branches,omitempty"`
Pullrequests string `json:"pullrequests,omitempty"`
ProductionEnvironment string `json:"productionEnvironment,omitempty"`
StandbyProductionEnvironment string `json:"standbyProductionEnvironment,omitempty"`
AutoIdle *int `json:"autoIdle,omitempty"`
StorageCalc *int `json:"storageCalc,omitempty"`
OpenshiftProjectPattern string `json:"openshiftProjectPattern,omitempty"`

0 comments on commit c3ee9e4

Please sign in to comment.