Skip to content

Commit 39b24d2

Browse files
authored
feat: separate cidrlist SDK & CLI, and update the README accordingly (#2)
1 parent 17a9115 commit 39b24d2

16 files changed

+152
-120
lines changed

README.md

+48-16
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,61 @@
22

33
Simple cli to get CIDR list from well known providers
44

5-
## List IPs from following providers:
5+
## Available Providers
66

7-
- akamai (origin IP acl)
8-
- aws
9-
- cloudflare
10-
- gcp
11-
- google
7+
| Provider name | Constant name | Source of IP addresses |
8+
| :- | :- | :- |
9+
| `akamai` | `cidrlist.ProviderAkamai` | [Akamai Origin IP ACL](https://techdocs.akamai.com/origin-ip-acl/docs/welcome) |
10+
| `aws` | `cidrlist.ProviderAWS` | [AWS IP Address Ranges](https://docs.aws.amazon.com/vpc/latest/userguide/aws-ip-ranges.html) |
11+
| `cloudflare` | `cidrlist.ProviderCloudflare` | [Cloudflare IP Ranges](https://www.cloudflare.com/ips/) |
12+
| `gcp` | `cidrlist.ProviderGCP` | [Google Cloud Global & Regional IP Address Ranges](https://support.google.com/a/answer/10026322?hl=en) |
13+
| `google` | `cidrlist.ProviderGoogle` | [Google IP Address Ranges](https://support.google.com/a/answer/10026322?hl=en) |
1214

1315
## Usage
1416

15-
```bash
16-
usage: cidrlist <command> [<args> ...]
17+
Install the library using the following command:
1718

18-
A command-line tool to fetch IP address ranges from well known providers.
19+
```go
20+
go get -u github.com/franzramadhan/cidrlist
21+
```
22+
23+
Implementation example:
24+
25+
```go
26+
package main
27+
28+
import (
29+
"fmt"
30+
31+
"github.com/franzramadhan/cidrlist"
32+
)
1933

34+
func main() {
35+
ips, err := cidrlist.Get(cidrlist.ProviderAWS)
36+
if err != nil {
37+
fmt.Println(err)
38+
return
39+
}
2040

21-
Flags:
22-
--[no-]help Show context-sensitive help (also try --help-long and --help-man).
41+
fmt.Printf("IP of provider %s:\n", cidrlist.ProviderAWS)
42+
for _, ip := range ips {
43+
fmt.Println(ip)
44+
}
45+
}
46+
```
47+
48+
## CLI Usage
49+
50+
Install cidrlist CLI using the following command:
51+
52+
```go
53+
go install github.com/franzramadhan/cidrlist/cmd/cidrlist@latest
54+
```
2355

24-
Commands:
25-
help [<command>...]
26-
Show help.
56+
Usage:
2757

28-
get <provider>
29-
Get IP from provider (cloudflare, akamai, aws, gcp, and google).
58+
```go
59+
cidrlist get <provider-name>
60+
cidrlist get cloudflare
61+
cidrlist get gcp
3062
```

cidrlist.go

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package cidrlist
2+
3+
import (
4+
"fmt"
5+
6+
"github.com/franzramadhan/cidrlist/providers"
7+
)
8+
9+
type Provider string
10+
11+
const (
12+
ProviderAkamai Provider = "akamai"
13+
ProviderAWS Provider = "aws"
14+
ProviderCloudflare Provider = "cloudflare"
15+
ProviderGCP Provider = "gcp"
16+
ProviderGoogle Provider = "google"
17+
)
18+
19+
func GetProviderNames() []string {
20+
return []string{
21+
string(ProviderAkamai),
22+
string(ProviderAWS),
23+
string(ProviderCloudflare),
24+
string(ProviderGCP),
25+
string(ProviderGoogle),
26+
}
27+
}
28+
29+
func Get(provider Provider) ([]string, error) {
30+
fnByProviders := map[Provider]func() ([]string, error){
31+
ProviderAkamai: providers.AkamaiIps,
32+
ProviderAWS: new(providers.AwsInputs).AwsIps,
33+
ProviderCloudflare: providers.CloudflareIps,
34+
ProviderGCP: providers.GcpIps,
35+
ProviderGoogle: providers.GoogleIps,
36+
}
37+
38+
if fn, ok := fnByProviders[provider]; ok {
39+
return fn()
40+
}
41+
42+
return nil, fmt.Errorf("invalid provider %s", provider)
43+
}

cmd/cidrlist/main.go

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strings"
7+
8+
"github.com/alecthomas/kingpin/v2"
9+
"github.com/franzramadhan/cidrlist"
10+
)
11+
12+
var (
13+
app = kingpin.New("cidrlist", "A command-line tool to fetch IP address ranges from well known providers.")
14+
getIp = app.Command("get", fmt.Sprintf("Get IP from provider (%s).", strings.Join(cidrlist.GetProviderNames(), ", ")))
15+
providerName = getIp.Arg("provider", "The name of the provider.").Required().String()
16+
)
17+
18+
func main() {
19+
switch kingpin.MustParse(app.Parse(os.Args[1:])) {
20+
case getIp.FullCommand():
21+
target := strings.ToLower(*providerName)
22+
provider := cidrlist.Provider(target)
23+
ips, err := cidrlist.Get(provider)
24+
if err != nil {
25+
fmt.Println(err)
26+
return
27+
}
28+
fmt.Printf("%s:\n%s", strings.ToUpper(target), ips)
29+
}
30+
}

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ go 1.21.4
55
require github.com/alecthomas/kingpin/v2 v2.4.0
66

77
require (
8-
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
8+
github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 // indirect
99
github.com/xhit/go-str2duration/v2 v2.1.0 // indirect
1010
)

go.sum

+2
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ github.com/alecthomas/kingpin/v2 v2.4.0 h1:f48lwail6p8zpO1bC4TxtqACaGqHYA22qkHjH
22
github.com/alecthomas/kingpin/v2 v2.4.0/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE=
33
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc=
44
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
5+
github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9 h1:ez/4by2iGztzR4L0zgAOR8lTQK9VlyBVVd7G4omaOQs=
6+
github.com/alecthomas/units v0.0.0-20231202071711-9a357b53e9c9/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE=
57
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
68
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
79
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=

main.go

-59
This file was deleted.

providers/akamai.go

+3-7
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
package providers
22

3-
import (
4-
"strings"
5-
)
6-
73
/*
84
Origin IP Access Control List (Origin IP ACL) offers some protection for your origin server by restricting traffic to ​Akamai​-controlled IP addresses.
95
​Akamai​ maintains a small and stable list of IP addresses that you use in policy rules in your origin server's firewall.
@@ -12,6 +8,7 @@ CIDR is an IP addressing scheme that improves the allocation of IP addresses by
128
139
Reference: https://techdocs.akamai.com/origin-ip-acl/docs/welcome
1410
*/
11+
1512
var AkamaiCidrs = []string{
1613
"23.32.0.0/11",
1714
"23.192.0.0/11",
@@ -37,7 +34,6 @@ var AkamaiCidrs = []string{
3734
"2405:9600::/32",
3835
}
3936

40-
func AkamaiIps() (string, error) {
41-
results := strings.Join(AkamaiCidrs, ",")
42-
return results, nil
37+
func AkamaiIps() ([]string, error) {
38+
return AkamaiCidrs, nil
4339
}

providers/akamai_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package providers
22

33
import (
44
"net"
5-
"strings"
65
"testing"
76
)
87

@@ -13,7 +12,7 @@ func TestAkamaiIps(t *testing.T) {
1312
t.Fatal(err)
1413
}
1514

16-
for _, prefix := range strings.Split(ips, ",") {
15+
for _, prefix := range ips {
1716
ipv4Addr, _, err := net.ParseCIDR(prefix)
1817
if err != nil {
1918
t.Errorf("Akamai IP Address is invalid %s", ipv4Addr)

providers/aws.go

+5-7
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"encoding/json"
55
"net/http"
66
"slices"
7-
"strings"
87
)
98

109
/*
@@ -42,25 +41,25 @@ type AwsInputs struct {
4241
// Service string
4342
}
4443

45-
func (a *AwsInputs) AwsIps() (string, error) {
44+
func (a *AwsInputs) AwsIps() ([]string, error) {
4645
var err error
4746
var client = &http.Client{}
4847
var data *Aws
4948
var prefixes []string
5049

5150
request, err := http.NewRequest(http.MethodGet, URL_AWS, nil)
5251
if err != nil {
53-
return "", err
52+
return nil, err
5453
}
5554
response, err := client.Do(request)
5655
if err != nil {
57-
return "", err
56+
return nil, err
5857
}
5958
defer response.Body.Close()
6059

6160
err = json.NewDecoder(response.Body).Decode(&data)
6261
if err != nil {
63-
return "", err
62+
return nil, err
6463
}
6564

6665
switch ipType := a.IpType; ipType {
@@ -84,7 +83,6 @@ func (a *AwsInputs) AwsIps() (string, error) {
8483

8584
slices.Sort(prefixes)
8685
prefixes = slices.Compact(prefixes)
87-
results := strings.Join(prefixes, ",")
8886

89-
return results, nil
87+
return prefixes, nil
9088
}

providers/aws_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package providers
22

33
import (
44
"net"
5-
"strings"
65
"testing"
76
)
87

@@ -14,7 +13,7 @@ func TestAwsIps(t *testing.T) {
1413
t.Fatal(err)
1514
}
1615

17-
for _, prefix := range strings.Split(ips, ",") {
16+
for _, prefix := range ips {
1817
ipv4Addr, _, err := net.ParseCIDR(prefix)
1918
if err != nil {
2019
t.Errorf("AWS IP Address is invalid %s", ipv4Addr)

providers/cloudflare.go

+5-6
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package providers
33
import (
44
"encoding/json"
55
"net/http"
6-
"strings"
76
)
87

98
/*
@@ -28,27 +27,27 @@ type Cloudflare struct {
2827
Messages []interface{} `json:"messages"`
2928
}
3029

31-
func CloudflareIps() (string, error) {
30+
func CloudflareIps() ([]string, error) {
3231
var err error
3332
var client = &http.Client{}
3433
var data *Cloudflare
3534

3635
request, err := http.NewRequest(http.MethodGet, URL_CLOUDFLARE, nil)
3736
if err != nil {
38-
return "", err
37+
return nil, err
3938
}
4039
response, err := client.Do(request)
4140
if err != nil {
42-
return "", err
41+
return nil, err
4342
}
4443
defer response.Body.Close()
4544

4645
err = json.NewDecoder(response.Body).Decode(&data)
4746
if err != nil {
48-
return "", err
47+
return nil, err
4948
}
5049

51-
results := strings.Join(append(data.Result.Ipv4Cidrs, data.Result.Ipv6Cidrs...), ",")
50+
results := append(data.Result.Ipv4Cidrs, data.Result.Ipv6Cidrs...)
5251

5352
return results, nil
5453
}

providers/cloudflare_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package providers
22

33
import (
44
"net"
5-
"strings"
65
"testing"
76
)
87

@@ -13,7 +12,7 @@ func TestCloudflareIps(t *testing.T) {
1312
t.Fatal(err)
1413
}
1514

16-
for _, prefix := range strings.Split(ips, ",") {
15+
for _, prefix := range ips {
1716
ipv4Addr, _, err := net.ParseCIDR(prefix)
1817
if err != nil {
1918
t.Errorf("Cloudflare IP Address is invalid %s", ipv4Addr)

0 commit comments

Comments
 (0)