Skip to content

Commit

Permalink
Setup parallel syncing logic
Browse files Browse the repository at this point in the history
  • Loading branch information
Julien Duchesne committed Jun 4, 2019
1 parent 567696c commit 2a8de07
Show file tree
Hide file tree
Showing 9 changed files with 120 additions and 79 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
.vscode

# Binaries for programs and plugins
*.exe
*.exe~
Expand Down
19 changes: 0 additions & 19 deletions 123.json

This file was deleted.

3 changes: 0 additions & 3 deletions cli/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ var rootCmd = &cobra.Command{
}
return mapstructure.Decode(configurationDict, configuration)
},
Run: func(cmd *cobra.Command, args []string) {
cmd.Help()
},
}

func init() {
Expand Down
20 changes: 0 additions & 20 deletions config.yaml

This file was deleted.

6 changes: 5 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,14 @@ go 1.12

require (
github.com/aws/aws-sdk-go v1.19.11
github.com/bndr/gojenkins v0.2.0
github.com/bndr/gojenkins v0.0.0-00010101000000-000000000000
github.com/inconshreveable/mousetrap v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.1.2
github.com/sirupsen/logrus v1.4.1
github.com/spf13/cobra v0.0.3
github.com/spf13/pflag v1.0.3 // indirect
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 // indirect
gopkg.in/yaml.v2 v2.2.2
)

replace github.com/bndr/gojenkins => github.com/julienduchesne/gojenkins v2.0.0+incompatible
14 changes: 12 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
github.com/aws/aws-sdk-go v1.19.11 h1:tqaTGER6Byw3QvsjGW0p018U2UOqaJPeJuzoaF7jjoQ=
github.com/aws/aws-sdk-go v1.19.11/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/bndr/gojenkins v0.2.0 h1:fplg5+NQoDCPlJSXSqCIspf7uiLiDzMpw9rimLt5sHs=
github.com/bndr/gojenkins v0.2.0/go.mod h1:J2FxlujWW87NJJrdysyctcDllRVYUONGGlHX16134P4=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af h1:pmfjZENx5imkbgOkpRUYLnmbU7UEFbjtDA2hxJ1ichM=
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/julienduchesne/gojenkins v2.0.0+incompatible h1:/XwAEsQjBa4z4zJ6ADtN41jLDvJ/Oxsh5S3JAP29SJM=
github.com/julienduchesne/gojenkins v2.0.0+incompatible/go.mod h1:vyTgrnBY+eN7w3FULQEfdrbSMecftCpXw9XGQmF76dk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
Expand All @@ -20,8 +23,15 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco=
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33 h1:I6FyU15t786LL7oL/hn43zqTuEGr4PN7F4XJ1p4E3Y8=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
Expand Down
70 changes: 59 additions & 11 deletions sync/config.go
Original file line number Diff line number Diff line change
@@ -1,47 +1,95 @@
package sync

import (
"fmt"

"github.com/coveo/credentials-sync/credentials"
"github.com/coveo/credentials-sync/targets"
log "github.com/sirupsen/logrus"
)

type Configuration struct {
Sources *credentials.SourcesConfiguration
StopOnError bool `mapstructure:"stop_on_error"`
Targets *targets.Configuration
Sources *credentials.SourcesConfiguration
StopOnError bool `mapstructure:"stop_on_error"`
TargetParallelism int `mapstructure:"target_parallelism"`
Targets *targets.Configuration
}

func NewConfiguration() *Configuration {
return &Configuration{
StopOnError: false,
StopOnError: false,
TargetParallelism: 4,
}
}

func (config *Configuration) Sync() {
validTargets := []targets.Target{}
// Start reading credentials
creds, err := config.Sources.Credentials()
if err != nil {
log.Fatalf("Caught an error while fetching credentials")
}

// Initialize targets
validTargets := []targets.Target{}
allTargets := config.Targets.AllTargets()
initChannel := make(chan targets.Target)
for _, target := range allTargets {
go initTarget(target, initChannel)
go initTarget(target, creds, initChannel, config.StopOnError)
}
for i := 0; i < len(allTargets); i++ {
initTarget := <-initChannel
if initTarget != nil {
validTargets = append(validTargets, initTarget)
} else if config.StopOnError {
return
}
}

syncChannel := make(chan bool, config.TargetParallelism)
for _, target := range validTargets {
syncChannel <- true
go syncCredentials(target, creds, syncChannel, config.StopOnError)
}

for i := 0; i < cap(syncChannel); i++ {
syncChannel <- true
}

}

func initTarget(target targets.Target, channel chan targets.Target) {
err := target.Initialize([]credentials.Credentials{})
func initTarget(target targets.Target, creds []credentials.Credentials, channel chan targets.Target, panicOnError bool) {
err := target.Initialize(creds)
if err == nil {
log.Infof("Connected to %s", target.ToString())
channel <- target
} else {
log.Errorf("Target `%s` has failed initialization. Ignoring it.", target.GetName())
message := fmt.Sprintf("Target `%s` has failed initialization: %v", target.GetName(), err)
if panicOnError {
log.Fatal(message)
}
log.Warning(message)
channel <- nil
}
}

func syncCredentials(target targets.Target, credentialsList []credentials.Credentials, channel chan bool, panicOnError bool) {
defer func() { <-channel }()

credChannel := make(chan bool, 1)
for _, cred := range credentialsList {
credChannel <- true
go func(cred credentials.Credentials) {
defer func() { <-credChannel }()
if err := target.UpdateCredentials(cred); err != nil {
message := fmt.Sprintf("Failed to send credential %s to %s: %v", cred.GetID(), target.GetName(), err)
if panicOnError {
log.Fatal(message)
}
log.Error(message)
}
}(cred)
}
for i := 0; i < cap(credChannel); i++ {
credChannel <- true
}

log.Infof("Finished sync to %s", target.GetName())
}
61 changes: 40 additions & 21 deletions targets/jenkins.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"github.com/coveo/credentials-sync/credentials"
)

const credentialsDomain = "_"

type JenkinsTarget struct {
Base `mapstructure:",squash"`

Expand All @@ -19,33 +21,18 @@ type JenkinsTarget struct {
SecureConnection bool `mapstructure:"secure_connections"`

client *gojenkins.Jenkins
existingCredentials []credentials.Credentials
credentialsManager *gojenkins.CredentialsManager
existingCredentials []string
loginCredentials credentials.Credentials
}

func (jenkins *JenkinsTarget) GetName() string {
return jenkins.Name
}

func (jenkins *JenkinsTarget) Initialize(allCredentials []credentials.Credentials) error {
for _, credentials := range allCredentials {
if jenkins.CredentialsID != nil && credentials.GetID() == *jenkins.CredentialsID {
jenkins.loginCredentials = credentials
}
}
if jenkins.loginCredentials != nil {
auth := jenkins.loginCredentials.(*credentials.UsernamePasswordCredentials)
jenkins.client = gojenkins.CreateJenkins(jenkins.URL, auth.Username, auth.Password)
} else {
jenkins.client = gojenkins.CreateJenkins(jenkins.URL)
}

jenkins.client.Requester.SslVerify = jenkins.SecureConnection
jenkins.client.Init()
var err error
func (jenkins *JenkinsTarget) Initialize(allCredentials []credentials.Credentials) (err error) {
defer func() {
if r := recover(); r != nil {
log.Error("Recovered the following error while initializing Jenkins: ", r)
switch x := r.(type) {
case string:
err = errors.New(x)
Expand All @@ -56,14 +43,43 @@ func (jenkins *JenkinsTarget) Initialize(allCredentials []credentials.Credential
}
}
}()
for _, credentials := range allCredentials {
if jenkins.CredentialsID != nil && credentials.GetID() == *jenkins.CredentialsID {
jenkins.loginCredentials = credentials
}
}
if jenkins.loginCredentials != nil {
auth := jenkins.loginCredentials.(*credentials.UsernamePasswordCredentials)
jenkins.client = gojenkins.CreateJenkins(nil, jenkins.URL, auth.Username, auth.Password)
} else {
jenkins.client = gojenkins.CreateJenkins(nil, jenkins.URL)
}

jenkins.client.Requester.SslVerify = jenkins.SecureConnection
jenkins.client.Init()
jenkins.credentialsManager = &gojenkins.CredentialsManager{
J: jenkins.client,
}

jenkins.existingCredentials, err = jenkins.credentialsManager.List(credentialsDomain)

return err
}

func (jenkins *JenkinsTarget) HasCredentials(cred credentials.Credentials) bool {
for _, id := range jenkins.existingCredentials {
if cred.GetID() == id {
return true
}
}
return false
}

func (jenkins *JenkinsTarget) ToString() string {
return fmt.Sprintf("%s (Jenkins) - %s", jenkins.BaseToString(), jenkins.URL)
}

func (jenkins *JenkinsTarget) UpdateListOfCredentials(listOfCredentials []*credentials.Credentials) error {
func (jenkins *JenkinsTarget) UpdateListOfCredentials(listOfCredentials []credentials.Credentials) error {
for _, credentials := range listOfCredentials {
if err := jenkins.UpdateCredentials(credentials); err != nil {
return err
Expand All @@ -72,8 +88,11 @@ func (jenkins *JenkinsTarget) UpdateListOfCredentials(listOfCredentials []*crede
return nil
}

func (jenkins *JenkinsTarget) UpdateCredentials(credentials *credentials.Credentials) error {
return nil
func (jenkins *JenkinsTarget) UpdateCredentials(cred credentials.Credentials) error {
if jenkins.HasCredentials(cred) {
return jenkins.credentialsManager.Update(credentialsDomain, cred.GetID(), cred)
}
return jenkins.credentialsManager.Add(credentialsDomain, cred)
}

func (jenkins *JenkinsTarget) ValidateConfiguration() bool {
Expand Down
4 changes: 2 additions & 2 deletions targets/targets.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ type Target interface {
GetName() string
Initialize([]credentials.Credentials) error
ToString() string
UpdateListOfCredentials([]*credentials.Credentials) error
UpdateCredentials(*credentials.Credentials) error
UpdateListOfCredentials([]credentials.Credentials) error
UpdateCredentials(credentials.Credentials) error
ValidateConfiguration() bool
}

Expand Down

0 comments on commit 2a8de07

Please sign in to comment.