Skip to content

Commit

Permalink
Support for full netplan spec
Browse files Browse the repository at this point in the history
This patch adds support for the complete netplan specification.
  • Loading branch information
akutz committed Nov 11, 2024
1 parent 5654a42 commit 95ba97b
Show file tree
Hide file tree
Showing 20 changed files with 6,238 additions and 225 deletions.
1 change: 1 addition & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ issues:
exclude-dirs:
- external
- pkg/util/cloudinit/schema
- pkg/util/netplan/schema
exclude-files:
- ".*generated.*\\.go"
exclude:
Expand Down
1 change: 1 addition & 0 deletions hack/quicktype/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
node_modules/
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) 2024 VMware, Inc. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

FROM node:20 AS build
WORKDIR /quicktype

Expand All @@ -10,9 +13,9 @@ COPY --from=build /quicktype /quicktype
WORKDIR /output
CMD [ \
"/quicktype/node_modules/quicktype/dist/index.js", \
"--src", "/schema-cloud-config-v1.json", \
"--src", "/schema.json", \
"--src-lang", "schema", \
"--out", "/output/cloudconfig.go", \
"--out", "/output/schema.go", \
"--lang", "go", \
"--package", "schema" \
]
130 changes: 130 additions & 0 deletions hack/quicktype/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Copyright (c) 2024 VMware, Inc. All Rights Reserved.
# SPDX-License-Identifier: Apache-2.0

# Required vars
SCHEMA_IN ?=
OUTPUT_GO ?=
TOOLS_DIR ?=
QUICK_DIR ?=
START_TYP ?=

# If you update this file, please follow
# https://suva.sh/posts/well-documented-makefiles

# Ensure Make is run with bash shell as some syntax below is bash-specific
SHELL := /usr/bin/env bash

.DEFAULT_GOAL := help

# Get the information about the platform on which the tools are built/run.
GOHOSTOS := $(shell go env GOHOSTOS)
GOHOSTARCH := $(shell go env GOHOSTARCH)
GOHOSTOSARCH := $(GOHOSTOS)_$(GOHOSTARCH)

# Directories.
BIN_DIR := bin
TOOLS_BIN_DIR := $(TOOLS_DIR)/bin/$(GOHOSTOSARCH)
export PATH := $(abspath $(BIN_DIR)):$(abspath $(TOOLS_BIN_DIR)):$(PATH)

# Binaries.
QUICKTYPE := $(QUICK_DIR)/node_modules/.bin/quicktype
GOIMPORTS := $(TOOLS_BIN_DIR)/goimports

# Images.
QUICKTYPE_IMAGE_NAME := vmop-quicktype
QUICKTYPE_IMAGE_VERSION := latest
QUICKTYPE_IMAGE ?= $(QUICKTYPE_IMAGE_NAME):$(QUICKTYPE_IMAGE_VERSION)

# CRI_BIN is the path to the container runtime binary.
ifeq (,$(strip $(GITHUB_RUN_ID)))
# Prefer podman locally.
CRI_BIN := $(shell command -v podman 2>/dev/null || command -v docker 2>/dev/null)
else
# Prefer docker in GitHub actions.
CRI_BIN := $(shell command -v docker 2>/dev/null || command -v podman 2>/dev/null)
endif
export CRI_BIN

# Select how to run quicktype.
ifeq (,$(shell command -v npm))
QUICKTYPE_METHOD ?= $(CRI_BIN)
endif

# Tooling binaries
GOIMPORTS := $(TOOLS_BIN_DIR)/goimports


## --------------------------------------
## Help
## --------------------------------------

help: ## Display this help
@awk 'BEGIN {FS = ":.*##"; printf "\nUsage:\n make \033[36m<target>\033[0m\n"} /^[a-zA-Z_-]+:.*?##/ { printf " \033[36m%-15s\033[0m %s\n", $$1, $$2 } /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST)


## --------------------------------------
## Tooling Binaries
## --------------------------------------

TOOLING_BINARIES := $(GOIMPORTS)
tools: $(TOOLING_BINARIES) ## Build tooling binaries
$(TOOLING_BINARIES):
make -C $(TOOLS_DIR) $(@F)


## --------------------------------------
## Image
## --------------------------------------

.PHONY: image-build
image-build: ## Build the container images
cd $(QUICK_DIR) && $(CRI_BIN) build -t $(QUICKTYPE_IMAGE) -f Dockerfile


## --------------------------------------
## Binaries
## --------------------------------------

quicktype: $(QUICKTYPE) ## Install quicktype
$(QUICKTYPE): $(QUICK_DIR)/package.json
cd $(QUICK_DIR) && npm ci --user quicktype


## --------------------------------------
## Generate
## --------------------------------------

$(OUTPUT_GO): $(SCHEMA_IN) | $(GOIMPORTS)
ifeq (container,$(QUICKTYPE_METHOD))
$(OUTPUT_GO): image-build
$(CRI_BIN) run -it --rm \
-v $$(pwd):/output \
-v $$(pwd)/$(SCHEMA_IN):/schema.json \
$(QUICKTYPE_IMAGE)
mv -f schema.go $@
$(GOIMPORTS) -w $@
else
$(OUTPUT_GO): | $(QUICKTYPE)
$(QUICKTYPE) \
--src $(SCHEMA_IN) --src-lang schema \
--out $@ --lang go --package schema \
--top-level $(START_TYP)
$(GOIMPORTS) -w $@
endif

generate-go: ## Generate the go source code from the schemas
$(MAKE) $(OUTPUT_GO)


## --------------------------------------
## Cleanup
## --------------------------------------

.PHONY: clean
clean: ## Run all the clean targets
rm -f $(OUTPUT_GO)

.PHONY: clobber
clobber: ## Remove all of the tooling as well
$(MAKE) clean
rm -fr $(BIN_DIR)
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion pkg/providers/vsphere/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ const (

// NetPlanVersion points to the version used for Network config.
// For more information, please see https://cloudinit.readthedocs.io/en/latest/topics/network-config-format-v2.html
NetPlanVersion = 2
NetPlanVersion = int64(2)

PCIPassthruMMIOOverrideAnnotation = pkg.VMOperatorKey + "/pci-passthru-64bit-mmio-size"
PCIPassthruMMIOExtraConfigKey = "pciPassthru.use64bitMMIO" //nolint:gosec
Expand Down
102 changes: 45 additions & 57 deletions pkg/providers/vsphere/network/netplan.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,87 +7,75 @@ import (
"strings"

"github.com/vmware-tanzu/vm-operator/pkg/providers/vsphere/constants"
"github.com/vmware-tanzu/vm-operator/pkg/util/netplan"
"github.com/vmware-tanzu/vm-operator/pkg/util/ptr"
)

// Netplan representation described in https://via.vmw.com/cloud-init-netplan // FIXME: 404.
type Netplan struct {
Version int `json:"version,omitempty"`
Ethernets map[string]NetplanEthernet `json:"ethernets,omitempty"`
}

type NetplanEthernet struct {
Match NetplanEthernetMatch `json:"match,omitempty"`
SetName string `json:"set-name,omitempty"`
Dhcp4 bool `json:"dhcp4,omitempty"`
Dhcp6 bool `json:"dhcp6,omitempty"`
Addresses []string `json:"addresses,omitempty"`
Gateway4 string `json:"gateway4,omitempty"`
Gateway6 string `json:"gateway6,omitempty"`
MTU int64 `json:"mtu,omitempty"`
Nameservers NetplanEthernetNameserver `json:"nameservers,omitempty"`
Routes []NetplanEthernetRoute `json:"routes,omitempty"`
}

type NetplanEthernetMatch struct {
MacAddress string `json:"macaddress,omitempty"`
}

type NetplanEthernetNameserver struct {
Addresses []string `json:"addresses,omitempty"`
Search []string `json:"search,omitempty"`
}

type NetplanEthernetRoute struct {
To string `json:"to"`
Via string `json:"via"`
Metric int32 `json:"metric,omitempty"`
}

func NetPlanCustomization(result NetworkInterfaceResults) (*Netplan, error) {
netPlan := &Netplan{
func NetPlanCustomization(result NetworkInterfaceResults) (*netplan.Network, error) {
netPlan := &netplan.Network{
Version: constants.NetPlanVersion,
Ethernets: make(map[string]NetplanEthernet),
Ethernets: make(map[string]netplan.Ethernet),
}

for _, r := range result.Results {
npEth := NetplanEthernet{
Match: NetplanEthernetMatch{
MacAddress: NormalizeNetplanMac(r.MacAddress),
npEth := netplan.Ethernet{
Match: &netplan.Match{
Macaddress: ptr.To(NormalizeNetplanMac(r.MacAddress)),
},
SetName: r.GuestDeviceName,
MTU: r.MTU,
Nameservers: NetplanEthernetNameserver{
SetName: &r.GuestDeviceName,
MTU: &r.MTU,
Nameservers: &netplan.Nameserver{
Addresses: r.Nameservers,
Search: r.SearchDomains,
},
}

npEth.Dhcp4 = r.DHCP4
npEth.Dhcp6 = r.DHCP6
npEth.Dhcp4 = &r.DHCP4
npEth.Dhcp6 = &r.DHCP6

if !npEth.Dhcp4 {
for _, ipConfig := range r.IPConfigs {
if !*npEth.Dhcp4 {
for i := range r.IPConfigs {
ipConfig := r.IPConfigs[i]
if ipConfig.IsIPv4 {
if npEth.Gateway4 == "" {
npEth.Gateway4 = ipConfig.Gateway
if npEth.Gateway4 == nil || *npEth.Gateway4 == "" {
npEth.Gateway4 = &ipConfig.Gateway
}
npEth.Addresses = append(npEth.Addresses, ipConfig.IPCIDR)
npEth.Addresses = append(
npEth.Addresses,
netplan.Address{
String: &ipConfig.IPCIDR,
},
)
}
}
}
if !npEth.Dhcp6 {
for _, ipConfig := range r.IPConfigs {
if !*npEth.Dhcp6 {
for i := range r.IPConfigs {
ipConfig := r.IPConfigs[i]
if !ipConfig.IsIPv4 {
if npEth.Gateway6 == "" {
npEth.Gateway6 = ipConfig.Gateway
if npEth.Gateway6 == nil || *npEth.Gateway6 == "" {
npEth.Gateway6 = &ipConfig.Gateway
}
npEth.Addresses = append(npEth.Addresses, ipConfig.IPCIDR)
npEth.Addresses = append(
npEth.Addresses,
netplan.Address{
String: &ipConfig.IPCIDR,
},
)
}
}
}

for _, route := range r.Routes {
npEth.Routes = append(npEth.Routes, NetplanEthernetRoute(route))
for i := range r.Routes {
route := r.Routes[i]
npEth.Routes = append(
npEth.Routes,
netplan.Route{
To: &route.To,
Metric: ptr.To(int64(route.Metric)),
Via: &route.Via,
},
)
}

netPlan.Ethernets[r.Name] = npEth
Expand Down
Loading

0 comments on commit 95ba97b

Please sign in to comment.