k8s.io/registry.k8s.io@v0.3.1/pkg/net/cloudcidrs/internal/ranges2go/parse_aws.go (about) 1 /* 2 Copyright 2022 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "encoding/json" 21 "net/netip" 22 "sort" 23 ) 24 25 // parseAWS parses raw AWS IP ranges JSON data 26 // and processes it to a regionsToPrefixes map 27 func parseAWS(raw string) (regionsToPrefixes, error) { 28 parsed, err := parseAWSIPRangesJSON([]byte(raw)) 29 if err != nil { 30 return nil, err 31 } 32 return awsRegionsToPrefixesFromData(parsed) 33 } 34 35 /* 36 For more on these datatypes see: 37 https://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html 38 */ 39 40 type AWSIPRangesJSON struct { 41 Prefixes []AWSPrefix `json:"prefixes"` 42 IPv6Prefixes []AWSIPv6Prefix `json:"ipv6_prefixes"` 43 // syncToken and createDate omitted 44 } 45 46 type AWSPrefix struct { 47 IPPrefix string `json:"ip_prefix"` 48 Region string `json:"region"` 49 Service string `json:"service"` 50 // network_border_group omitted 51 } 52 53 type AWSIPv6Prefix struct { 54 IPv6Prefix string `json:"ipv6_prefix"` 55 Region string `json:"region"` 56 Service string `json:"service"` 57 // network_border_group omitted 58 } 59 60 // parseIPRangesJSON parse AWS IP ranges JSON data 61 // https://docs.aws.amazon.com/general/latest/gr/aws-ip-ranges.html 62 func parseAWSIPRangesJSON(rawJSON []byte) (*AWSIPRangesJSON, error) { 63 r := &AWSIPRangesJSON{} 64 if err := json.Unmarshal(rawJSON, r); err != nil { 65 return nil, err 66 } 67 return r, nil 68 } 69 70 // awsRegionsToPrefixesFromData processes the raw unmarshalled JSON into regionsToPrefixes map 71 func awsRegionsToPrefixesFromData(data *AWSIPRangesJSON) (regionsToPrefixes, error) { 72 // convert from AWS published structure to a map by region, parse Prefixes 73 rtp := regionsToPrefixes{} 74 for _, prefix := range data.Prefixes { 75 region := prefix.Region 76 ipPrefix, err := netip.ParsePrefix(prefix.IPPrefix) 77 if err != nil { 78 return nil, err 79 } 80 rtp[region] = append(rtp[region], ipPrefix) 81 } 82 for _, prefix := range data.IPv6Prefixes { 83 region := prefix.Region 84 ipPrefix, err := netip.ParsePrefix(prefix.IPv6Prefix) 85 if err != nil { 86 return nil, err 87 } 88 rtp[region] = append(rtp[region], ipPrefix) 89 } 90 91 // flatten 92 numPrefixes := 0 93 for region := range rtp { 94 // this approach allows us to produce consistent generated results 95 // since the ip ranges will be ordered 96 sort.Slice(rtp[region], func(i, j int) bool { 97 return rtp[region][i].String() < rtp[region][j].String() 98 }) 99 rtp[region] = dedupeSortedPrefixes(rtp[region]) 100 numPrefixes += len(rtp[region]) 101 } 102 103 return rtp, nil 104 }