Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add UUID for Log Streaming Job ID #167

Merged
merged 13 commits into from
Feb 1, 2022
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ require (
github.com/google/go-github/v29 v29.0.2 // indirect
github.com/google/go-github/v31 v31.0.0
github.com/google/go-querystring v1.0.0 // indirect
github.com/google/uuid v1.1.2-0.20200519141726-cb32006e483f
github.com/google/uuid v1.3.0
github.com/googleapis/gax-go/v2 v2.0.5 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/gorilla/mux v1.8.0
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2-0.20200519141726-cb32006e483f h1:qa1wFcvZzVLbFVPdsdTsWL6k5IP6BEmFmd9SeahRQ5s=
github.com/google/uuid v1.1.2-0.20200519141726-cb32006e483f/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
Expand Down
1 change: 1 addition & 0 deletions server/controllers/events/events_controller_e2e_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -912,6 +912,7 @@ func setupE2E(t *testing.T, repoDir string) (events_controllers.VCSEventsControl
"**/*.tf,**/*.tfvars,**/*.tfvars.json,**/terragrunt.hcl",
statsScope,
logger,
projectCmdOutputHandler,
)

showStepRunner, err := runtime.NewShowStepRunner(terraformClient, defaultTFVersion)
Expand Down
95 changes: 6 additions & 89 deletions server/controllers/jobs_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@ import (
"net/http"
"net/url"

"strconv"

"github.com/gorilla/mux"
"github.com/pkg/errors"
"github.com/runatlantis/atlantis/server/controllers/templates"
"github.com/runatlantis/atlantis/server/controllers/websocket"
"github.com/runatlantis/atlantis/server/core/db"
Expand All @@ -29,102 +26,22 @@ type JobsController struct {
StatsScope tally.Scope
}

type ProjectInfoKeyGenerator struct{}

func (g ProjectInfoKeyGenerator) Generate(r *http.Request) (string, error) {
projectInfo, err := newProjectInfo(r)

if err != nil {
return "", errors.Wrap(err, "creating project info")
}

return projectInfo.String(), nil
}

type pullInfo struct {
org string
repo string
pull int
}

func (p *pullInfo) String() string {
return fmt.Sprintf("%s/%s/%d", p.org, p.repo, p.pull)
}

type projectInfo struct {
projectName string
workspace string
pullInfo
}

func (p *projectInfo) String() string {
return fmt.Sprintf("%s/%s/%d/%s/%s", p.org, p.repo, p.pull, p.projectName, p.workspace)
}

func newPullInfo(r *http.Request) (*pullInfo, error) {
org, ok := mux.Vars(r)["org"]
if !ok {
return nil, fmt.Errorf("Internal error: no org in route")
}
repo, ok := mux.Vars(r)["repo"]
if !ok {
return nil, fmt.Errorf("Internal error: no repo in route")
}
pull, ok := mux.Vars(r)["pull"]
if !ok {
return nil, fmt.Errorf("Internal error: no pull in route")
}
pullNum, err := strconv.Atoi(pull)
if err != nil {
return nil, err
}

return &pullInfo{
org: org,
repo: repo,
pull: pullNum,
}, nil
}

// Gets the PR information from the HTTP request params
func newProjectInfo(r *http.Request) (*projectInfo, error) {
pullInfo, err := newPullInfo(r)
if err != nil {
return nil, err
}

project, ok := mux.Vars(r)["project"]
if !ok {
return nil, fmt.Errorf("Internal error: no project in route")
}

workspace, ok := mux.Vars(r)["workspace"]
if !ok {
return nil, fmt.Errorf("Internal error: no workspace in route")
}

return &projectInfo{
pullInfo: *pullInfo,
projectName: project,
workspace: workspace,
}, nil
}

func (j *JobsController) getProjectJobs(w http.ResponseWriter, r *http.Request) error {
projectInfo, err := newProjectInfo(r)
if err != nil {
j.respond(w, logging.Error, http.StatusInternalServerError, err.Error())
jobID, ok := mux.Vars(r)["job-id"]
Aayyush marked this conversation as resolved.
Show resolved Hide resolved
if !ok {
err := fmt.Errorf("internal error: no job ID in route")
j.respond(w, logging.Error, http.StatusBadRequest, err.Error())
return err
}

viewData := templates.ProjectJobData{
AtlantisVersion: j.AtlantisVersion,
ProjectPath: projectInfo.String(),
ProjectPath: jobID,
CleanedBasePath: j.AtlantisURL.Path,
ClearMsg: models.LogStreamingClearMsg,
}

err = j.ProjectJobsTemplate.Execute(w, viewData)
err := j.ProjectJobsTemplate.Execute(w, viewData)
if err != nil {
Aayyush marked this conversation as resolved.
Show resolved Hide resolved
j.Logger.Err(err.Error())
return err
Expand Down
30 changes: 12 additions & 18 deletions server/controllers/websocket/mux.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package websocket

import (
"fmt"
"net/http"

"github.com/gorilla/mux"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
"github.com/runatlantis/atlantis/server/logging"
)

// PartitionKeyGenerator generates partition keys for the multiplexor
type PartitionKeyGenerator interface {
Generate(r *http.Request) (string, error)
}

// PartitionRegistry is the registry holding each partition
// and is responsible for registering/deregistering new buffers
type PartitionRegistry interface {
Expand All @@ -24,40 +21,37 @@ type PartitionRegistry interface {
// and the registry. Note this is still a WIP as right now the registry is assumed to handle
// everything.
type Multiplexor struct {
writer *Writer
keyGenerator PartitionKeyGenerator
registry PartitionRegistry
writer *Writer
registry PartitionRegistry
}

func NewMultiplexor(log logging.SimpleLogging, keyGenerator PartitionKeyGenerator, registry PartitionRegistry) *Multiplexor {
func NewMultiplexor(log logging.SimpleLogging, registry PartitionRegistry) *Multiplexor {
upgrader := websocket.Upgrader{}
upgrader.CheckOrigin = func(r *http.Request) bool { return true }
return &Multiplexor{
writer: &Writer{
upgrader: upgrader,
log: log,
},
keyGenerator: keyGenerator,
registry: registry,
registry: registry,
}
}

// Handle should be called for a given websocket request. It blocks
// while writing to the websocket until the buffer is closed.
func (m *Multiplexor) Handle(w http.ResponseWriter, r *http.Request) error {
key, err := m.keyGenerator.Generate(r)

if err != nil {
return errors.Wrapf(err, "generating partition key")
jobID, ok := mux.Vars(r)["job-id"]
Aayyush marked this conversation as resolved.
Show resolved Hide resolved
if !ok {
return fmt.Errorf("internal error: no job ID in route")
}

// Buffer size set to 1000 to ensure messages get queued.
// TODO: make buffer size configurable
buffer := make(chan string, 1000)

// spinning up a goroutine for this since we are attempting to block on the read side.
go m.registry.Register(key, buffer)
defer m.registry.Deregister(key, buffer)
go m.registry.Register(jobID, buffer)
defer m.registry.Deregister(jobID, buffer)

return errors.Wrapf(m.writer.Write(w, r, buffer), "writing to ws %s", key)
return errors.Wrapf(m.writer.Write(w, r, buffer), "writing to ws %s", jobID)
}
94 changes: 94 additions & 0 deletions server/events/mocks/mock_job_id_generator.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion server/events/models/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,8 @@ type ProjectCommandContext struct {
PolicySets valid.PolicySets
// DeleteSourceBranchOnMerge will attempt to allow a branch to be deleted when merged (AzureDevOps & GitLab Support Only)
DeleteSourceBranchOnMerge bool
// UUID for atlantis logs
JobID string
}

// ProjectCloneDir creates relative path to clone the repo to. If we are running
Expand Down Expand Up @@ -712,8 +714,16 @@ func (c CommandName) TitleString() string {
return strings.Title(strings.ReplaceAll(strings.ToLower(c.String()), "_", " "))
}

type JobContext struct {
PullNum int
Repo string
ProjectName string
Workspace string
HeadCommit string
}

type ProjectCmdOutputLine struct {
ProjectInfo string
JobID string

Line string

Expand Down
7 changes: 6 additions & 1 deletion server/events/project_command_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"os"

"github.com/runatlantis/atlantis/server/events/yaml/valid"
"github.com/runatlantis/atlantis/server/handlers"
"github.com/runatlantis/atlantis/server/logging"
"github.com/uber-go/tally"

Expand Down Expand Up @@ -49,6 +50,7 @@ func NewProjectCommandBuilder(
AutoplanFileList string,
scope tally.Scope,
logger logging.SimpleLogging,
jobIDGenerator handlers.JobIDGenerator,
) ProjectCommandBuilder {
return NewProjectCommandBuilderWithLimit(
policyChecksSupported,
Expand All @@ -66,6 +68,7 @@ func NewProjectCommandBuilder(
scope,
logger,
InfiniteProjectsPerPR,
jobIDGenerator,
)
}

Expand All @@ -85,6 +88,7 @@ func NewProjectCommandBuilderWithLimit(
scope tally.Scope,
logger logging.SimpleLogging,
limit int,
jobIDGenerator handlers.JobIDGenerator,
) ProjectCommandBuilder {
var projectCommandBuilder ProjectCommandBuilder = &DefaultProjectCommandBuilder{
ParserValidator: parserValidator,
Expand All @@ -97,10 +101,11 @@ func NewProjectCommandBuilderWithLimit(
SkipCloneNoChanges: skipCloneNoChanges,
EnableRegExpCmd: EnableRegExpCmd,
AutoplanFileList: AutoplanFileList,
ProjectCommandContextBuilder: NewProjectCommandContextBulder(
ProjectCommandContextBuilder: NewProjectCommandContextBuilder(
policyChecksSupported,
commentBuilder,
scope,
jobIDGenerator,
),
}

Expand Down
Loading