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"
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{
26 Type: function.StaticReturnType(cty.String),
27 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
29 if err := gocty.FromCtyValue(args[1], &hostNum); err != nil {
30 return cty.UnknownVal(cty.String), err
32 _, network, err := net.ParseCIDR(args[0].AsString())
34 return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err)
37 ip, err := cidr.Host(network, hostNum)
39 return cty.UnknownVal(cty.String), err
42 return cty.StringVal(ip.String()), nil
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{
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())
59 return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err)
62 return cty.StringVal(net.IP(network.Mask).String()), nil
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{
83 Type: function.StaticReturnType(cty.String),
84 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
86 if err := gocty.FromCtyValue(args[1], &newbits); err != nil {
87 return cty.UnknownVal(cty.String), err
90 if err := gocty.FromCtyValue(args[2], &netnum); err != nil {
91 return cty.UnknownVal(cty.String), err
94 _, network, err := net.ParseCIDR(args[0].AsString())
96 return cty.UnknownVal(cty.String), fmt.Errorf("invalid CIDR expression: %s", err)
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.)
104 return cty.UnknownVal(cty.String), fmt.Errorf("may not extend prefix by more than 32 bits")
107 newNetwork, err := cidr.Subnet(network, newbits, netnum)
109 return cty.UnknownVal(cty.String), err
112 return cty.StringVal(newNetwork.String()), nil
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})
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})
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})