Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

feature: RunTrigger gRPC endpoint for Waypoint Server #2840

Merged
merged 48 commits into from
Jan 12, 2022
Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
48 commits
Select commit Hold shift + click to select a range
d9c7049
Define RunTrigger grpc method
briancain Dec 10, 2021
4892a1c
Initial implementation of RunTrigger service method
briancain Dec 10, 2021
cf7ca4e
Add service level tests for runtrigger api func
briancain Dec 14, 2021
2772990
Fix linter for copying msg with locks
briancain Dec 14, 2021
d528d90
Add note about exec overrides
briancain Dec 14, 2021
eac6554
Ensure workspace is auto-set if not specified on Upsert
briancain Dec 14, 2021
7b9ec2e
Humanize time in trigger list
briancain Dec 14, 2021
b63777e
Huamize last active time in inspect cmd
briancain Dec 14, 2021
b8fdff9
Only queue multi-job if multi-app trigger run has been requested
briancain Dec 15, 2021
a2d30d4
Improve logging in runtrigger service func
briancain Dec 15, 2021
3300551
Label all run trigger jobs with requested trigger ID
briancain Dec 15, 2021
67b61b8
Include variable overrides when requesting run triggers
briancain Dec 15, 2021
a6444a4
Add a queue job request func to return requests for all apps in project
briancain Dec 16, 2021
43aad09
Only support cli sourced vars in runtrigger
briancain Dec 16, 2021
cdf5920
linter: Copy all relevant template job values into generated job
briancain Dec 16, 2021
5f80348
Allow trigger update to update workspace/project/app target
briancain Dec 16, 2021
910397e
Fixup timestamp usage
briancain Jan 3, 2022
feba47c
Use copystructure to copy job template for project scoped job generation
briancain Jan 3, 2022
8bac0e2
Add tests to ensure JobCreate only creates requested job number
briancain Jan 3, 2022
e604199
Simplify runtrigger by always using queueJobMulti to start triggers
briancain Jan 3, 2022
52d9118
Fixup warn log
briancain Jan 3, 2022
79e93d5
Add a quick note about queueJobMulti
briancain Jan 4, 2022
367cc81
Add CHANGELOG
briancain Jan 4, 2022
5264f5a
cli: remove word 'operation' from displaying operation
briancain Jan 5, 2022
d79b24b
cli: Fix panic where id was provided by flag and not argument
briancain Jan 5, 2022
8d8fbf6
cli: Reduce total columns for listing triggers, introduce full flag f…
briancain Jan 5, 2022
3fef7c0
Include which flag to set for empty operation
briancain Jan 6, 2022
84f9b5a
Remove id flag, only use argument in trigger inspect
briancain Jan 6, 2022
0922086
Update .changelog/2840.txt
briancain Jan 6, 2022
7bf3fb5
Set artifact message for Deployment operations on running triggers
briancain Jan 6, 2022
a14fa8c
Add note about deploy op and pushedartifact
briancain Jan 6, 2022
9af0503
More explicit description for operation options in trigger create/update
briancain Jan 7, 2022
6e01c33
Ensure application refs are properly set
briancain Jan 7, 2022
db323c0
Update internal/cli/trigger_apply.go
briancain Jan 10, 2022
0cb4f95
Website autogen from cli doc string fix
briancain Jan 10, 2022
7baac59
core: Ensure full Deployment proto message is set for queueing Release
briancain Jan 11, 2022
fbead7c
core: Add status report deploy and release operation type triggers
briancain Jan 11, 2022
7014dd4
Server proto auto-gen
briancain Jan 11, 2022
338ca0b
docs: fix typo in code doc
briancain Jan 11, 2022
7d907cb
Add trigger URL docs
briancain Jan 12, 2022
e14a219
Update how to run trigger via grpc and explain job id returns
briancain Jan 12, 2022
8197b6c
Add future HTTP section
briancain Jan 12, 2022
f17bfe8
Fix typo in trigger docs
briancain Jan 12, 2022
22734d9
Ensure Build proto message is set for Artifact Push operation
briancain Jan 12, 2022
5c3fddd
Ensure Deployment Destroy has a Deployment full proto message set
briancain Jan 12, 2022
5d58f8b
Apply suggestions from code review
briancain Jan 12, 2022
8c8c6e0
Docs fix: We -> You
briancain Jan 12, 2022
3d72cd3
core: Improve error message for variable override wrong type
briancain Jan 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changelog/2840.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
```release-note:feature
core: Introduce RunTriggers to Waypoint Server and CLI. Triggers can be configured
ahead of time to execute lifecycle operations on demand through the Waypoint API.
Currently, only the gRPC API is supported, but in the future an HTTP endpoint
will be added to be used within CI.
```
109 changes: 72 additions & 37 deletions internal/cli/trigger_apply.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package cli
import (
"strings"

"github.com/golang/protobuf/ptypes/empty"
"github.com/posener/complete"

"github.com/hashicorp/waypoint-plugin-sdk/terminal"
Expand All @@ -26,11 +27,11 @@ type TriggerApplyCommand struct {
flagTriggerNoAuth bool

// Operation options
flagArtifactSeq int
flagBuildSeq int
flagDeploySeq int
flagReleaseSeq int
flagDisablePush bool
flagBuildSeq int
flagDeploySeq int
flagDisablePush bool
flagStatusReportDeploy bool
flagStatusReportRelease bool

// Release options
flagReleasePrune bool
Expand All @@ -39,7 +40,7 @@ type TriggerApplyCommand struct {

// Current supported trigger operation names.
var triggerOpValues = []string{"build", "push", "deploy", "destroy-workspace",
"destroy-deployment", "release", "up", "init"}
"destroy-deployment", "release", "up", "init", "status-report-deploy", "status-report-release"}

func (c *TriggerApplyCommand) Run(args []string) int {
// Initialize. If we fail, we just exit since Init handles the UI.
Expand Down Expand Up @@ -94,17 +95,22 @@ func (c *TriggerApplyCommand) Run(args []string) int {
}

// Trigger target
if diffTrigger.Workspace != nil {
if diffTrigger.Workspace != nil && c.flagWorkspace == "" {
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
if diffTrigger.Workspace != nil && c.flagWorkspace == "" {
if c.flagWorkspace == "" {
if diffTrigger.Workspace != nil {
c.flagWorkspace = diffTrigger.Workspace.Workspace
} else {
c.flagWorkspace = "default"
}

To make that flow cleaner, and optionally refactor the triggers below to have the flag check as the first conditional for uniformity?

Copy link
Member Author

Choose a reason for hiding this comment

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

We'll still have to do this workspace flag check later, because inside this if-statement we're only setting these values if we're updating a trigger URL and one already exists, i.e. the check on line 83. So in the creation case, we'll still need the check below if workspace was not set.

c.flagWorkspace = diffTrigger.Workspace.Workspace
}
if diffTrigger.Project != nil {
if diffTrigger.Project != nil && c.flagProject == "" {
c.flagProject = diffTrigger.Project.Project
}
if diffTrigger.Application != nil {
if diffTrigger.Application != nil && c.flagApp == "" {
c.flagApp = diffTrigger.Application.Application
}
}

// NOTE(briancain): there's probably a better way to set default workspace now
if c.flagWorkspace == "" {
c.flagWorkspace = "default"
}

createTrigger := &pb.Trigger{
Name: c.flagTriggerName,
Description: c.flagTriggerDescription,
Expand Down Expand Up @@ -152,27 +158,33 @@ func (c *TriggerApplyCommand) Run(args []string) int {
},
}
case c.flagTriggerOperation == "deploy":
// TODO/FUTURE NOTE: If no sequence number is specified (i.e. seq 0), the backend should default to using the "latest" artifact instead
var artifact *pb.PushedArtifact
if c.flagBuildSeq != 0 {
artifact = &pb.PushedArtifact{
Application: &pb.Ref_Application{
Application: c.flagApp,
Project: c.flagProject,
},
Sequence: uint64(c.flagBuildSeq),
Workspace: &pb.Ref_Workspace{
Workspace: c.flagWorkspace,
},
}
}

// NOTE: nil artifact means "latest", the server will look up the latest in the DB and set it there
createTrigger.Operation = &pb.Trigger_Deploy{
Deploy: &pb.Job_DeployOp{
Artifact: &pb.PushedArtifact{
Sequence: uint64(c.flagBuildSeq),
Workspace: &pb.Ref_Workspace{
Workspace: c.flagWorkspace,
},
Application: &pb.Ref_Application{
Application: c.flagApp,
Project: c.flagProject,
},
},
Artifact: artifact,
},
}
case c.flagTriggerOperation == "destroy-workspace":
// NOTE(briancain): I don't think this operation actually works, takes no arguments...
createTrigger.Operation = &pb.Trigger_Destroy{
Destroy: &pb.Job_DestroyOp{
Target: &pb.Job_DestroyOp_Workspace{},
Target: &pb.Job_DestroyOp_Workspace{
Workspace: &empty.Empty{},
},
},
}
case c.flagTriggerOperation == "destroy-deployment":
Expand Down Expand Up @@ -235,9 +247,44 @@ func (c *TriggerApplyCommand) Run(args []string) int {
createTrigger.Operation = &pb.Trigger_Init{
Init: &pb.Job_InitOp{},
}
case c.flagTriggerOperation == "status-report-deploy":
createTrigger.Operation = &pb.Trigger_StatusReport{
StatusReport: &pb.Job_StatusReportOp{
Target: &pb.Job_StatusReportOp_Deployment{
Deployment: &pb.Deployment{
Sequence: uint64(c.flagDeploySeq),
Workspace: &pb.Ref_Workspace{
Workspace: c.flagWorkspace,
},
Application: &pb.Ref_Application{
Application: c.flagApp,
Project: c.flagProject,
},
},
},
},
}
case c.flagTriggerOperation == "status-report-release":
createTrigger.Operation = &pb.Trigger_StatusReport{
StatusReport: &pb.Job_StatusReportOp{
Target: &pb.Job_StatusReportOp_Release{
Release: &pb.Release{
Sequence: uint64(c.flagDeploySeq),
Workspace: &pb.Ref_Workspace{
Workspace: c.flagWorkspace,
},
Application: &pb.Ref_Application{
Application: c.flagApp,
Project: c.flagProject,
},
},
},
},
}
case c.flagTriggerOperation == "":
if diffTrigger == nil {
c.ui.Output("Empty operation type requested. Must be one of the following values:\n%s\n\n%s",
c.ui.Output("Empty operation type requested. Operation must be set with "+
"'-op' and be one of the following values:\n%s\n\n%s",
strings.Join(triggerOpValues[:], ", "), c.Help(), terminal.WithErrorStyle())
return 1
} else {
Expand Down Expand Up @@ -267,7 +314,7 @@ func (c *TriggerApplyCommand) Run(args []string) int {
c.ui.Output("Trigger %q (%s) has been %s", resp.Trigger.Name, resp.Trigger.Id,
action, terminal.WithSuccessStyle())

c.ui.Output(" Trigger ID: %s", resp.Trigger.Id, terminal.WithSuccessStyle())
c.ui.Output("Trigger ID: %s", resp.Trigger.Id, terminal.WithSuccessStyle())
// TODO(briancain): update output to show trigger URL with wp server attached once http service is implemented
//c.ui.Output("Trigger URL: %s", resp.TriggerURL, terminal.WithSuccessStyle())

Expand Down Expand Up @@ -321,12 +368,6 @@ func (c *TriggerApplyCommand) Flags() *flag.Sets {

// Operation specific flags
fo := set.NewSet("Operation Options")
fo.IntVar(&flag.IntVar{
Name: "artifact-id",
Target: &c.flagArtifactSeq,
Usage: "The sequence number (short id) for the artifact to use in an operation.",
})

fo.BoolVar(&flag.BoolVar{
Name: "disable-push",
Target: &c.flagDisablePush,
Expand All @@ -337,19 +378,13 @@ func (c *TriggerApplyCommand) Flags() *flag.Sets {
fo.IntVar(&flag.IntVar{
Name: "build-id",
Target: &c.flagBuildSeq,
Usage: "The sequence number (short id) for the build to use in an operation.",
Usage: "The sequence number (short id) for the build to use for a deployment operation.",
})

fo.IntVar(&flag.IntVar{
Name: "deployment-id",
Target: &c.flagDeploySeq,
Usage: "The sequence number (short id) for the deployment to use in an operation.",
})

fo.IntVar(&flag.IntVar{
Name: "release-id",
Target: &c.flagReleaseSeq,
Usage: "The sequence number (short id) for the release to use in an operation.",
Usage: "The sequence number (short id) for the deployment to use for a deployment operation.",
})

// Release operation specific flags
Expand Down
44 changes: 26 additions & 18 deletions internal/cli/trigger_inspect.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"strings"

"github.com/dustin/go-humanize"
"github.com/golang/protobuf/jsonpb"
"github.com/posener/complete"
"google.golang.org/grpc/codes"
Expand Down Expand Up @@ -33,11 +34,12 @@ func (c *TriggerInspectCommand) Run(args []string) int {
return 1
}

if len(c.args) == 0 && c.flagTriggerId == "" {
if len(c.args) == 0 {
c.ui.Output("Trigger ID required.\n\n%s", c.Help(), terminal.WithErrorStyle())
return 1
} else {
c.flagTriggerId = c.args[0]
}
c.flagTriggerId = c.args[0]

ctx := c.Ctx

Expand All @@ -48,7 +50,7 @@ func (c *TriggerInspectCommand) Run(args []string) int {
})
if err != nil {
if status.Code(err) == codes.NotFound {
c.ui.Output("Trigger configuration not found", clierrors.Humanize(err),
c.ui.Output("Trigger configuration not found: %s", clierrors.Humanize(err),
terminal.WithErrorStyle())
return 1
}
Expand Down Expand Up @@ -86,26 +88,33 @@ func (c *TriggerInspectCommand) Run(args []string) int {
var opStr string
switch triggerOpType := trigger.Operation.(type) {
case *pb.Trigger_Build:
opStr = "build operation"
opStr = "build"
case *pb.Trigger_Push:
opStr = "push operation"
opStr = "push"
case *pb.Trigger_Deploy:
opStr = "deploy operation"
opStr = "deploy"
case *pb.Trigger_Destroy:
switch triggerOpType.Destroy.Target.(type) {
case *pb.Job_DestroyOp_Workspace:
opStr = "destroy workspace operation"
opStr = "destroy workspace"
case *pb.Job_DestroyOp_Deployment:
opStr = "destroy deployment operation"
opStr = "destroy deployment"
default:
opStr = "unknown destroy operation target"
}
case *pb.Trigger_Release:
opStr = "release operation"
opStr = "release"
case *pb.Trigger_Up:
opStr = "up operation"
opStr = "up"
case *pb.Trigger_Init:
opStr = "init operation"
opStr = "init"
case *pb.Trigger_StatusReport:
switch triggerOpType.StatusReport.Target.(type) {
case *pb.Job_StatusReportOp_Deployment:
opStr = "status report deployment"
case *pb.Job_StatusReportOp_Release:
opStr = "status report release"
}
default:
opStr = fmt.Sprintf("unknown operation: %T", triggerOpType)
}
Expand All @@ -115,6 +124,11 @@ func (c *TriggerInspectCommand) Run(args []string) int {
tags = strings.Join(trigger.Tags[:], ", ")
}

lastActiveTime := "n/a"
if trigger.ActiveTime.IsValid() {
lastActiveTime = humanize.Time(trigger.ActiveTime.AsTime())
}

c.ui.Output("Trigger URL config:", terminal.WithHeaderStyle())
c.ui.NamedValues([]terminal.NamedValue{
{
Expand All @@ -124,7 +138,7 @@ func (c *TriggerInspectCommand) Run(args []string) int {
Name: "ID", Value: trigger.Id,
},
{
Name: "Last Time Active", Value: trigger.ActiveTime.String(),
Name: "Last Time Active", Value: lastActiveTime,
},
{
Name: "Authenticated", Value: trigger.Authenticated,
Expand Down Expand Up @@ -156,12 +170,6 @@ func (c *TriggerInspectCommand) Flags() *flag.Sets {
return c.flagSet(flagSetOperation, func(set *flag.Sets) {
f := set.NewSet("Command Options")

f.StringVar(&flag.StringVar{
Name: "id",
Target: &c.flagTriggerId,
Usage: "The id of the trigger URL to inspect.",
})

f.BoolVar(&flag.BoolVar{
Name: "json",
Target: &c.flagJson,
Expand Down
Loading