diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/lang/funcs/cidr.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/lang/funcs/cidr.go | 129 |
1 files changed, 129 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/lang/funcs/cidr.go b/vendor/github.com/hashicorp/terraform/lang/funcs/cidr.go new file mode 100644 index 0000000..6ce8aa9 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/lang/funcs/cidr.go | |||
@@ -0,0 +1,129 @@ | |||
1 | package funcs | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "net" | ||
6 | |||
7 | "github.com/apparentlymart/go-cidr/cidr" | ||
8 | "github.com/zclconf/go-cty/cty" | ||
9 | "github.com/zclconf/go-cty/cty/function" | ||
10 | "github.com/zclconf/go-cty/cty/gocty" | ||
11 | ) | ||
12 | |||
13 | // CidrHostFunc contructs a function that calculates a full host IP address | ||
14 | // within a given IP network address prefix. | ||
15 | var CidrHostFunc = function.New(&function.Spec{ | ||
16 | Params: []function.Parameter{ | ||
17 | { | ||
18 | Name: "prefix", | ||
19 | Type: cty.String, | ||
20 | }, | ||
21 | { | ||
22 | Name: "hostnum", | ||
23 | Type: cty.Number, | ||
24 | }, | ||
25 | }, | ||
26 | Type: function.StaticReturnType(cty.String), | ||
27 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
28 | var hostNum int | ||
29 | if err := gocty.FromCtyValue(args[1], &hostNum); err != nil { | ||
30 | return cty.UnknownVal(cty.String), err | ||
31 | } | ||
32 | _, network, err := net.ParseCIDR(args[0].AsString()) | ||
33 | if err != nil { | ||
34 | return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err) | ||
35 | } | ||
36 | |||
37 | ip, err := cidr.Host(network, hostNum) | ||
38 | if err != nil { | ||
39 | return cty.UnknownVal(cty.String), err | ||
40 | } | ||
41 | |||
42 | return cty.StringVal(ip.String()), nil | ||
43 | }, | ||
44 | }) | ||
45 | |||
46 | // CidrNetmaskFunc contructs a function that converts an IPv4 address prefix given | ||
47 | // in CIDR notation into a subnet mask address. | ||
48 | var CidrNetmaskFunc = function.New(&function.Spec{ | ||
49 | Params: []function.Parameter{ | ||
50 | { | ||
51 | Name: "prefix", | ||
52 | Type: cty.String, | ||
53 | }, | ||
54 | }, | ||
55 | Type: function.StaticReturnType(cty.String), | ||
56 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
57 | _, network, err := net.ParseCIDR(args[0].AsString()) | ||
58 | if err != nil { | ||
59 | return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err) | ||
60 | } | ||
61 | |||
62 | return cty.StringVal(net.IP(network.Mask).String()), nil | ||
63 | }, | ||
64 | }) | ||
65 | |||
66 | // CidrSubnetFunc contructs a function that calculates a subnet address within | ||
67 | // a given IP network address prefix. | ||
68 | var CidrSubnetFunc = function.New(&function.Spec{ | ||
69 | Params: []function.Parameter{ | ||
70 | { | ||
71 | Name: "prefix", | ||
72 | Type: cty.String, | ||
73 | }, | ||
74 | { | ||
75 | Name: "newbits", | ||
76 | Type: cty.Number, | ||
77 | }, | ||
78 | { | ||
79 | Name: "netnum", | ||
80 | Type: cty.Number, | ||
81 | }, | ||
82 | }, | ||
83 | Type: function.StaticReturnType(cty.String), | ||
84 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
85 | var newbits int | ||
86 | if err := gocty.FromCtyValue(args[1], &newbits); err != nil { | ||
87 | return cty.UnknownVal(cty.String), err | ||
88 | } | ||
89 | var netnum int | ||
90 | if err := gocty.FromCtyValue(args[2], &netnum); err != nil { | ||
91 | return cty.UnknownVal(cty.String), err | ||
92 | } | ||
93 | |||
94 | _, network, err := net.ParseCIDR(args[0].AsString()) | ||
95 | if err != nil { | ||
96 | return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err) | ||
97 | } | ||
98 | |||
99 | // For portability with 32-bit systems where the subnet number | ||
100 | // will be a 32-bit int, we only allow extension of 32 bits in | ||
101 | // one call even if we're running on a 64-bit machine. | ||
102 | // (Of course, this is significant only for IPv6.) | ||
103 | if newbits > 32 { | ||
104 | return cty.UnknownVal(cty.String), fmt.Errorf("may not extend prefix by more than 32 bits") | ||
105 | } | ||
106 | |||
107 | newNetwork, err := cidr.Subnet(network, newbits, netnum) | ||
108 | if err != nil { | ||
109 | return cty.UnknownVal(cty.String), err | ||
110 | } | ||
111 | |||
112 | return cty.StringVal(newNetwork.String()), nil | ||
113 | }, | ||
114 | }) | ||
115 | |||
116 | // CidrHost calculates a full host IP address within a given IP network address prefix. | ||
117 | func CidrHost(prefix, hostnum cty.Value) (cty.Value, error) { | ||
118 | return CidrHostFunc.Call([]cty.Value{prefix, hostnum}) | ||
119 | } | ||
120 | |||
121 | // CidrNetmask converts an IPv4 address prefix given in CIDR notation into a subnet mask address. | ||
122 | func CidrNetmask(prefix cty.Value) (cty.Value, error) { | ||
123 | return CidrNetmaskFunc.Call([]cty.Value{prefix}) | ||
124 | } | ||
125 | |||
126 | // CidrSubnet calculates a subnet address within a given IP network address prefix. | ||
127 | func CidrSubnet(prefix, newbits, netnum cty.Value) (cty.Value, error) { | ||
128 | return CidrSubnetFunc.Call([]cty.Value{prefix, newbits, netnum}) | ||
129 | } | ||