-
Notifications
You must be signed in to change notification settings - Fork 3
/
cmd_sync.go
117 lines (93 loc) · 3.16 KB
/
cmd_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
package main
import (
"log"
common "github.com/apiheat/akamai-cli-common/v4"
service "github.com/apiheat/go-edgegrid/v6/service/netlistv2"
"github.com/urfave/cli/v2"
)
// cmdSyncNetListID is used by cli to sync items between source and target list
func cmdSyncNetListID(c *cli.Context) error {
return syncNetListbyID(c)
}
// cmdsyncNetListWithFile is used by cli to sync items between local file and target akamai network list
func cmdsyncNetListWithFile(c *cli.Context) error {
return syncNetListWithFile(c)
}
// syncNetListbyID synchronizes item from src list to destination list
func syncNetListbyID(c *cli.Context) error {
synchronize(c.String("id-src"), c.String("id-dst"), false, c.Bool("force"), c.Bool("dry-run"))
return nil
}
// syncNetListWithFile synchronizes item from src list to destination list
func syncNetListWithFile(c *cli.Context) error {
synchronize(c.String("from-file"), c.String("id-dst"), true, c.Bool("force"), c.Bool("dry-run"))
return nil
}
//synchronize is used to synchronize between 2 sources of IPs. If used with force option it will
//also perform removal of addresses from the target.
func synchronize(source, destination string, fromFile, force, dryRun bool) {
var ipsFromSource []string
listNetListOptsv2 := service.ListNetworkListsOptionsv2{}
listNetListOptsv2.IncludeElements = true
if fromFile {
// Get source IPs from file in local system
sourceIPs, err := readLinesFromFile(source)
if err != nil {
log.Fatal(err)
}
ipsFromSource = sourceIPs
} else {
// Get source IPs from list in Akamai
netListSrc, netlistErr := apiClient.GetNetworkList(source, listNetListOptsv2)
if netlistErr != nil {
log.Fatalln(netlistErr)
}
ipsFromSource = netListSrc.List
}
// Get the destination list
netListDst, netlistErr := apiClient.GetNetworkList(destination, listNetListOptsv2)
if netlistErr != nil {
log.Fatalln(netlistErr)
}
//What is present in source list and not in destination
diffAdd := stringsSlicesDifference(ipsFromSource, netListDst.List)
//What is present in destination list and not in source
diffRemove := stringsSlicesDifference(netListDst.List, ipsFromSource)
if dryRun {
diff := struct {
InSrc []string `json:"add,omitempty"`
InDst []string `json:"remmove,omitempty"`
}{
InSrc: unique(diffAdd),
InDst: diffRemove,
}
common.OutputJSON(diff)
return
}
//Safe check we will not remove all ips we have
if len(diffRemove) > 0 && !force {
log.Fatalf("Some IPs are present in target, but not in source. %v. Use `--force` to enable removing", diffRemove)
}
//Iterate and remove the values which are not present in file
for _, IPForRemoval := range diffRemove {
_, err := apiClient.RemoveNetworkListElement(destination, IPForRemoval)
if err != nil {
log.Fatal(err)
}
}
//if there is nothing to add - bail out...
if len(diffAdd) == 0 {
return
}
//Add entire set from the file to the change
syncListOpts := service.NetworkListsOptionsv2{
List: unique(ipsFromSource),
}
// Append items from src list to dst list
netListDst, errAdd := apiClient.AddNetworkListElement(destination, syncListOpts)
if errAdd != nil {
log.Fatal(errAdd)
}
common.OutputJSON(netListDst)
return
}