-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathsync.go
128 lines (110 loc) · 4.14 KB
/
sync.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
package personnel_sync
import (
"errors"
"fmt"
"log"
"os"
"strings"
"time"
"github.com/silinternational/personnel-sync/v6/alert"
"github.com/silinternational/personnel-sync/v6/google"
"github.com/silinternational/personnel-sync/v6/internal"
"github.com/silinternational/personnel-sync/v6/restapi"
"github.com/silinternational/personnel-sync/v6/webhelpdesk"
)
func RunSync(configFile string) error {
log.SetOutput(os.Stdout)
log.SetFlags(0)
log.Printf("Personnel sync started at %s", time.Now().UTC().Format(time.RFC1123Z))
rawConfig, err := internal.LoadConfig(configFile)
if err != nil {
msg := fmt.Sprintf("Unable to load config, error: %s", err)
log.Println(msg)
return nil
}
config, err := internal.ReadConfig(rawConfig)
if err != nil {
msg := fmt.Sprintf("Unable to read config, error: %s", err)
log.Println(msg)
alert.SendEmail(config.Alert, msg)
return nil
}
// Instantiate Source
var source internal.Source
switch config.Source.Type {
case internal.SourceTypeRestAPI:
source, err = restapi.NewRestAPISource(config.Source)
case internal.SourceTypeGoogleSheets:
source, err = google.NewGoogleSheetsSource(config.Source)
default:
err = errors.New("unrecognized source type")
}
if err != nil {
msg := fmt.Sprintf("Unable to initialize %s source, error: %s", config.Source.Type, err)
log.Println(msg)
alert.SendEmail(config.Alert, msg)
return nil
}
// Instantiate Destination
var destination internal.Destination
switch config.Destination.Type {
case internal.DestinationTypeGoogleContacts:
destination, err = google.NewGoogleContactsDestination(config.Destination)
case internal.DestinationTypeGoogleGroups:
destination, err = google.NewGoogleGroupsDestination(config.Destination)
case internal.DestinationTypeGoogleSheets:
destination, err = google.NewGoogleSheetsDestination(config.Destination)
case internal.DestinationTypeGoogleUsers:
destination, err = google.NewGoogleUsersDestination(config.Destination)
case internal.DestinationTypeRestAPI:
destination, err = restapi.NewRestAPIDestination(config.Destination)
case internal.DestinationTypeWebHelpDesk:
destination, err = webhelpdesk.NewWebHelpDeskDestination(config.Destination)
default:
err = errors.New("unrecognized destination type")
}
if err != nil {
msg := fmt.Sprintf("Unable to initialize %s destination, error: %s", config.Destination.Type, err)
log.Println(msg)
alert.SendEmail(config.Alert, msg)
return nil
}
maxNameLength := config.MaxSyncSetNameLength()
var alertList []string
// Iterate through SyncSets and process changes
for i, syncSet := range config.SyncSets {
if syncSet.Name == "" {
msg := "configuration contains a set with no name"
alertList = append(alertList, msg)
}
prefix := fmt.Sprintf("[ %-*s ] ", maxNameLength, syncSet.Name)
syncSetLogger := log.New(os.Stdout, prefix, 0)
syncSetLogger.Printf("(%v/%v) Beginning sync set", i+1, len(config.SyncSets))
// Apply SyncSet configs (excluding source/destination as appropriate)
if err = source.ForSet(syncSet.Source); err != nil {
err = fmt.Errorf(`Error setting source set on syncSet "%s": %w`, syncSet.Name, err)
alertList = handleSyncError(syncSetLogger, err, alertList)
}
if err = destination.ForSet(syncSet.Destination); err != nil {
err = fmt.Errorf(`Error setting destination set on syncSet "%s": %w`, syncSet.Name, err)
alertList = handleSyncError(syncSetLogger, err, alertList)
}
if err = internal.RunSyncSet(syncSetLogger, source, destination, config); err != nil {
err = fmt.Errorf(`Sync failed with error on syncSet "%s": %w`, syncSet.Name, err)
alertList = handleSyncError(syncSetLogger, err, alertList)
}
}
if len(alertList) > 0 {
alert.SendEmail(config.Alert, fmt.Sprintf("Sync error(s):\n%s", strings.Join(alertList, "\n")))
}
log.Printf("Personnel sync completed at %s", time.Now().UTC().Format(time.RFC1123Z))
return nil
}
func handleSyncError(logger *log.Logger, err error, alertList []string) []string {
logger.Println(err)
var syncError internal.SyncError
if isSyncError := errors.As(err, &syncError); !isSyncError || syncError.SendAlert {
alertList = append(alertList, err.Error())
}
return alertList
}