Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functionality to parse multiple prefixes #35

Merged
merged 1 commit into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
render:
@for file in examples/xr-*.yaml; do \
echo ""; \
echo "Rendering $$file..."; \
crossplane beta render \
"$$file" \
apis/composition.yaml \
examples/functions.yaml; \
done

debug:
go run . --insecure --debug
101 changes: 71 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,98 +5,119 @@ A [Crossplane](https://www.crossplane.io/)
for calculating Classless Inter-Domain Routing
([CIDR](https://en.wikipedia.org/wiki/Classless_Inter-Domain_Routing))
numbers.

A CIDR is an IP address allocation method that is used to improve
data routing efficiency on the internet.

## Overview

This composition function offers 4 HashiCorp compatible
IP Network Functions plus one custom wrapper. Follow the
function links for detailed explanations of the function
semantics.
This composition function offers 4 HashiCorp compatible IP Network Functions
plus two custom wrappers. Follow the function links for detailed explanations of
the function semantics.

- [cidrhost](https://developer.hashicorp.com/terraform/language/functions/cidrhost)
- [cidrnetmask](https://developer.hashicorp.com/terraform/language/functions/cidrnetmask)
- [cidrsubnet](https://developer.hashicorp.com/terraform/language/functions/cidrsubnet)
- [cidrsubnets](https://developer.hashicorp.com/terraform/language/functions/cidrsubnets)
- cidrsubnetloop wraps [cidrsubnet](https://developer.hashicorp.com/terraform/language/functions/cidrsubnet)
- multiprefixloop wraps [cidrsubnets](https://developer.hashicorp.com/terraform/language/functions/cidrsubnets)

To use this function, apply the following
[functions.yaml](examples/functions.yaml)
to your Crossplane management cluster.
```

```bash
cat <<EOF|kubectl apply -f -
apiVersion: pkg.crossplane.io/v1beta1
kind: Function
metadata:
name: upbound-function-cidr
spec:
package: xpkg.upbound.io/upbound/function-cidr:v0.1.0
package: xpkg.upbound.io/upbound/function-cidr:v0.4.0
EOF
```

Call the function from a Crossplane composition as described below.

## Terminology

The `cidrfunc` IP Network Functions have various input parameters.
Below are brief descriptions for context.

- `prefix` must be given in CIDR notation, as defined in [RFC 4632 section 3.1.](https://datatracker.ietf.org/doc/html/rfc4632#section-3.1)
- `hostnum` is a whole number that can be represented as a binary integer with no more than the number of digits remaining in the address after the given prefix.
- `newbits` is the number of additional bits with which to extend the prefix. For example, if given a prefix ending in /16 and a newbits value of 4, the resulting subnet address will have length /20.
- `netnum` is a whole number that can be represented as a binary integer with no more than newbits binary digits, which will be used to populate the additional bits added to the prefix.
- `hostnum` is a whole number that can be represented as a binary integer with
no more than the number of digits remaining in the address after the given
prefix.
- `newbits` is the number of additional bits with which to extend the prefix.
For example, if given a prefix ending in /16 and a newbits value of 4, the
resulting subnet address will have length /20.
- `netnum` is a whole number that can be represented as a binary integer with no
more than newbits binary digits, which will be used to populate the additional
bits added to the prefix.

## Usage

Specify the `cidrfunc` calculation type in the composition function input.

Valid values are as follows:
```

```yaml
- cidrhost
- cidrnetmask
- cidrsubnet
- cidrsubnets
- cidrsubnetloop
- multiprefixloop
```
Specify a custom `outputfield` in the function input parameters
when the output should appear at a different path
than the respective `status.atFunction.cidr` sub field default path.

Specify a custom `outputfield` in the function input parameters when the output
should appear at a different path than the respective `status.atFunction.cidr`
sub field default path.

All `cidrfunc` IP Network Functions require a CIDR `prefix` as input.
Provide the `prefix` directly in the
function input or specify a `prefixfield` in the XR where
the function shall pick up the `prefix` value.

Function input field names ending in `field` indicate that
the function shall read the field path value from the specified
field path in the XR.
Provide the `prefix` directly in the function input or specify a `prefixfield`
in the XR where the function shall pick up the `prefix` value.

Function input field names ending in `field` indicate that the function shall
read the field path value from the specified field path in the XR.

### cidrhost

The `cidrhost cidrfunc` requires a `hostnum` or `hostnumfield` as
function input. `hostnum` is an integer.

### cidrnetmask
The `cidrnetmask cidrfunc` does not require additional parameters
beyond the `prefix`. The `prefix` can be read from an XR field
when the `prefixField` path is specified in the function input
instead of a `prefix` value.

The `cidrnetmask cidrfunc` does not require additional parameters beyond the
`prefix`. The `prefix` can be read from an XR field when the `prefixField` path
is specified in the function input instead of a `prefix` value.

### cidrsubnet
The `cidrhost cidrsubnet` reauires a `netnum` or `netnumfield`,
and a `newbits` or `newbitsfield` as function input.

The `cidrhost cidrsubnet` requires a `netnum` or `netnumfield`, and a `newbits`
or `newbitsfield` as function input.

`netNum` is an integer.
`newBits` is one integer in an array of integers.

### cidrsubnets
The `cidrhost cidrsubnets` reauires a `newBits`
or `newBitsField` as function input.

The `cidrhost cidrsubnets` requires a `newBits` or `newBitsField` as function
input.

`newBits` is an array of integers.

### cidrsubnetloop

The `cidrhost cidrsubnetloop` reauires the following input fields.

- `newBits` (integer array) or `newBitsField`
- `netNumCount` (integer) or `netNumCountField`
- `netNumItems` (string array) or `netNumItemsField`
- `offset` or `offsetfield`
** netNumCount and netNumItems are mutually exclusive **

**`netNumCount` and `netNumItems` are mutually exclusive**

The `cidrsubnetloop` wrapper calculates `cidrsubnet` CIDRs using
the `prefix` and `newBits` parameters as input. It performs the
Expand All @@ -105,7 +126,27 @@ iteration from `iteration`+`offset`. The iterations are either from
0 to `netNumCount` -1 or from 0 to number of items in `netNumItemsCount`
or their respective values from their XR field references.

### multiprefixloop

This is an additional convenience function that takes a list of objects, each
describing a cidr prefix to split and returns the result as a
`map[string][]string` key'd on the prefix for that block.

It is most useful for scenarios where your composition requires multiple cidr
prefixes, such as splitting VPC additional CIDRs for subnet creation.

The `multiprefixloop` function requires a list of inputs with each input
containing:

- `prefix` The CIDR prefix to create subnets for
- `newBits` An integer array defining how to split the prefix
- `offset` An optional bit size to start the subnet range after

If `offset` is specified, this is prepended to the `newBits` field immediately
before calculations and then removed after the calculation is completed.

## Testing The Function

Clone the repo. Run `make debug` and in a second terminal run `make render`
and examine the output. Corresponding compositions and XR yaml can be
found in the `examples` folder.
and examine the output. Corresponding compositions and XR yaml can be found in
the `examples` folder.
4 changes: 2 additions & 2 deletions apis/composition.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ spec:
input:
apiVersion: cidr.fn.crossplane.io/v1beta1
kind: Parameters
cidrFunc: spec.parameters.cidrFunc
cidrFuncField: spec.parameters.cidrFunc
prefixField: spec.parameters.cidrBlock
newBitsField: spec.parameters.newBits
netNumItemsField: spec.parameters.azs
hostNumField: spec.parameters.hostNum
offsetField: spec.parameters.offset
outputField: spec.parameters.output
multiPrefixField: spec.parameters.subnets
12 changes: 12 additions & 0 deletions apis/definition.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,18 @@ spec:
- cidrhost
- cidrnetmask
- cidrsubnetloop
- multiprefixloop
subnets:
type: array
items:
type: object
properties:
prefix:
type: string
newBits:
type: array
items:
type: integer
cidrBlock:
type: string
newBits:
Expand Down
1 change: 0 additions & 1 deletion examples/xr-cidrhost.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,3 @@ spec:
cidrFunc: cidrhost
cidrBlock: 10.0.0.0/20
hostNum: 111
output: status.atFunction.cidr.hostAddress
1 change: 0 additions & 1 deletion examples/xr-cidrnetmask.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,3 @@ spec:
parameters:
cidrFunc: cidrnetmask
cidrBlock: 172.16.0.0/12
output: status.atFunction.cidr.netmask
1 change: 0 additions & 1 deletion examples/xr-cidrsubnet.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,3 @@ spec:
newBits:
- 8
netNum: 3
output: status.atFunction.cidr.subnet-a
20 changes: 20 additions & 0 deletions examples/xr-multicidrsubnetsloop.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: platform.upbound.io/v1alpha1
kind: XCIDR
metadata:
name: cidr-multiprefixloop
spec:
parameters:
cidrFunc: multiprefixloop
subnets:
- prefix: 10.0.0.0/20
newBits:
- 8
- 4
- 2
- prefix: 127.0.0.0/20
newBits: [
4, 4, 4,
4, 4, 4,
5, 5, 5,
5, 5, 5,
]
Loading
Loading