From 00901fb62feae4a78750460b43886672df90b686 Mon Sep 17 00:00:00 2001 From: Enrique Llorente Date: Mon, 6 May 2024 12:26:34 +0200 Subject: [PATCH] WIP: Add generator Signed-off-by: Enrique Llorente --- .github/workflows/ci.yaml | 10 +- .gitignore | 3 + Cargo.lock | 330 ++ Cargo.toml | 18 + Makefile | 48 + hack/boilerplate.go.txt | 16 + hack/controller-gen.sh | 3 + hack/download-nmstate-e2e-artifacts.sh | 20 + src/bin/nmstate-kubernetes-go-apigen/main.rs | 1067 ++++++ test/api/types_test.go | 135 + test/crd/Makefile | 5 + test/crd/groupversion_info.go | 36 + test/crd/nmstate.io_clusternetworkstate.yaml | 2657 ++++++++++++++ test/crd/setup-testenv.sh | 28 + test/crd/types.go | 38 + test/crd/types_test.go | 126 + test/crd/zz_generated.deepcopy.go | 99 + test/go.mod | 62 + test/go.sum | 192 + v2/.golangci.yml | 108 + v2/encoding.go | 222 ++ v2/go.mod | 21 + v2/go.sum | 64 + v2/zz_generated.deepcopy.go | 3357 ++++++++++++++++++ v2/zz_generated.types.go | 2854 +++++++++++++++ 25 files changed, 11510 insertions(+), 9 deletions(-) create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 Makefile create mode 100644 hack/boilerplate.go.txt create mode 100755 hack/controller-gen.sh create mode 100755 hack/download-nmstate-e2e-artifacts.sh create mode 100644 src/bin/nmstate-kubernetes-go-apigen/main.rs create mode 100644 test/api/types_test.go create mode 100644 test/crd/Makefile create mode 100644 test/crd/groupversion_info.go create mode 100644 test/crd/nmstate.io_clusternetworkstate.yaml create mode 100755 test/crd/setup-testenv.sh create mode 100644 test/crd/types.go create mode 100644 test/crd/types_test.go create mode 100644 test/crd/zz_generated.deepcopy.go create mode 100644 test/go.mod create mode 100644 test/go.sum create mode 100644 v2/.golangci.yml create mode 100644 v2/encoding.go create mode 100644 v2/go.mod create mode 100644 v2/go.sum create mode 100644 v2/zz_generated.deepcopy.go create mode 100644 v2/zz_generated.types.go diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 08b115d..61b4530 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,3 +1,4 @@ +name: CI on: pull_request: types: [opened, synchronize, reopened] @@ -6,15 +7,6 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: install deps - run: | - #!/bin/bash -e - apt-get update - apt-get install -y make git curl gcc - - name: Install GH CLI - uses: dev-hanz-ops/install-gh-cli-action@v0.1.0 - with: - gh-cli-version: 2.32.0 # optional, see action.yml for current default - uses: actions-rust-lang/setup-rust-toolchain@v1 - uses: actions/setup-go@v5 with: diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6671c58 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.output +target +.k8s diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..c4718df --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,330 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d96bd03f33fe50a863e394ee9718a706f988b9079b20c3784fb726e7678b62fb" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anyhow" +version = "1.0.82" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f538837af36e6f6a9be0faa67f9a314f8119e4e4b5867c6ab40ed60360142519" + +[[package]] +name = "clap" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bc066a67923782aa8515dbaea16946c5bcc5addbd668bb80af688e53e548a0" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98cc8fbded0c607b7ba9dd60cd98df59af97e84d24e49c8557331cfc26d301ce" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "convert_case" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "env_filter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +dependencies = [ + "log", + "regex", +] + +[[package]] +name = "env_logger" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b35839ba51819680ba087cd351788c9a3c476841207e0b8cee0b04722343b9" +dependencies = [ + "anstream", + "anstyle", + "env_filter", + "humantime", + "log", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "log" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[package]] +name = "nmstate-kubernetes-go-apigen" +version = "0.0.1" +dependencies = [ + "anyhow", + "clap", + "convert_case", + "env_logger", + "log", + "proc-macro2", + "regex", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.52" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..863cd43 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "nmstate-kubernetes-go-apigen" +edition = "2018" +rust-version = "1.58" +version = "0.0.1" + +[[bin]] +name = "nmstate-kubernetes-go-apigen" + +[dependencies] +anyhow = "1.0.82" +log = "0.4.21" +env_logger = "0.11.3" +regex = "1.10.2" +clap = { version = "4.5.4", features = ["cargo", "derive"] } +syn = {version = "2.0.39", features = ["visit", "extra-traits", "full"]} +convert_case = "0.6.0" +proc-macro2 = "1.0.56" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f617460 --- /dev/null +++ b/Makefile @@ -0,0 +1,48 @@ +.ONESHELL: # Applies to every targets in the file! +.SHELLFLAGS += -e + +SHELL := /bin/bash +OUTPUT_DIR=${CURDIR}/.output + +NMSTATE_VERSION ?= 2.2.27 +NMSTATE_REPO ?= https://github.com/nmstate/nmstate +NMSTATE_SOURCE_TARBALL_URL ?= https://github.com/nmstate/nmstate/archive/refs/tags/v${NMSTATE_VERSION}.tar.gz +export NMSTATE_SOURCE_INSTALL_DIR ?= ${OUTPUT_DIR}/nmstate-${NMSTATE_VERSION} +export NMSTATE_E2E_DUMP ?= ${OUTPUT_DIR}/nmstate-${NMSTATE_VERSION}-e2e-dump + +GOLANGCI_LINT_VERSION ?= v1.52.2 +CONTROLLER_GEN_VERSION ?= v0.14.0 + +GO_HEADER=${CURDIR}/hack/boilerplate.go.txt +GO_GENERATE_OUTPUT=v2/ +GO_JUNIT_REPORT=$(shell go env GOPATH)/bin/go-junit-report -set-exit-code + +${NMSTATE_E2E_DUMP}: + hack/download-nmstate-e2e-artifacts.sh v${NMSTATE_VERSION} ${NMSTATE_SOURCE_INSTALL_DIR} ${NMSTATE_E2E_DUMP} + +${NMSTATE_SOURCE_INSTALL_DIR}: + mkdir -p ${NMSTATE_SOURCE_INSTALL_DIR} + git clone ${NMSTATE_REPO} -b v${NMSTATE_VERSION} ${NMSTATE_SOURCE_INSTALL_DIR} + +.PHONY: test-api +test-api: generate ${NMSTATE_E2E_DUMP} + cd test/api + go test 2>&1 | $(GO_JUNIT_REPORT) -set-exit-code -iocopy -out $(OUTPUT_DIR)/junit.api.xml + +test-crd: generate ${NMSTATE_E2E_DUMP} + cd test/crd + GOFLAGS=-mod=mod go run sigs.k8s.io/controller-tools/cmd/controller-gen@${CONTROLLER_GEN_VERSION} object:headerFile="${GO_HEADER}" paths="." + GOFLAGS=-mod=mod go run sigs.k8s.io/controller-tools/cmd/controller-gen@${CONTROLLER_GEN_VERSION} crd paths="." output:crd:artifacts:config=. + go test 2>&1 | $(GO_JUNIT_REPORT) -set-exit-code -iocopy -out $(OUTPUT_DIR)/junit.crd.xml + +test: test-api test-crd + +.PHONY: generate +generate: ${NMSTATE_SOURCE_INSTALL_DIR} + cargo run -- --input-dir=${NMSTATE_SOURCE_INSTALL_DIR}/rust/src/lib --output-file=${CURDIR}/v2/zz_generated.types.go --header-file=${GO_HEADER} + GOFLAGS=-mod=mod go run sigs.k8s.io/controller-tools/cmd/controller-gen@${CONTROLLER_GEN_VERSION} object:headerFile="${GO_HEADER}" paths="${CURDIR}/v2" + +.PHONY: lint +lint: generate + cd ${GO_GENERATE_OUTPUT} + go run github.com/golangci/golangci-lint/cmd/golangci-lint@${GOLANGCI_LINT_VERSION} run diff --git a/hack/boilerplate.go.txt b/hack/boilerplate.go.txt new file mode 100644 index 0000000..0c9fb07 --- /dev/null +++ b/hack/boilerplate.go.txt @@ -0,0 +1,16 @@ +/* +Copyright The NMState Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + diff --git a/hack/controller-gen.sh b/hack/controller-gen.sh new file mode 100755 index 0000000..0ed40e7 --- /dev/null +++ b/hack/controller-gen.sh @@ -0,0 +1,3 @@ +#!/bin/bash -e + +GOFLAGS=-mod=mod go run sigs.k8s.io/controller-tools/cmd/controller-gen@v0.14.0 $@ diff --git a/hack/download-nmstate-e2e-artifacts.sh b/hack/download-nmstate-e2e-artifacts.sh new file mode 100755 index 0000000..d47bdd5 --- /dev/null +++ b/hack/download-nmstate-e2e-artifacts.sh @@ -0,0 +1,20 @@ +#!/bin/bash -xe + +tag=$1 +nmstate_dir=$2 +output_dir=$3 + +( + cd $nmstate_dir + # Get the SHA from last commit before tag + sha=$(git rev-list -n 1 $tag~1) + + # Get the first commit from the PR that generated the tag SHA + pr_sha=$(gh pr list --state merged --search $sha --json commits |jq -r .[0].commits[0].oid) + + # Take the first run from that PR commit + run_id=$(gh run list -c $pr_sha --json databaseId -q ".[0].databaseId") + + # Download artifacts from that run + gh run download -D $output_dir -p "*dump*" $run_id +) diff --git a/src/bin/nmstate-kubernetes-go-apigen/main.rs b/src/bin/nmstate-kubernetes-go-apigen/main.rs new file mode 100644 index 0000000..b6072c8 --- /dev/null +++ b/src/bin/nmstate-kubernetes-go-apigen/main.rs @@ -0,0 +1,1067 @@ +// SPDX-License-Identifier: Apache-2.0 +use std::collections::{HashMap, HashSet}; +use std::fs::File; +use std::io::Read; +use std::io::Write; +use std::process::Command; + +use syn::visit::{self, Visit}; +use syn::{Expr, ItemEnum, ItemStruct, Lit, Meta, Variant}; + +use convert_case::{Boundary, Case, Casing, Converter}; + +use clap::Parser; + +use log::{error, info}; +use regex::RegexSet; + +use anyhow::{Context, Error}; + +const OMITEMPTY: &str = "omitempty"; + +struct GolangEmitter { + header: String, + output: String, +} + +struct RustVisitor { + skip_structs: RegexSet, + skip_variants: HashMap<&'static str, HashSet<&'static str>>, + skip_fields: HashMap<&'static str, HashSet<&'static str>>, + current_struct: Option, + current_enum: Option, + ovs_bridge_interface: Option, + linux_bridge_interface: Option, + emitter: GolangEmitter, +} + +#[derive(Default, Clone)] +struct FieldContext { + name: String, + is_optional: bool, + is_number_or_string: bool, + docs: String, +} + +#[derive(Default, Clone)] +struct StructContext { + name: String, + serde_rename_all: Option, + docs: String, +} + +#[derive(Default, Clone)] +struct EnumContext { + name: String, + serde_rename_all: Option, + repr: Option, + docs: String, + variants: Vec, + is_number_or_string: bool, + has_other_variant: bool, +} + +#[derive(Default, Clone)] +struct VariantContext { + enum_name: String, + enum_serde_rename_all: Option, + enum_is_number_or_string: bool, + name: String, + serde_rename: Option, + serde_alias: Option, + docs: String, + u8_discriminant: Option, +} + +#[derive(Parser)] +#[command(version, about, long_about = None)] +struct Arguments { + #[arg(long, required = true)] + input_dir: String, + #[arg(long, required = true)] + output_file: String, + #[arg(long, required = true)] + header_file: String, +} + +fn main() { + let mut log_builder = env_logger::Builder::new(); + log_builder.filter(None, log::LevelFilter::Info); + log_builder.init(); + if let Err(e) = try_main() { + error!("{:#}", e); + std::process::exit(1); + } +} + +fn try_main() -> Result<(), Error> { + let args = Arguments::parse(); + info!("input_dir: {}", args.input_dir); + info!("output_file: {}", args.output_file); + info!("header_file: {}", args.header_file); + + let mut visitor = RustVisitor { + skip_structs: RegexSet::new([ + r"Merged.*", + "InterfaceIpv4", + "InterfaceIpv6", + "FeatureVisitor", + "IntegerOrString", + ])?, + skip_fields: HashMap::from([ + ("_other", HashSet::new()), + ("prop_list", HashSet::new()), + ("base", HashSet::new()), + ("slaves", HashSet::new()), + ( + "name", + HashSet::from(["LinuxBridgePortConfig", "OVSBridgePortConfig"]), + ), + ( + "vlan", + HashSet::from(["LinuxBridgePortConfig", "OVSBridgePortConfig"]), + ), + ("options", HashSet::from(["OVSBridgeConfig"])), + ("ports", HashSet::from(["OVSBridgeConfig"])), + ]), + skip_variants: HashMap::from([ + ("LinuxBridge", HashSet::from(["Interface"])), + ("OvsBridge", HashSet::from(["Interface"])), + ("Dummy", HashSet::from(["Interface"])), + ("Unknown", HashSet::from(["Interface"])), + ("Loopback", HashSet::from(["Interface"])), + ("Xfrm", HashSet::from(["Interface"])), + ]), + current_struct: None, + current_enum: None, + linux_bridge_interface: None, + ovs_bridge_interface: None, + emitter: GolangEmitter { + header: std::fs::read_to_string(&args.header_file) + .context(format!("failed reading header file: {}", args.header_file))?, + output: String::new(), + }, + }; + + visitor.visit_files( + args.input_dir, + vec![ + "lldp.rs", + "ieee8021x.rs", + "mptcp.rs", + "ovs.rs", + "iface.rs", + "dns.rs", + "route.rs", + "route_rule.rs", + "ip.rs", + "hostname.rs", + "ifaces/bond.rs", + "ifaces/dummy.rs", + "ifaces/linux_bridge.rs", + "ifaces/bridge_vlan.rs", + "ifaces/ovs.rs", + "ifaces/vlan.rs", + "ifaces/vxlan.rs", + "ifaces/mac_vlan.rs", + "ifaces/mac_vtap.rs", + "ifaces/vrf.rs", + "ifaces/infiniband.rs", + "ifaces/loopback.rs", + "ifaces/sriov.rs", + "ifaces/ethtool.rs", + "ifaces/base.rs", + "ifaces/ethernet.rs", + "ifaces/macsec.rs", + "ifaces/ipsec.rs", + "ifaces/hsr.rs", + "net_state.rs", + "ovn.rs", + "dispatch.rs", + ], + )?; + + let mut output_file = File::create(&args.output_file) + .context(format!("failed creating output file {}", &args.output_file))?; + write!(output_file, "{}", visitor.emitter.output)?; + Command::new("go") + .arg("fmt") + .arg(args.output_file) + .output() + .expect("failed to format generated api"); + Ok(()) +} + +impl<'ast> Visit<'ast> for RustVisitor { + fn visit_item_struct(&mut self, node: &'ast ItemStruct) { + if self.should_skip_struct(node) { + return; + } + let visited_struct = StructContext { + name: rust_name_to_golang_name(node.ident.to_string().as_str()), + serde_rename_all: self.parse_serde_rename_all(&node.attrs), + docs: self.parse_docs(&node.attrs), + }; + match visited_struct.name.as_str() { + "LinuxBridgeInterface" => { + self.linux_bridge_interface = Some(visited_struct.clone()); + } + "OVSBridgeInterface" => { + self.ovs_bridge_interface = Some(visited_struct.clone()); + } + _ => { + self.emitter.emit_struct_begin(&visited_struct); + self.current_struct = Some(visited_struct.clone()); + + visit::visit_item_struct(self, node); + + self.emitter.emit_struct_end(); + self.current_struct = None; + } + } + } + + fn visit_item_enum(&mut self, node: &'ast ItemEnum) { + let mut current_enum = EnumContext { + name: rust_name_to_golang_name(&node.ident.to_string()), + serde_rename_all: self.parse_serde_rename_all(&node.attrs), + repr: self.parse_repr_attribute(&node.attrs), + docs: self.parse_docs(&node.attrs), + variants: Vec::::new(), + has_other_variant: false, + is_number_or_string: node.ident.to_string().as_str() + == "LinuxBridgeMulticastRouterType", + }; + self.current_enum = Some(current_enum.clone()); + match current_enum.name.as_str() { + "Interface" => { + self.emitter.emit_struct_begin(&StructContext { + name: current_enum.name, + docs: current_enum.docs, + serde_rename_all: None, + }); + + self.emitter.output.push_str( + r#" + BaseInterface `json:",omitempty"` + *BridgeInterface `json:",omitempty"` +"#, + ); + visit::visit_item_enum(self, node); + self.emitter.emit_struct_end(); + } + "BridgePortTrunkTag" | "LldpNeighborTlv" => { + self.emitter.emit_struct_begin(&StructContext { + name: current_enum.name, + docs: current_enum.docs, + serde_rename_all: None, + }); + visit::visit_item_enum(self, node); + self.emitter.emit_struct_end(); + } + _ => { + // It needs to visit the enum variants first to recollect them + // at current_enum.variants and compose the kubebuilder + // enum validation annotation + visit::visit_item_enum(self, node); + // Update current_enum with latest changes, maybe this should + // be handled by a reference or a Box or the like so we don't + // have to copy it again. + current_enum = self.current_enum.clone().unwrap(); + self.emitter.emit_enum_begin(¤t_enum); + if let Some(current_enum) = self.current_enum.clone() { + for variant in current_enum.variants { + self.emitter.emit_enum_variant(&variant); + } + } + self.emitter.emit_enum_end(current_enum.name); + } + } + self.current_enum = None; + } + + fn visit_variant(&mut self, node: &'ast Variant) { + if self.should_skip_variant(node) { + return; + } + if let Some(current_enum) = self.current_enum.clone() { + let variant_ctx = &mut VariantContext { + enum_name: current_enum.name.clone(), + enum_serde_rename_all: current_enum.serde_rename_all.clone(), + enum_is_number_or_string: current_enum.is_number_or_string, + name: rust_name_to_golang_name(&node.ident.to_string()), + serde_rename: self.parse_serde_rename(&node.attrs), + serde_alias: self.parse_serde_alias(&node.attrs), + docs: self.parse_docs(&node.attrs), + u8_discriminant: None, + }; + match current_enum.name.as_str() { + "Interface" | "LldpNeighborTlv" => { + let json_name = "".to_string(); + self.emit_variant_as_field(json_name, variant_ctx, node); + } + "BridgePortTrunkTag" => { + let json_name = to_kebab_case(&node.ident.to_string()); + self.emit_variant_as_field(json_name, variant_ctx, node); + } + + _ => { + if let Some(discriminant) = node.discriminant.clone() { + let (_, expr) = discriminant; + if let Expr::Lit(literal_discriminant) = expr { + if let Lit::Int(int_discriminant) = literal_discriminant.lit { + if let Ok(u8_discriminant) = int_discriminant.base10_parse::() { + variant_ctx.u8_discriminant = Some(u8_discriminant); + } + } + } + } + if let Some(enum_ctx) = &mut self.current_enum { + if variant_ctx.name == "Other" { + enum_ctx.has_other_variant = true + } else { + enum_ctx.variants.push(variant_ctx.clone()); + } + } + } + } + } + } + + fn visit_field(&mut self, node: &'ast syn::Field) { + if self.should_skip_field(node) { + return; + } + + if let Some(current_struct) = self.current_struct.clone() { + if let Some(field_ident) = node.clone().ident { + let mut field_context = FieldContext { + // Rename "IfaceType" to "Type" since the context + // is already the interface + name: if field_ident == "iface_type" && current_struct.name == "BaseInterface" { + "type".to_string() + } else { + field_ident.to_string() + }, + is_number_or_string: self + .has_serde_deserialize_with_number_or_string(&node.attrs), + // Force optional if serde skip_serializating annotation + // is found, so fields are not passed to nmstate if not + // set + is_optional: self.has_serde_skip_serialization(&node.attrs) + || (current_struct.name != "LldpConfig" + && current_struct.name.starts_with("Lldp")), + docs: self.parse_docs(&node.attrs), + }; + + self.emitter.emit_field_begin(&field_context); + self.parse_field_type(node.clone().ty, &mut field_context); + + if let Some(renamed_field_name) = self.parse_serde_rename(&node.attrs) { + field_context.name = renamed_field_name; + } else if let Some(struct_serde_rename_all) = current_struct.serde_rename_all { + if struct_serde_rename_all == "kebab-case" { + field_context.name = to_kebab_case(&field_context.name); + } else if struct_serde_rename_all == "snake_case" { + field_context.name = to_snake_case(&field_context.name); + } else if struct_serde_rename_all == "lowercase" { + field_context.name = field_context.name.to_lowercase(); + } + } + let mut json_tag = vec![field_context.name.clone()]; + if self + .parse_serde_skip_serialization_if(&node.attrs) + .is_some() + || field_context.is_optional + || field_context.name == "dns-resolver" + || field_context.name == "route-rules" + || field_context.name == "routes" + || field_context.name == "interfaces" + || field_context.name == "ovs-db" + || field_context.name == "ovn" + || field_context.name == "type" + || field_context.name == "state" + || field_context.name == "other" + || field_context.name == "allow-extra-address" + || field_context.name == "allow-extra-patch-ports" + || field_context.name == "route-table-id" + || field_context.name == "peer" + || (current_struct.name != "LldpConfig" + && current_struct.name.starts_with("Lldp")) + { + json_tag.push(String::from(OMITEMPTY)); + } + self.emitter.emit_json_tag(json_tag); + + self.emitter.emit_field_end(); + } + } + } +} + +impl<'ast> RustVisitor { + fn visit_files( + &mut self, + input_dir: String, + files_to_visit: Vec<&'static str>, + ) -> Result<(), anyhow::Error> { + self.emitter.emit_header(); + self.emitter.emit_package_name(String::from("v2")); + + self.emitter.output.push_str( + r#" +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) +"#, + ); + + for file_to_visit in files_to_visit { + let mut file = + File::open(format!("{}/{}", input_dir, file_to_visit)).context(format!( + "failed opening file to visit {}/{}", + input_dir, file_to_visit + ))?; + let mut content = String::new(); + file.read_to_string(&mut content)?; + let ast = syn::parse_file(&content)?; + self.visit_file(&ast); + } + if let (Some(linux_bridge_interface), Some(ovs_bridge_interface)) = ( + self.linux_bridge_interface.clone(), + self.ovs_bridge_interface.clone(), + ) { + // We have to conglomerate ovs and linux bridge into the same + // structure to make k8s crd generator happy + self.emitter + .emit_bridge_interface(&linux_bridge_interface, &ovs_bridge_interface); + } + + Ok(()) + } + + fn should_skip_struct(&self, node: &'ast ItemStruct) -> bool { + self.skip_structs.is_match(&node.ident.to_string()) + } + + fn should_skip_variant(&self, node: &'ast Variant) -> bool { + if let Some(current_enum) = self.current_enum.clone() { + if let Some(skip_variant_enums) = + self.skip_variants.get(node.ident.to_string().as_str()) + { + skip_variant_enums.is_empty() + || skip_variant_enums.contains(current_enum.name.as_str()) + } else { + false + } + } else { + true + } + } + + fn should_skip_field(&mut self, node: &'ast syn::Field) -> bool { + if self.parse_serde_attribute(&node.attrs, "skip").is_some() { + return true; + } + if let Some(current_struct) = self.current_struct.clone() { + if let Some(node_ident) = node.ident.clone() { + if let Some(skip_field_structs) = + self.skip_fields.get(node_ident.to_string().as_str()) + { + return skip_field_structs.is_empty() + || skip_field_structs.contains(current_struct.name.as_str()); + } else { + return false; + } + } + } + true + } + + fn emit_variant_as_field( + &mut self, + json_name: String, + variant_ctx: &VariantContext, + node: &'ast Variant, + ) { + if !json_name.is_empty() { + self.emitter.emit_field_begin(&FieldContext { + name: variant_ctx.name.clone(), + docs: variant_ctx.docs.clone(), + is_number_or_string: false, + is_optional: false, + }); + } + if let syn::Fields::Unnamed(unamed_fields) = node.fields.clone() { + if let Some(field) = unamed_fields.unnamed.first() { + self.emitter.emit_optional(); + self.parse_field_type(field.ty.clone(), &mut FieldContext::default()); + } + } + self.emitter + .emit_json_tag(vec![json_name, String::from(OMITEMPTY)]); + self.emitter.emit_field_end(); + } + + fn parse_field_type(&mut self, t: syn::Type, field_ctx: &mut FieldContext) { + match t { + syn::Type::Path(t) => self.parse_field_path_type(t, field_ctx), + _ => { + self.emitter + .emit_type_name(String::from("todo"), &mut FieldContext::default()); + } + } + } + + fn parse_field_path_type(&mut self, t: syn::TypePath, field_context: &mut FieldContext) { + if let Some(last_segment) = t.path.segments.last() { + let last_segment_name = last_segment.ident.to_string(); + if last_segment_name == "Option" || last_segment_name == "Vec" { + self.emitter + .emit_type_name(last_segment_name, field_context); + if let syn::PathArguments::AngleBracketed(ab) = last_segment.arguments.clone() { + if let Some(syn::GenericArgument::Type(gt)) = ab.args.first() { + self.parse_field_type(gt.clone(), field_context); + } + } + } else if last_segment_name == "HashMap" { + if let syn::PathArguments::AngleBracketed(ab) = last_segment.arguments.clone() { + if field_context.is_optional { + self.emitter.emit_optional(); + field_context.is_optional = false; + } + self.emitter.emit_map_begin(); + if let Some(syn::GenericArgument::Type(key)) = ab.args.first() { + self.parse_field_type(key.clone(), &mut FieldContext::default()); + } + self.emitter.emit_map_end(); + if let Some(syn::GenericArgument::Type(value)) = ab.args.last() { + // The value of other_config and external_ids + // can be int or string + if matches!(field_context.name.as_str(), "other_config" | "external_ids") { + field_context.is_number_or_string = true + } + self.parse_field_type(value.clone(), field_context); + } + } + } else { + self.emitter + .emit_type_name(last_segment_name, field_context); + } + } + } + + fn parse_serde_alias(&mut self, attributes: &Vec) -> Option { + self.parse_serde_attribute(attributes, "alias") + } + + fn parse_serde_rename(&mut self, attributes: &Vec) -> Option { + self.parse_serde_attribute(attributes, "rename") + } + + fn parse_serde_skip_serialization_if( + &mut self, + attributes: &Vec, + ) -> Option { + self.parse_serde_attribute(attributes, "skip_serializing_if") + } + + fn has_serde_skip_serialization(&mut self, attributes: &Vec) -> bool { + self.parse_serde_attribute(attributes, "skip_serializing") + .is_some() + } + + fn parse_serde_rename_all(&mut self, attributes: &Vec) -> Option { + self.parse_serde_attribute(attributes, "rename_all") + } + + fn parse_serde_deserialize_with(&mut self, attributes: &Vec) -> Option { + self.parse_serde_attribute(attributes, "deserialize_with") + } + + fn has_serde_deserialize_with_number_or_string( + &mut self, + attributes: &Vec, + ) -> bool { + match self.parse_serde_deserialize_with(attributes) { + Some(deserializer) => matches!( + deserializer.as_str(), + "crate::deserializer::option_u8_or_string" + | "crate::deserializer::option_u16_or_string" + | "crate::deserializer::option_u32_or_string" + | "crate::deserializer::option_u64_or_string" + | "crate::deserializer::option_i8_or_string" + | "crate::deserializer::option_i16_or_string" + | "crate::deserializer::option_i32_or_string" + | "crate::deserializer::option_i64_or_string" + | "parse_ipsec_iface" + ), + _ => false, + } + } + + fn parse_serde_attribute( + &mut self, + attributes: &Vec, + attribute_name: &str, + ) -> Option { + self.parse_attribute("serde", attributes, Some(attribute_name)) + } + + fn parse_repr_attribute(&mut self, attributes: &Vec) -> Option { + self.parse_attribute("repr", attributes, None) + } + + fn parse_attribute( + &mut self, + key: &str, + attributes: &Vec, + attribute_name_op: Option<&str>, + ) -> Option { + for attr in attributes { + if let syn::Meta::List(list) = attr.clone().meta { + if let Some(first_segment) = list.path.segments.first() { + if first_segment.ident == key { + let mut tokens_iter = list.tokens.into_iter(); + while let Some(token) = tokens_iter.next() { + if let proc_macro2::TokenTree::Ident(iden_token) = token { + match attribute_name_op { + Some(attribute_name) => { + if iden_token == attribute_name { + tokens_iter.next(); // = + if let Some(rename_value) = tokens_iter.next() { + return Some( + rename_value.to_string().replace('"', ""), + ); + } + return Some(String::new()); + } + } + None => { + return Some(iden_token.to_string()); + } + } + } + } + } + } + } + } + None + } + + fn parse_docs(&mut self, attributes: &Vec) -> String { + let mut docs = String::new(); + for attr in attributes { + if let Meta::NameValue(meta) = attr.meta.clone() { + if let Expr::Lit(lit) = meta.value { + if let Lit::Str(doc_str) = lit.lit { + docs.push_str(doc_str.value().as_str()); + docs.push('\n'); + } + } + } + } + docs + } +} + +impl GolangEmitter { + fn emit_enum_begin(&mut self, enum_ctx: &EnumContext) -> &mut GolangEmitter { + let enum_type = if enum_ctx.is_number_or_string { + "intstr.IntOrString" + } else if enum_ctx.repr == Some("u8".to_string()) { + "uint8" + } else { + "string" + }; + self.emit_docs(&enum_ctx.name, &enum_ctx.docs); + if enum_ctx.is_number_or_string { + self.emit_int_or_string_validation(); + } + self.emit_enum_validation(enum_ctx); + self.output.push_str("type "); + self.output.push_str(&enum_ctx.name); + self.output.push(' '); + self.output.push_str(enum_type); + self.output.push('\n'); + if enum_ctx.is_number_or_string { + self.emit_enum_int_or_string_json_encoding(enum_ctx); + } + self + } + + fn emit_enum_variant(&mut self, variant_ctx: &VariantContext) -> &mut GolangEmitter { + let name = format!("{}{}", &variant_ctx.enum_name, &variant_ctx.name); + self.emit_docs(&name, &variant_ctx.docs); + if variant_ctx.enum_is_number_or_string { + self.output.push_str("var "); + } else { + self.output.push_str("const "); + } + self.output.push_str(&name); + self.output.push_str(" = "); + self.output.push_str(&variant_ctx.enum_name); + if !variant_ctx.enum_is_number_or_string && variant_ctx.u8_discriminant.is_some() { + self.output.push('('); + self.output + .push_str(format!("{}", variant_ctx.u8_discriminant.unwrap()).as_str()); + self.output.push_str(")\n"); + } else { + if variant_ctx.enum_is_number_or_string { + self.output.push_str("(intstr.FromString(\""); + self.emit_enum_variant_string(variant_ctx); + self.output.push_str("\"))"); + } else { + self.output.push('('); + self.output.push('"'); + self.emit_enum_variant_string(variant_ctx); + self.output.push('"'); + self.output.push(')'); + } + self.output.push('\n'); + } + self + } + fn emit_enum_variant_string(&mut self, variant_ctx: &VariantContext) -> &mut GolangEmitter { + if let Some(variant_name) = variant_ctx.serde_rename.as_ref() { + self.output.push_str(variant_name); + } else if Some(String::from("kebab-case")) == variant_ctx.enum_serde_rename_all { + self.output.push_str(&to_kebab_case(&variant_ctx.name)); + } else if Some(String::from("snake_case")) == variant_ctx.enum_serde_rename_all { + self.output.push_str(&to_snake_case(&variant_ctx.name)); + } else if Some(String::from("lowercase")) == variant_ctx.enum_serde_rename_all { + self.output.push_str(&variant_ctx.name.to_lowercase()); + } else { + self.output.push_str(&variant_ctx.name); + } + self + } + fn emit_enum_end(&mut self, name: String) -> &mut GolangEmitter { + self.output.push_str("// enum "); + self.output.push_str(&name); + self.output.push_str("\n\n"); + self + } + + fn emit_package_name(&mut self, name: String) -> &mut GolangEmitter { + self.output.push_str("package "); + self.output.push_str(&name); + self.output.push_str("\n\n"); + self + } + fn emit_int_or_string_validation(&mut self) -> &mut GolangEmitter { + self.output + .push_str("// +kubebuilder:validation:XIntOrString\n"); + self + } + + fn emit_enum_validation(&mut self, enum_ctx: &EnumContext) -> &mut GolangEmitter { + // If the enum has "Other(String)" variant it means that + // it can be everything so it should not be validated + if enum_ctx.has_other_variant && enum_ctx.name != "InterfaceType" { + return self; + } + self.output.push_str("// +kubebuilder:validation:Enum="); + for variant in &enum_ctx.variants { + if let Some(u8_discriminant) = variant.u8_discriminant { + self.output + .push_str(format!("{}", u8_discriminant).as_str()); + self.output.push(';'); + } + if variant.u8_discriminant.is_none() || variant.enum_is_number_or_string { + self.output.push('"'); + self.emit_enum_variant_string(variant); + self.output.push('"'); + self.output.push(';'); + } + if let Some(alias) = &variant.serde_alias { + self.output.push('"'); + self.output.push_str(alias); + self.output.push('"'); + self.output.push(';'); + } + } + self.output.push('\n'); + self + } + + fn emit_docs(&mut self, name: &str, docs: &str) -> &mut GolangEmitter { + for (i, doc_line) in docs.lines().enumerate() { + self.output.push_str("//"); + if i == 0 { + self.output.push(' '); + self.output.push_str(name); + self.output.push(' '); + } + self.output.push_str(doc_line); + self.output.push('\n'); + } + self + } + + fn emit_struct_begin(&mut self, struct_ctx: &StructContext) -> &mut GolangEmitter { + self.emit_docs(&struct_ctx.name, &struct_ctx.docs); + self.output.push_str("// +k8s:deepcopy-gen=true\n"); + self.output.push_str("type "); + self.output.push_str(&struct_ctx.name); + self.output.push_str(" struct {\n"); + self + } + + fn emit_struct_end(&mut self) -> &mut GolangEmitter { + self.output.push_str("}\n\n"); + self + } + + fn emit_field_begin(&mut self, field_ctx: &FieldContext) -> &mut GolangEmitter { + let golang_field_name = rust_name_to_golang_name(&field_ctx.name); + self.emit_docs(&golang_field_name, &field_ctx.docs); + self.output.push_str(" "); + self.output.push_str(&golang_field_name); + self.output.push(' '); + self + } + + fn emit_field_end(&mut self) -> &mut GolangEmitter { + self.output.push('\n'); + self + } + + fn emit_type_name( + &mut self, + type_name: String, + field_ctx: &mut FieldContext, + ) -> &mut GolangEmitter { + if (type_name == "String" && !field_ctx.is_number_or_string) + || type_name == "IpAddr" + || type_name == "Value" + { + if field_ctx.is_optional { + self.emit_optional(); + } + self.output.push_str("string"); + } else if field_ctx.is_number_or_string && type_name != "Option" { + self.output.push_str("*intstr.IntOrString") + } else if type_name == "u8" { + if field_ctx.is_optional { + self.emit_optional(); + } + self.output.push_str("uint8"); + } else if type_name == "u16" { + if field_ctx.is_optional { + self.emit_optional(); + } + self.output.push_str("uint16"); + } else if type_name == "i16" { + if field_ctx.is_optional { + self.emit_optional(); + } + self.output.push_str("int16"); + } else if type_name == "u32" { + if field_ctx.is_optional { + self.emit_optional(); + } + self.output.push_str("uint32"); + } else if type_name == "i32" { + if field_ctx.is_optional { + self.emit_optional(); + } + self.output.push_str("int32"); + } else if type_name == "i64" { + if field_ctx.is_optional { + self.emit_optional(); + } + self.output.push_str("int64"); + } else if type_name == "u64" { + if field_ctx.is_optional { + self.emit_optional(); + } + self.output.push_str("uint64"); + } else if type_name == "Vec" { + if field_ctx.is_optional { + self.emit_optional(); + } + self.output.push_str("[]"); + field_ctx.is_optional = false + } else if type_name == "Option" { + field_ctx.is_optional = true; + } else if type_name == "DnsState" { + self.output.push('*'); + self.output.push_str(&rust_name_to_golang_name(&type_name)); + } else if type_name == "EthtoolFeatureConfig" { + self.output.push_str("map[string]bool"); + } else if type_name == "Interfaces" { + self.output.push_str("[]Interface"); + } else if type_name == "RouteRules" + || type_name == "Routes" + || type_name == "OvsDbGlobalConfig" + || type_name == "OvnConfiguration" + { + self.emit_optional(); + self.output.push_str(&rust_name_to_golang_name(&type_name)); + } else if type_name == "InterfaceIpv4" || type_name == "InterfaceIpv6" { + if field_ctx.is_optional { + self.emit_optional(); + } + self.output.push_str("InterfaceIP"); + } else { + if field_ctx.is_optional { + self.emit_optional(); + } + match type_name.as_str() { + "bool" => { + self.output.push_str(&type_name); + } + _ => { + self.output.push_str(&rust_name_to_golang_name(&type_name)); + } + } + } + self + } + + fn emit_map_begin(&mut self) -> &mut GolangEmitter { + self.output.push_str("map["); + self + } + fn emit_map_end(&mut self) -> &mut GolangEmitter { + self.output.push(']'); + self + } + fn emit_optional(&mut self) -> &mut GolangEmitter { + self.output.push('*'); + self + } + fn emit_json_tag(&mut self, args: Vec) -> &mut GolangEmitter { + self.output + .push_str(&format!(" `json:\"{}\"`", args.join(","))); + self + } + fn emit_header(&mut self) -> &mut GolangEmitter { + //self.output.push_str("//go:build !ignore_autogenerated\n\n"); + self.output.push_str(&self.header); + //self.output.push_str( + // "\n// Code generated by nmstate-go-apigen. DO NOT EDIT.\n", + //); + self + } + fn emit_enum_int_or_string_json_encoding( + &mut self, + enum_ctx: &EnumContext, + ) -> &mut GolangEmitter { + self.output.push_str( + format!( + r#" +func (o {enum_name}) MarshalJSON() ([]byte, error) {{ + return intstr.IntOrString(o).MarshalJSON() +}} + +func (o *{enum_name}) UnmarshalJSON(data []byte) error {{ + oi := intstr.IntOrString(*o) + if err := oi.UnmarshalJSON(data); err != nil {{ + return err + }} + *o = {enum_name}(oi) + return nil +}} + +"#, + enum_name = enum_ctx.name + ) + .as_str(), + ); + self + } + fn emit_bridge_interface( + &mut self, + linux_bridge_interface: &StructContext, + ovs_bridge_interface: &StructContext, + ) -> &mut GolangEmitter { + self.output.push_str( + r#" +// +k8s:deepcopy-gen=true +type OVSBridgeStpOptions struct { + Enabled *bool `json:"enabled,omitempty"` +} + +// +k8s:deepcopy-gen=true +type BridgePortConfigMetaData struct { + Name string `json:"name"` + Vlan *BridgePortVlanConfig `json:"vlan,omitempty"` +} + +// +k8s:deepcopy-gen=true +type BridgePortConfig struct { + BridgePortConfigMetaData `json:""` + *OVSBridgePortConfig `json:",omitempty"` + *LinuxBridgePortConfig `json:",omitempty"` +} + +// +k8s:deepcopy-gen=true +type BridgeOptions struct { + *LinuxBridgeOptions `json:",omitempty"` + *OVSBridgeOptions `json:",omitempty"` +} +"#, + ); + + self.emit_docs("BridgeConfig", "Linux or OVS bridge configuration"); + self.emit_docs("", " "); + self.emit_docs("Linux bridge: ", &linux_bridge_interface.docs); + self.emit_docs("", " "); + self.emit_docs("OVS bridge: ", &ovs_bridge_interface.docs); + self.output.push_str( + r#"// +k8s:deepcopy-gen=true +type BridgeConfig struct { + *OVSBridgeConfig `json:",omitempty"` + Options *BridgeOptions `json:"options,omitempty"` + Ports *[]BridgePortConfig `json:"port,omitempty"` +} +"#, + ); + self.output.push_str( + r#"// +k8s:deepcopy-gen=true +type BridgeInterface struct { + *BridgeConfig `json:"bridge,omitempty"` +} +"#, + ); + self + } +} + +pub fn to_kebab_case(s: &str) -> String { + Converter::new() + .remove_boundaries(&Boundary::digits()) + .to_case(Case::Kebab) + .convert(s) +} + +pub fn to_snake_case(s: &str) -> String { + s.to_case(Case::Snake) +} + +pub fn rust_name_to_golang_name(s: &str) -> String { + let mut golang_name = String::new(); + // Convert everyting to snake case so we can easily split and + // follow the golang naming conventin for Acronyms. + for word in to_snake_case(s).split('_') { + let golang_word = match word { + "ovn" | "ovs" | "uuid" | "db" | "udp" | "tcp" | "ip" | "dns" | "id" => { + word.to_uppercase() + } + _ => capitalize(word), + }; + golang_name.push_str(&golang_word); + } + golang_name +} + +pub fn capitalize(s: &str) -> String { + let mut c = s.chars(); + match c.next() { + None => String::new(), + Some(f) => f.to_uppercase().collect::() + c.as_str(), + } +} diff --git a/test/api/types_test.go b/test/api/types_test.go new file mode 100644 index 0000000..a7a5acf --- /dev/null +++ b/test/api/types_test.go @@ -0,0 +1,135 @@ +/* +Copyright The NMState Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v2 + +import ( + "fmt" + "io/fs" + "os" + "path/filepath" + "strings" + "testing" + + "sigs.k8s.io/yaml" + + nmstatev2 "github.com/nmstate/kubernetes-go-api/v2" + "github.com/stretchr/testify/require" +) + +func removeNullFields(originalState any) any { + originalStateSlice, isSlice := originalState.([]any) + if isSlice { + modifiedState := []any{} + for _, value := range originalStateSlice { + modifiedState = append(modifiedState, removeNullFields(value)) + } + return modifiedState + } + originalStateMap, isMap := originalState.(map[string]any) + if isMap { + modifiedState := map[string]any{} + for key, value := range originalStateMap { + if value != nil { + modifiedState[key] = removeNullFields(value) + } + } + return modifiedState + } + return originalState +} + +func normalizeState(state map[string]any) map[string]any { + ifaces, ok := state["interfaces"] + if ok { + if len(ifaces.([]any)) == 0 { + delete(state, "interfaces") + } else { + state["interfaces"] = removeNullFields(ifaces) + } + } + return state +} + +func requireStateEq(t *testing.T, expected, obtained []byte) { + var expectedYAMLAsInterface, obtainedYAMLAsInterface map[string]any + err := yaml.Unmarshal(expected, &expectedYAMLAsInterface) + require.NoError(t, err, "should success unmarshaling expected value\n%s", expected) + + err = yaml.Unmarshal(obtained, &obtainedYAMLAsInterface) + require.NoError(t, err, "should success unmarshaling obtained value\n%s", obtained) + require.Equal(t, normalizeState(expectedYAMLAsInterface), + normalizeState(obtainedYAMLAsInterface), + "unmarshaled expected and obtained states should be equal\n---> expected <--- \n%s\n ---> obtained <--- \n%s\n", expected, obtained) +} + +func testNetworkState(t *testing.T, expectedState []byte) { + netState := &nmstatev2.NetworkState{} + err := yaml.UnmarshalStrict(expectedState, netState) + require.NoError(t, err, "must success unmarshaling the state\n%+v", string(expectedState)) + obtainedState, err := yaml.Marshal(netState) + require.NoError(t, err, "must success marshaling back the state\n%+v", string(expectedState)) + + requireStateEq(t, nmstatev2.ReplaceDeprecatedNames(expectedState), obtainedState) +} + +func testUnmarshalDir(t *testing.T, dir string) { + states := map[string][]byte{} + err := filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() && info.Name() == "policy" { + return filepath.SkipDir + } + if info.IsDir() || filepath.Ext(info.Name()) != ".yml" || strings.Contains(info.Name(), "rollback") { + return nil + } + state, err := os.ReadFile(path) + if err != nil { + return fmt.Errorf("failed reading state '%s': %w", info.Name(), err) + } + states[info.Name()] = state + return nil + }) + require.NoError(t, err, "must succeed reading states") + require.NotEmpty(t, states, "missing test/integration output to test") + for stateName, expectedState := range states { + t.Run(stateName, func(t *testing.T) { + testNetworkState(t, expectedState) + }) + } +} + +func TestAPI(t *testing.T) { + tests := []struct { + name, dir string + }{ + { + name: "examples", + dir: os.Getenv("NMSTATE_SOURCE_INSTALL_DIR") + "/examples", + }, + { + name: "e2e-dump", + dir: os.Getenv("NMSTATE_E2E_DUMP"), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + testUnmarshalDir(t, tt.dir) + }) + } +} diff --git a/test/crd/Makefile b/test/crd/Makefile new file mode 100644 index 0000000..3cac667 --- /dev/null +++ b/test/crd/Makefile @@ -0,0 +1,5 @@ +JUNIT_DIR ?= /tmp/ +GO_JUNIT_REPORT=$(shell go env GOPATH)/bin/go-junit-report -set-exit-code + +generate: + go generate diff --git a/test/crd/groupversion_info.go b/test/crd/groupversion_info.go new file mode 100644 index 0000000..ed61917 --- /dev/null +++ b/test/crd/groupversion_info.go @@ -0,0 +1,36 @@ +/* +Copyright The Kubernetes NMState Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package v1 contains API Schema definitions for the nmstate.io v1 API group +// +kubebuilder:object:generate=true +// +groupName=nmstate.io +package v2 + +import ( + "k8s.io/apimachinery/pkg/runtime/schema" + "sigs.k8s.io/controller-runtime/pkg/scheme" +) + +var ( + // GroupVersion is group version used to register these objects + GroupVersion = schema.GroupVersion{Group: "nmstate.io", Version: "v2"} + + // SchemeBuilder is used to add go types to the GroupVersionKind scheme + SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion} + + // AddToScheme adds the types in this group-version to the given scheme. + AddToScheme = SchemeBuilder.AddToScheme +) diff --git a/test/crd/nmstate.io_clusternetworkstate.yaml b/test/crd/nmstate.io_clusternetworkstate.yaml new file mode 100644 index 0000000..a58039e --- /dev/null +++ b/test/crd/nmstate.io_clusternetworkstate.yaml @@ -0,0 +1,2657 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.14.0 + name: clusternetworkstate.nmstate.io +spec: + group: nmstate.io + names: + kind: ClusterNetworkState + listKind: ClusterNetworkStateList + plural: clusternetworkstate + shortNames: + - cns + singular: clusternetworkstate + scope: Cluster + versions: + - name: v2 + schema: + openAPIV3Schema: + description: ClusterNetworkState is the Schema for the nodenetworkconfigurationpolicies + API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + properties: + state: + description: "NetworkState The [NetworkState] represents the whole + network state including both\nkernel status and configurations provides + by backends(NetworkManager,\nOpenvSwitch databas, and etc).\n\n\nExample + yaml(many lines omitted) serialized NetworkState would be:\n\n\n```yaml\nhostname:\n\n\n\trunning: + host.example.org\n\tconfig: host.example.org\n\n\ndns-resolver:\n\n\n\tconfig:\n\t + \ server:\n\t - 2001:db8:1::\n\t - 192.0.2.1\n\t search: []\n\n\nroute-rules:\n\n\n\tconfig:\n\t- + ip-from: 2001:db8:b::/64\n\t priority: 30000\n\t route-table: + 200\n\t- ip-from: 192.0.2.2/32\n\t priority: 30000\n\t route-table: + 200\n\n\nroutes:\n\n\n\tconfig:\n\t- destination: 2001:db8:a::/64\n\t + \ next-hop-interface: eth1\n\t next-hop-address: 2001:db8:1::2\n\t + \ metric: 108\n\t table-id: 200\n\t- destination: 192.168.2.0/24\n\t + \ next-hop-interface: eth1\n\t next-hop-address: 192.168.1.3\n\t + \ metric: 108\n\t table-id: 200\n\n\ninterfaces:\n - name: eth1\n + \ type: ethernet\n state: up\n mac-address: 0E:F9:2B:28:42:D9\n + \ mtu: 1500\n ipv4:\n enabled: true\n dhcp: false\n address:\n + \ - ip: 192.168.1.3\n prefix-length: 24\n ipv6:\n enabled: + true\n dhcp: false\n autoconf: false\n address:\n - ip: + 2001:db8:1::1\n prefix-length: 64\n\n\novs-db:\n\n\n\texternal_ids:\n\t + \ hostname: host.example.org\n\t rundir: /var/run/openvswitch\n\t + \ system-id: 176866c7-6dc8-400f-98ac-c658509ec09f\n\tother_config: + {}\n\n\n```" + properties: + dns-resolver: + description: DNS DNS resolver status, deserialize and serialize + from/to `dns-resolver`. + properties: + config: + description: |- + Config The static saved DNS resolver config. + When applying, if this not mentioned(None), current static DNS config + will be preserved as it was. If defined(Some), will override current + static DNS config. + properties: + options: + description: |- + Options DNS option list. + To remove all existing search, please use `Some(Vec::new())`. + If undefined(set to `None`), will preserve current config. + items: + type: string + type: array + search: + description: |- + Search Search list for host-name lookup. + To remove all existing search, please use `Some(Vec::new())`. + If undefined(set to `None`), will preserve current config. + items: + type: string + type: array + server: + description: |- + Server Name server IP address list. + To remove all existing servers, please use `Some(Vec::new())`. + If undefined(set to `None`), will preserve current config. + items: + type: string + type: array + type: object + running: + description: |- + Running The running effective state. The DNS server might be from DHCP(IPv6 + autoconf) or manual setup. + Ignored when applying state. + properties: + options: + description: |- + Options DNS option list. + To remove all existing search, please use `Some(Vec::new())`. + If undefined(set to `None`), will preserve current config. + items: + type: string + type: array + search: + description: |- + Search Search list for host-name lookup. + To remove all existing search, please use `Some(Vec::new())`. + If undefined(set to `None`), will preserve current config. + items: + type: string + type: array + server: + description: |- + Server Name server IP address list. + To remove all existing servers, please use `Some(Vec::new())`. + If undefined(set to `None`), will preserve current config. + items: + type: string + type: array + type: object + type: object + hostname: + description: Hostname Hostname of current host. + properties: + config: + type: string + running: + type: string + type: object + interfaces: + description: Interfaces Network interfaces + items: + description: Interface Represent a kernel or user space network + interface. + properties: + 802.1x: + description: |- + Ieee8021X IEEE 802.1X authentication configurations. + Serialize and deserialize to/from `802.1x`. + properties: + ca-cert: + description: CaCert Deserialize and serialize from/to + `ca-cert`. + type: string + client-cert: + description: ClientCert Deserialize and serialize from/to + `client-cert`. + type: string + eap-methods: + description: Eap Deserialize and serialize from/to + `eap-methods`. + items: + type: string + type: array + identity: + type: string + private-key: + description: PrivateKey Deserialize and serialize from/to + `private-key`. + type: string + private-key-password: + description: |- + PrivateKeyPassword Deserialize and serialize from/to `private-key-password`. + Replaced to `<_password_hid_by_nmstate>` when querying. + type: string + type: object + accept-all-mac-addresses: + description: |- + AcceptAllMacAddresses Whether kernel should skip check on package targeting MAC address and + accept all packages, also known as promiscuous mode. + Serialize and deserialize to/from `accpet-all-mac-addresses`. + type: boolean + bridge: + description: |- + BridgeConfig Linux or OVS bridge configuration + + + Linux bridge: Bridge interface provided by linux kernel. + When serializing or deserializing, the [BaseInterface] will + be flatted and [LinuxBridgeConfig] stored as `bridge` section. The yaml + output [crate::NetworkState] containing an example linux bridge interface: + ```yml + interfaces: + - name: br0 + type: linux-bridge + state: up + mac-address: 9A:91:53:6C:67:DA + mtu: 1500 + min-mtu: 68 + max-mtu: 65535 + wait-ip: any + ipv4: + enabled: false + ipv6: + enabled: false + bridge: + options: + gc-timer: 29594 + group-addr: 01:80:C2:00:00:00 + group-forward-mask: 0 + group-fwd-mask: 0 + hash-max: 4096 + hello-timer: 46 + mac-ageing-time: 300 + multicast-last-member-count: 2 + multicast-last-member-interval: 100 + multicast-membership-interval: 26000 + multicast-querier: false + multicast-querier-interval: 25500 + multicast-query-interval: 12500 + multicast-query-response-interval: 1000 + multicast-query-use-ifaddr: false + multicast-router: auto + multicast-snooping: true + multicast-startup-query-count: 2 + multicast-startup-query-interval: 3125 + stp: + enabled: true + forward-delay: 15 + hello-time: 2 + max-age: 20 + priority: 32768 + vlan-protocol: 802.1q + port: + - name: eth1 + stp-hairpin-mode: false + stp-path-cost: 100 + stp-priority: 32 + - name: eth2 + stp-hairpin-mode: false + stp-path-cost: 100 + stp-priority: 32 + + + ``` + + + OVS bridge: OpenvSwitch bridge interface. Example yaml output of [crate::NetworkState] + with an OVS bridge: + ```yaml + --- + interfaces: + - name: br0 + type: ovs-interface + state: up + ipv4: + address: + - ip: 192.0.2.252 + prefix-length: 24 + - ip: 192.0.2.251 + prefix-length: 24 + dhcp: false + enabled: true + ipv6: + address: + - ip: 2001:db8:2::1 + prefix-length: 64 + - ip: 2001:db8:1::1 + prefix-length: 64 + autoconf: false + dhcp: false + enabled: true + - name: br0 + type: ovs-bridge + state: up + bridge: + port: + - name: br0 + - name: eth1 + + + ``` + properties: + allow-extra-patch-ports: + description: |- + AllowExtraPatchPorts Only validate for applying, when set to `true`, extra OVS patch ports + will not fail the verification. Default is false. + This property will not be persisted, every time you modify + ports of specified OVS bridge, you need to explicitly define this + property if not using default value. + Deserialize from `allow-extra-patch-ports`. + type: boolean + options: + properties: + datapath: + description: |- + Datapath Set to `netdev` for DPDK. + Deserialize and serialize from/to `datapath`. + type: string + fail-mode: + description: FailMode Deserialize and serialize + from/to `fail-mode`. + type: string + gc-timer: + format: int64 + type: integer + group-addr: + type: string + group-forward-mask: + anyOf: + - type: integer + - type: string + description: |- + GroupForwardMask Alias of [LinuxBridgeOptions.group_fwd_mask], not preferred, please + use [LinuxBridgeOptions.group_fwd_mask] instead. + x-kubernetes-int-or-string: true + group-fwd-mask: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + hash-max: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + hello-timer: + format: int64 + type: integer + mac-ageing-time: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + mcast-snooping-enable: + description: McastSnoopingEnable Deserialize and + serialize from/to `mcast-snooping-enable`. + type: boolean + multicast-last-member-count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + multicast-last-member-interval: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + multicast-membership-interval: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + multicast-querier: + type: boolean + multicast-querier-interval: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + multicast-query-interval: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + multicast-query-response-interval: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + multicast-query-use-ifaddr: + type: boolean + multicast-router: + anyOf: + - type: integer + - type: string + enum: + - 1 + - auto + - 0 + - disabled + - 2 + - enabled + x-kubernetes-int-or-string: true + multicast-snooping: + type: boolean + multicast-startup-query-count: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + multicast-startup-query-interval: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + rstp: + type: boolean + stp: + properties: + enabled: + type: boolean + forward-delay: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + hello-time: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + max-age: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + priority: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + vlan-default-pvid: + type: integer + vlan-protocol: + enum: + - 802.1q + - 802.1ad + type: string + type: object + port: + items: + properties: + link-aggregation: + description: |- + OVSBridgeBondConfig The example yaml output of OVS bond: + ```yml + --- + interfaces: + - name: eth1 + type: ethernet + state: up + - name: eth2 + type: ethernet + state: up + - name: br0 + type: ovs-bridge + state: up + bridge: + port: + - name: veth1 + - name: ovs0 + - name: bond1 + link-aggregation: + mode: balance-slb + port: + - name: eth2 + - name: eth1 + + + ``` + properties: + bond-downdelay: + anyOf: + - type: integer + - type: string + description: BondDowndelay Deserialize and + serialize from/to `bond-downdelay`. + x-kubernetes-int-or-string: true + bond-updelay: + anyOf: + - type: integer + - type: string + description: BondUpdelay Deserialize and + serialize from/to `bond-updelay`. + x-kubernetes-int-or-string: true + mode: + enum: + - active-backup + - balance-slb + - balance-tcp + - lacp + type: string + ovs-db: + description: |- + Ovsdb OpenvSwitch specific `other_config` for OVS bond. Please refer to + manpage `ovs-vswitchd.conf.db(5)` for more detail. + When setting to None, nmstate will try to preserve current + `other_config`, otherwise, nmstate will override all `other_config` + for specified OVS bond. + properties: + external_ids: + additionalProperties: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + other_config: + additionalProperties: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + description: |- + OtherConfig OpenvSwitch specific `other_config`. Please refer to + manpage `ovs-vswitchd.conf.db(5)` for more detail. + When setting to None, nmstate will try to preserve current + `other_config`, otherwise, nmstate will override all `other_config` + for specified interface. + type: object + type: object + port: + description: Ports Serialize to 'port'. Deserialize + from `port` or `ports`. + items: + properties: + name: + type: string + required: + - name + type: object + type: array + type: object + name: + type: string + stp-hairpin-mode: + description: |- + StpHairpinMode Controls whether traffic may be send back out of the port on which it + was received. + type: boolean + stp-path-cost: + anyOf: + - type: integer + - type: string + description: StpPathCost The STP path cost of + the specified port. + x-kubernetes-int-or-string: true + stp-priority: + anyOf: + - type: integer + - type: string + description: |- + StpPriority The STP port priority. The priority value is an unsigned 8-bit quantity + (number between 0 and 255). This metric is used in the designated port + an droot port selecā€ tion algorithms. + x-kubernetes-int-or-string: true + vlan: + description: BridgePortVlanConfig Bridge VLAN + filtering configuration + properties: + enable-native: + description: |- + EnableNative Enable native VLAN. + Deserialize and serialize from/to `enable-native`. + type: boolean + mode: + description: Mode Bridge VLAN filtering mode + enum: + - trunk + - access + type: string + tag: + anyOf: + - type: integer + - type: string + description: Tag VLAN Tag for native VLAN. + x-kubernetes-int-or-string: true + trunk-tags: + description: |- + TrunkTags Trunk tags. + Deserialize and serialize from/to `trunk-tags`. + items: + properties: + id: + description: ID Single VLAN trunk ID + type: integer + id-range: + description: IDRange VLAN trunk ID + range + properties: + max: + description: Max Maximum VLAN ID(included). + type: integer + min: + description: Min Minimum VLAN ID(included). + type: integer + required: + - max + - min + type: object + type: object + type: array + type: object + required: + - name + type: object + type: array + type: object + controller: + description: |- + Controller Controller of the specified interface. + Only valid for applying, `None` means no change, empty string means + detach from current controller, please be advise, an error will trigger + if this property conflict with ports list of bridge/bond/etc. + Been always set to `None` by [crate::NetworkState::retrieve()]. + type: string + copy-mac-from: + description: |- + CopyMacFrom Copy the MAC address from specified interface. + Ignored during serializing. + Deserialize from `copy-mac-from`. + type: string + description: + description: |- + Description Interface description stored in network backend. Not available for + kernel only mode. + type: string + dispatch: + description: Dispatch Dispatch script configurations + properties: + post-activation: + description: |- + PostActivation Dispatch bash script content to be invoked after interface activation + finished by network backend. Nmstate will append additional lines + to make sure this script is only invoked for specified interface when + backend interface activation finished. + Setting to empty string will remove the dispatch script + type: string + post-deactivation: + description: |- + PostDeactivation Dispatch bash script content to be invoked after interface deactivation + finished by network backend. Nmstate will append additional lines + to make sure this script is only invoked for specified interface when + backend interface deactivation finished. + Setting to empty string will remove the dispatch script + type: string + type: object + dpdk: + properties: + devargs: + type: string + n_rxq_desc: + description: |- + NRxqDesc Specifies the rx queue size (number rx descriptors) for dpdk ports. + Must be power of 2 in the range of 1 to 4096. + Setting to 0 means remove this setting from OVS database. + format: int32 + type: integer + n_txq_desc: + description: |- + NTxqDesc Specifies the tx queue size (number tx descriptors) for dpdk ports. + Must be power of 2 in the range of 1 to 4096. + Setting to 0 means remove this setting from OVS database. + format: int32 + type: integer + rx-queue: + description: |- + RxQueue Deserialize and serialize from/to `rx-queue`. You may also use + OVS terminology `n_rxq` for this property. + format: int32 + type: integer + required: + - devargs + type: object + driver: + description: Driver The driver of the specified network + device. + type: string + ethernet: + properties: + auto-negotiation: + description: AutoNeg Deserialize and serialize from/to + `auto-negotiation`. + type: boolean + duplex: + enum: + - full + - half + type: string + speed: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + sr-iov: + description: |- + SrIov Single Root I/O Virtualization(SRIOV) configuration. + Deserialize and serialize from/to `sr-iov`. + properties: + total-vfs: + anyOf: + - type: integer + - type: string + description: |- + TotalVfs The number of VFs enabled on PF. + Deserialize and serialize from/to `total-vfs`. + x-kubernetes-int-or-string: true + vfs: + description: |- + Vfs VF specific configurations. + * Setting to `Some(Vec::new())` will revert all VF configurations back + to defaults. + * If not empty, missing [SrIovVfConfig] will use current configuration. + items: + properties: + id: + format: int32 + type: integer + iface-name: + description: |- + IfaceName Interface name for this VF, only for querying, will be ignored + when applying network state. + type: string + mac-address: + description: MacAddress Deserialize and serialize + from/to `mac-address`. + type: string + max-tx-rate: + anyOf: + - type: integer + - type: string + description: MaxTxRate Deserialize and serialize + from/to `max-tx-rate`. + x-kubernetes-int-or-string: true + min-tx-rate: + anyOf: + - type: integer + - type: string + description: MinTxRate Deserialize and serialize + from/to `min_tx_rate`. + x-kubernetes-int-or-string: true + qos: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + spoof-check: + description: SpoofCheck Deserialize and serialize + from/to `spoof-check`. + type: boolean + trust: + type: boolean + vlan-id: + anyOf: + - type: integer + - type: string + description: VlanID Deserialize and serialize + from/to `vlan-id`. + x-kubernetes-int-or-string: true + vlan-proto: + enum: + - 802.1q + - 802.1ad + type: string + required: + - id + type: object + type: array + type: object + type: object + ethtool: + description: Ethtool Ethtool configurations + properties: + coalesce: + description: Coalesce The coalescing settings of the + specified network device. + properties: + adaptive-rx: + description: AdaptiveRx Deserialize and serialize + from/to `adaptive-rx`. + type: boolean + adaptive-tx: + description: AdaptiveTx Deserialize and serialize + from/to `adaptive-tx`. + type: boolean + pkt-rate-high: + anyOf: + - type: integer + - type: string + description: PktRateHigh Deserialize and serialize + from/to `pkt-rate-high`. + x-kubernetes-int-or-string: true + pkt-rate-low: + anyOf: + - type: integer + - type: string + description: PktRateLow Deserialize and serialize + from/to `pkt-rate-low`. + x-kubernetes-int-or-string: true + rx-frames: + anyOf: + - type: integer + - type: string + description: RxFrames Deserialize and serialize + from/to `rx-frames`. + x-kubernetes-int-or-string: true + rx-frames-high: + anyOf: + - type: integer + - type: string + description: RxFramesHigh Deserialize and serialize + from/to `rx-frames-high`. + x-kubernetes-int-or-string: true + rx-frames-irq: + anyOf: + - type: integer + - type: string + description: RxFramesIrq Deserialize and serialize + from/to `rx-frames-irq`. + x-kubernetes-int-or-string: true + rx-frames-low: + anyOf: + - type: integer + - type: string + description: RxFramesLow Deserialize and serialize + from/to `rx-frames-low`. + x-kubernetes-int-or-string: true + rx-usecs: + anyOf: + - type: integer + - type: string + description: RxUsecs Deserialize and serialize + from/to `rx-usecs`. + x-kubernetes-int-or-string: true + rx-usecs-high: + anyOf: + - type: integer + - type: string + description: RxUsecsHigh Deserialize and serialize + from/to `rx-usecs-high`. + x-kubernetes-int-or-string: true + rx-usecs-irq: + anyOf: + - type: integer + - type: string + description: RxUsecsIrq Deserialize and serialize + from/to `rx-usecs-irq`. + x-kubernetes-int-or-string: true + rx-usecs-low: + anyOf: + - type: integer + - type: string + description: RxUsecsLow Deserialize and serialize + from/to `rx-usecs-low`. + x-kubernetes-int-or-string: true + sample-interval: + anyOf: + - type: integer + - type: string + description: SampleInterval Deserialize and serialize + from/to `sample-interval`. + x-kubernetes-int-or-string: true + stats-block-usecs: + anyOf: + - type: integer + - type: string + description: StatsBlockUsecs Deserialize and serialize + from/to `stats-block-usecs`. + x-kubernetes-int-or-string: true + tx-frames: + anyOf: + - type: integer + - type: string + description: TxFrames Deserialize and serialize + from/to `tx-frames`. + x-kubernetes-int-or-string: true + tx-frames-high: + anyOf: + - type: integer + - type: string + description: TxFramesHigh Deserialize and serialize + from/to `tx-frames-high`. + x-kubernetes-int-or-string: true + tx-frames-irq: + anyOf: + - type: integer + - type: string + description: TxFramesIrq Deserialize and serialize + from/to `tx-frames-irq`. + x-kubernetes-int-or-string: true + tx-frames-low: + anyOf: + - type: integer + - type: string + description: TxFramesLow Deserialize and serialize + from/to `tx-frames-low`. + x-kubernetes-int-or-string: true + tx-usecs: + anyOf: + - type: integer + - type: string + description: TxUsecs Deserialize and serialize + from/to `tx-usecs`. + x-kubernetes-int-or-string: true + tx-usecs-high: + anyOf: + - type: integer + - type: string + description: TxUsecsHigh Deserialize and serialize + from/to `tx-usecs-high`. + x-kubernetes-int-or-string: true + tx-usecs-irq: + anyOf: + - type: integer + - type: string + description: TxUsecsIrq Deserialize and serialize + from/to `tx-usecs-irq`. + x-kubernetes-int-or-string: true + tx-usecs-low: + anyOf: + - type: integer + - type: string + description: TxUsecsLow Deserialize and serialize + from/to `tx-usecs-low`. + x-kubernetes-int-or-string: true + type: object + feature: + additionalProperties: + type: boolean + description: |- + Feature The protocol offload and other features of specified network device. + Only changeable features are included when querying. + type: object + pause: + description: Pause The pause parameters of the specified + Ethernet device. + properties: + autoneg: + type: boolean + rx: + type: boolean + tx: + type: boolean + type: object + ring: + description: Ring The rx/tx ring parameters of the + specified network device. + properties: + rx: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + rx-jumbo: + anyOf: + - type: integer + - type: string + description: RxJumbo Deserialize and serialize + from/to `rx-jumbo`. + x-kubernetes-int-or-string: true + rx-jumbo-max: + anyOf: + - type: integer + - type: string + description: RxJumboMax Deserialize and serialize + from/to `rx-jumbo-max`. + x-kubernetes-int-or-string: true + rx-max: + anyOf: + - type: integer + - type: string + description: RxMax Deserialize and serialize from/to + `rx-max`. + x-kubernetes-int-or-string: true + rx-mini: + anyOf: + - type: integer + - type: string + description: RxMini Deserialize and serialize from/to + `rx-mini`. + x-kubernetes-int-or-string: true + rx-mini-max: + anyOf: + - type: integer + - type: string + description: RxMiniMax Deserialize and serialize + from/to `rx-mini-max`. + x-kubernetes-int-or-string: true + tx: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + tx-max: + anyOf: + - type: integer + - type: string + description: TxMax Deserialize and serialize from/to + `tx-max`. + x-kubernetes-int-or-string: true + type: object + type: object + hsr: + description: Hsr Deserialize and serialize to `hsr`. + properties: + multicast-spec: + description: MulticastSpec The last byte of the supervision + address. + type: integer + port1: + description: Port1 The port1 interface name. + type: string + port2: + description: Port2 The port2 interface name. + type: string + protocol: + description: Protocol Protocol to be used. + enum: + - hsr + - prp + type: string + supervision-address: + description: |- + SupervisionAddress The MAC address used for the supervision frames. This property is + read-only. + type: string + required: + - multicast-spec + - port1 + - port2 + - protocol + type: object + identifier: + description: |- + Identifier Define network backend matching method on choosing network interface. + Default to [InterfaceIdentifier::Name]. + enum: + - name + - mac-address + type: string + infiniband: + properties: + base-iface: + description: BaseIface For pkey sub-interface only. + Empty for base interface. + type: string + mode: + description: Mode Mode of InfiniBand interface. + enum: + - datagram + - connected + type: string + pkey: + anyOf: + - type: integer + - type: string + description: |- + Pkey P-key of sub-interface. + Serialize in hex string format(lower case). + For base interface, it is set to None. + The `0xffff` value also indicate this is a InfiniBand base interface. + x-kubernetes-int-or-string: true + required: + - mode + type: object + ipv4: + description: |- + Ipv4 IPv4 information. + Hided if interface is not allowed to hold IP information(e.g. port of + bond is not allowed to hold IP information). + properties: + addr-gen-mode: + description: Ipv6AddrGenMode IPv6 address generation + mode + type: string + address: + items: + properties: + ip: + description: IP IP address. + type: string + mptcp-flags: + description: |- + MptcpFlags MPTCP flag on this IP address. + Ignored when applying as nmstate does not support support IP address + specific MPTCP flags. You should apply MPTCP flags at interface level + via [BaseInterface.mptcp]. + items: + enum: + - signal + - subflow + - backup + - fullmesh + type: string + type: array + preferred-life-time: + description: |- + PreferredLifeTime Remaining time for IP address been preferred. The output format is + "32sec" or "forever". + This property is query only, it will be ignored when applying. + Serialize to `preferred-life-time`. + Deserialize from `preferred-life-time` or `preferred-left` or + `preferred-lft`. + type: string + prefix-length: + description: |- + PrefixLength Prefix length. + Serialize and deserialize to/from `prefix-length`. + type: integer + valid-life-time: + description: |- + ValidLifeTime Remaining time for IP address been valid. The output format is + "32sec" or "forever". + This property is query only, it will be ignored when applying. + Serialize to `valid-life-time`. + Deserialize from `valid-life-time` or `valid-left` or `valid-lft`. + type: string + required: + - ip + - prefix-length + type: object + type: array + allow-extra-address: + type: boolean + auto-dns: + type: boolean + auto-gateway: + type: boolean + auto-route-metric: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + auto-route-table-id: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + auto-routes: + type: boolean + autoconf: + type: boolean + dhcp: + type: boolean + dhcp-client-id: + description: Dhcpv4ClientID DHCPv4 client ID + type: string + dhcp-custom-hostname: + type: string + dhcp-duid: + description: Dhcpv6Duid DHCPv6 Unique Identifier + type: string + dhcp-send-hostname: + type: boolean + enabled: + type: boolean + token: + type: string + type: object + ipv6: + description: |- + Ipv6 IPv4 information. + Hided if interface is not allowed to hold IP information(e.g. port of + bond is not allowed to hold IP information). + properties: + addr-gen-mode: + description: Ipv6AddrGenMode IPv6 address generation + mode + type: string + address: + items: + properties: + ip: + description: IP IP address. + type: string + mptcp-flags: + description: |- + MptcpFlags MPTCP flag on this IP address. + Ignored when applying as nmstate does not support support IP address + specific MPTCP flags. You should apply MPTCP flags at interface level + via [BaseInterface.mptcp]. + items: + enum: + - signal + - subflow + - backup + - fullmesh + type: string + type: array + preferred-life-time: + description: |- + PreferredLifeTime Remaining time for IP address been preferred. The output format is + "32sec" or "forever". + This property is query only, it will be ignored when applying. + Serialize to `preferred-life-time`. + Deserialize from `preferred-life-time` or `preferred-left` or + `preferred-lft`. + type: string + prefix-length: + description: |- + PrefixLength Prefix length. + Serialize and deserialize to/from `prefix-length`. + type: integer + valid-life-time: + description: |- + ValidLifeTime Remaining time for IP address been valid. The output format is + "32sec" or "forever". + This property is query only, it will be ignored when applying. + Serialize to `valid-life-time`. + Deserialize from `valid-life-time` or `valid-left` or `valid-lft`. + type: string + required: + - ip + - prefix-length + type: object + type: array + allow-extra-address: + type: boolean + auto-dns: + type: boolean + auto-gateway: + type: boolean + auto-route-metric: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + auto-route-table-id: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + auto-routes: + type: boolean + autoconf: + type: boolean + dhcp: + type: boolean + dhcp-client-id: + description: Dhcpv4ClientID DHCPv4 client ID + type: string + dhcp-custom-hostname: + type: string + dhcp-duid: + description: Dhcpv6Duid DHCPv6 Unique Identifier + type: string + dhcp-send-hostname: + type: boolean + enabled: + type: boolean + token: + type: string + type: object + libreswan: + properties: + authby: + type: string + clientaddrfamily: + enum: + - ipv4 + - ipv6 + type: string + dpdaction: + type: string + dpddelay: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + dpdtimeout: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + esp: + type: string + hostaddrfamily: + enum: + - ipv4 + - ipv6 + type: string + ike: + type: string + ikelifetime: + type: string + ikev2: + type: string + ipsec-interface: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + left: + type: string + leftcert: + type: string + leftid: + type: string + leftmodecfgclient: + type: boolean + leftrsasigkey: + type: string + psk: + description: Psk PSK authentication, if not defined, + will use X.509 PKI authentication + type: string + right: + type: string + rightid: + type: string + rightrsasigkey: + type: string + rightsubnet: + type: string + salifetime: + type: string + type: + enum: + - tunnel + - transport + type: string + required: + - right + type: object + link-aggregation: + description: Bond Bond specific settings. + properties: + mode: + description: Mode Mode is mandatory when create new + bond interface. + enum: + - balance-rr + - "0" + - active-backup + - "1" + - balance-xor + - "2" + - broadcast + - "3" + - 802.3ad + - "4" + - balance-tlb + - "5" + - balance-alb + - "6" + - unknown + type: string + options: + description: |- + Options When applying, if defined, it will override current port list. + The verification will not fail on bond options miss-match but an + warning message. + Please refer to [kernel documentation](https://www.kernel.org/doc/Documentation/networking/bonding.txt) for detail + properties: + ad_actor_sys_prio: + anyOf: + - type: integer + - type: string + description: |- + AdActorSysPrio In an AD system, this specifies the system priority. The allowed range + is 1 - 65535. + x-kubernetes-int-or-string: true + ad_actor_system: + description: |- + AdActorSystem In an AD system, this specifies the mac-address for the actor in + protocol packet exchanges (LACPDUs). The value cannot be NULL or + multicast. It is preferred to have the local-admin bit set for this mac + but driver does not enforce it. If the value is not given then system + defaults to using the controller's mac address as actors' system + address. + type: string + ad_select: + description: |- + AdSelect Specifies the 802.3ad aggregation selection logic to use. The + possible values and their effects are: + enum: + - stable + - "0" + - bandwidth + - "1" + - count + - "2" + type: string + ad_user_port_key: + anyOf: + - type: integer + - type: string + description: |- + AdUserPortKey In an AD system, the port-key has three parts as shown below - + + + ```text + Bits Use + 00 Duplex + 01-05 Speed + 06-15 User-defined + ``` + + + This defines the upper 10 bits of the port key. The values can be from + 0 + - 1023. If not given, the system defaults to 0. + + + This parameter has effect only in 802.3ad mode. + x-kubernetes-int-or-string: true + all_slaves_active: + description: |- + AllSlavesActive Specifies that duplicate frames (received on inactive ports) should be + dropped (0) or delivered (1). + + + Normally, bonding will drop duplicate frames (received on inactive + ports), which is desirable for most users. But there are some times it + is nice to allow duplicate frames to be delivered. + enum: + - dropped + - "0" + - delivered + - "1" + type: string + arp_all_targets: + description: |- + ArpAllTargets Specifies the quantity of arp_ip_targets that must be reachable in + order for the ARP monitor to consider a port as being up. This + option affects only active-backup mode for ports with + arp_validation enabled. + enum: + - any + - "0" + - all + - "1" + type: string + arp_interval: + anyOf: + - type: integer + - type: string + description: |- + ArpInterval Specifies the ARP link monitoring frequency in milliseconds. + + + The ARP monitor works by periodically checking the port devices to + determine whether they have sent or received traffic recently (the + precise criteria depends upon the bonding mode, and the state of the + port). Regular traffic is generated via ARP probes issued for the + addresses specified by the arp_ip_target option. + + + This behavior can be modified by the arp_validate option, + below. + + + If ARP monitoring is used in an etherchannel compatible mode (modes 0 + and 2), the switch should be configured in a mode that evenly + distributes packets across all links. If the switch is configured to + distribute the packets in an XOR fashion, all replies from the ARP + targets will be received on the same link which could cause the other + team members to fail. ARP monitoring should not be used in conjunction + with miimon. A value of 0 disables ARP monitoring. The default value + is 0. + x-kubernetes-int-or-string: true + arp_ip_target: + description: |- + ArpIPTarget Specifies the IP addresses to use as ARP monitoring peers when + arp_interval is > 0. These are the targets of the ARP request sent to + determine the health of the link to the targets. Specify these values + in ddd.ddd.ddd.ddd format. Multiple IP addresses must be separated by a + comma. At least one IP address must be given for ARP monitoring to + function. The maximum number of targets that can be specified is 16. + The default value is no IP addresses. + type: string + arp_missed_max: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + arp_validate: + description: |- + ArpValidate Specifies whether or not ARP probes and replies should be validated in + any mode that supports arp monitoring, or whether non-ARP traffic + should be filtered (disregarded) for link monitoring purposes. + enum: + - none + - "0" + - active + - "1" + - backup + - "2" + - all + - "3" + - filter + - "4" + - filter_active + - "5" + - filter_backup + - "6" + type: string + balance_slb: + type: boolean + downdelay: + anyOf: + - type: integer + - type: string + description: |- + Downdelay Specifies the time, in milliseconds, to wait before disabling a port + after a link failure has been detected. This option is only valid for + the miimon link monitor. The downdelay value should be a multiple of + the miimon value; if not, it will be rounded down to the nearest + multiple. The default value is 0. + x-kubernetes-int-or-string: true + fail_over_mac: + description: |- + FailOverMac Specifies whether active-backup mode should set all ports to the same + MAC address at enportment (the traditional behavior), or, when enabled, + perform special handling of the bond's MAC address in accordance with + the selected policy. + enum: + - none + - "0" + - active + - "1" + - follow + - "2" + type: string + lacp_rate: + description: |- + LacpRate Option specifying the rate in which we'll ask our link partner to + transmit LACPDU packets in 802.3ad mode. + enum: + - slow + - "0" + - fast + - "1" + type: string + lp_interval: + anyOf: + - type: integer + - type: string + description: |- + LpInterval Specifies the number of seconds between instances where the bonding + driver sends learning packets to each slaves peer switch. + + + The valid range is 1 - 0x7fffffff; the default value is 1. This Option + has effect only in balance-tlb and balance-alb modes. + x-kubernetes-int-or-string: true + miimon: + anyOf: + - type: integer + - type: string + description: |- + Miimon Specifies the MII link monitoring frequency in milliseconds. + This determines how often the link state of each port is + inspected for link failures. A value of zero disables MII + link monitoring. A value of 100 is a good starting point. + The use_carrier option, below, affects how the link state is + determined. See the High Availability section for additional + information. The default value is 0. + x-kubernetes-int-or-string: true + min_links: + anyOf: + - type: integer + - type: string + description: |- + MinLinks Specifies the minimum number of links that must be active before + asserting carrier. It is similar to the Cisco EtherChannel min-links + feature. This allows setting the minimum number of member ports that + must be up (link-up state) before marking the bond device as up + (carrier on). This is useful for situations where higher level services + such as clustering want to ensure a minimum number of low bandwidth + links are active before switchover. This option only affect 802.3ad + mode. + + + The default value is 0. This will cause carrier to be asserted (for + 802.3ad mode) whenever there is an active aggregator, regardless of the + number of available links in that aggregator. Note that, because an + aggregator cannot be active without at least one available link, + setting this option to 0 or to 1 has the exact same effect. + x-kubernetes-int-or-string: true + num_grat_arp: + anyOf: + - type: integer + - type: string + description: |- + NumGratArp Specify the number of peer notifications (gratuitous ARPs and + unsolicited IPv6 Neighbor Advertisements) to be issued after a + failover event. As soon as the link is up on the new port + (possibly immediately) a peer notification is sent on the + bonding device and each VLAN sub-device. This is repeated at + the rate specified by peer_notif_delay if the number is + greater than 1. + + + The valid range is 0 - 255; the default value is 1. These options + affect only the active-backup mode. These options were added for + bonding versions 3.3.0 and 3.4.0 respectively. + + + From Linux 3.0 and bonding version 3.7.1, these notifications are + generated by the ipv4 and ipv6 code and the numbers of repetitions + cannot be set independently. + x-kubernetes-int-or-string: true + num_unsol_na: + anyOf: + - type: integer + - type: string + description: NumUnsolNa Identical to [BondOptions.num_grat_arp] + x-kubernetes-int-or-string: true + packets_per_slave: + anyOf: + - type: integer + - type: string + description: |- + PacketsPerSlave Specify the number of packets to transmit through a port before moving + to the next one. When set to 0 then a port is chosen at random. + + + The valid range is 0 - 65535; the default value is 1. This option has + effect only in balance-rr mode. + x-kubernetes-int-or-string: true + primary: + description: |- + Primary A string (eth0, eth2, etc) specifying which slave is the primary + device. The specified device will always be the active slave while + it is available. Only when the primary is off-line will alternate + devices be used. This is useful when one slave is preferred over + another, e.g., when one slave has higher throughput than another. + + + The primary option is only valid for active-backup(1), balance-tlb (5) + and balance-alb (6) mode. + type: string + primary_reselect: + description: |- + PrimaryReselect Specifies the reselection policy for the primary port. This affects + how the primary port is chosen to become the active port when failure + of the active port or recovery of the primary port occurs. This + option is designed to prevent flip-flopping between the primary port + and other ports. + enum: + - always + - "0" + - better + - "1" + - failure + - "2" + type: string + resend_igmp: + anyOf: + - type: integer + - type: string + description: |- + ResendIgmp Specifies the number of IGMP membership reports to be issued after + a failover event. One membership report is issued immediately after + the failover, subsequent packets are sent in each 200ms interval. + + + The valid range is 0 - 255; the default value is 1. A value of 0 + prevents the IGMP membership report from being issued in response + to the failover event. + + + This option is useful for bonding modes balance-rr (0), active-backup + (1), balance-tlb (5) and balance-alb (6), in which a failover can + switch the IGMP traffic from one port to another. Therefore a + fresh IGMP report must be issued to cause the switch to forward the + incoming IGMP traffic over the newly selected port. + x-kubernetes-int-or-string: true + tlb_dynamic_lb: + description: |- + TlbDynamicLb Specifies if dynamic shuffling of flows is enabled in tlb mode. The + value has no effect on any other modes. + + + The default behavior of tlb mode is to shuffle active flows across + ports based on the load in that interval. This gives nice lb + characteristics but can cause packet reordering. If re-ordering is a + concern use this variable to disable flow shuffling and rely on load + balancing provided solely by the hash distribution. xmit-hash-policy + can be used to select the appropriate hashing for the setup. + + + The sysfs entry can be used to change the setting per bond device and + the initial value is derived from the module parameter. The sysfs entry + is allowed to be changed only if the bond device is down. + + + The default value is "1" that enables flow shuffling while value "0" + disables it. This option was added in bonding driver 3.7.1 + type: boolean + updelay: + anyOf: + - type: integer + - type: string + description: |- + Updelay Specifies the time, in milliseconds, to wait before enabling a port + after a link recovery has been detected. This option is only valid for + the miimon link monitor. The updelay value should be a multiple of the + miimon value; if not, it will be rounded down to the nearest multiple. + The default value is 0. + x-kubernetes-int-or-string: true + use_carrier: + description: |- + UseCarrier Specifies whether or not miimon should use MII or ETHTOOL + ioctls vs. netif_carrier_ok() to determine the link + status. The MII or ETHTOOL ioctls are less efficient and + utilize a deprecated calling sequence within the kernel. The + netif_carrier_ok() relies on the device driver to maintain its + state with netif_carrier_on/off; at this writing, most, but + not all, device drivers support this facility. + + + If bonding insists that the link is up when it should not be, + it may be that your network device driver does not support + netif_carrier_on/off. The default state for netif_carrier is + "carrier on," so if a driver does not support netif_carrier, + it will appear as if the link is always up. In this case, + setting use_carrier to 0 will cause bonding to revert to the + MII / ETHTOOL ioctl method to determine the link state. + + + A value of 1 enables the use of netif_carrier_ok(), a value of + 0 will use the deprecated MII / ETHTOOL ioctls. The default + value is 1. + type: boolean + xmit_hash_policy: + description: |- + XmitHashPolicy Selects the transmit hash policy to use for slave selection in + balance-xor, 802.3ad, and tlb modes. + enum: + - layer2 + - "0" + - layer3+4 + - "1" + - layer2+3 + - "2" + - encap2+3 + - "3" + - encap3+4 + - "4" + - vlan+srcmac + - "5" + type: string + type: object + port: + description: |- + Port Deserialize and serialize from/to `port`. + You can also use `ports` for deserializing. + When applying, if defined, it will override current port list. + items: + type: string + type: array + ports-config: + description: |- + PortsConfig Deserialize and serialize from/to `ports-config`. + When applying, if defined, it will override current ports + configuration. Note that `port` is not required to set with + `ports-config`. An error will be raised during apply when the port + names specified in `port` and `ports-config` conflict with each + other. + items: + properties: + name: + description: Name name is mandatory when specifying + the ports configuration. + type: string + priority: + anyOf: + - type: integer + - type: string + description: |- + Priority Deserialize and serialize from/to `priority`. + When applying, if defined, it will override the current bond port + priority. The verification will fail if bonding mode is not + active-backup(1) or balance-tlb (5) or balance-alb (6). + x-kubernetes-int-or-string: true + queue-id: + anyOf: + - type: integer + - type: string + description: QueueID Deserialize and serialize + from/to `queue-id`. + x-kubernetes-int-or-string: true + required: + - name + type: object + type: array + type: object + lldp: + description: Lldp Link Layer Discovery Protocol configurations. + properties: + enabled: + type: boolean + neighbors: + items: + items: + properties: + _description: + type: string + chassis-id: + type: string + chassis-id-type: + enum: + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + type: integer + ieee-802-1-ppvids: + items: + format: int32 + type: integer + type: array + ieee-802-1-vlans: + items: + properties: + name: + type: string + vid: + format: int32 + type: integer + type: object + type: array + ieee-802-3-mac-phy-conf: + properties: + autoneg: + type: boolean + operational-mau-type: + type: integer + pmd-autoneg-cap: + type: integer + type: object + ieee-802-3-max-frame-size: + format: int32 + type: integer + management-addresses: + items: + properties: + address: + type: string + address-subtype: + enum: + - Unknown + - IPv4 + - IPv6 + - MAC + type: string + interface-number: + format: int32 + type: integer + interface-number-subtype: + format: int32 + type: integer + type: object + type: array + oui: + allOf: + - enum: + - 00:80:c2 + - 00:12:0f + - 00:80:c2 + - 00:12:0f + - enum: + - 00:80:c2 + - 00:12:0f + - 00:80:c2 + - 00:12:0f + - enum: + - 00:80:c2 + - 00:12:0f + - 00:80:c2 + - 00:12:0f + - enum: + - 00:80:c2 + - 00:12:0f + - 00:80:c2 + - 00:12:0f + type: string + port-id: + type: string + port-id-type: + enum: + - 0 + - 1 + - 2 + - 3 + - 4 + - 5 + - 6 + - 7 + type: integer + subtype: + allOf: + - enum: + - 3 + - 1 + - 2 + - 4 + - enum: + - 3 + - 1 + - 2 + - 4 + - enum: + - 3 + - 1 + - 2 + - 4 + - enum: + - 3 + - 1 + - 2 + - 4 + type: integer + system-capabilities: + items: + type: string + type: array + system-description: + type: string + system-name: + type: string + type: + allOf: + - enum: + - 1 + - 2 + - 5 + - 6 + - 7 + - 8 + - 127 + - enum: + - 1 + - 2 + - 5 + - 6 + - 7 + - 8 + - 127 + - enum: + - 1 + - 2 + - 5 + - 6 + - 7 + - 8 + - 127 + - enum: + - 1 + - 2 + - 5 + - 6 + - 7 + - 8 + - 127 + - enum: + - 1 + - 2 + - 5 + - 6 + - 7 + - 8 + - 127 + - enum: + - 1 + - 2 + - 5 + - 6 + - 7 + - 8 + - 127 + - enum: + - 1 + - 2 + - 5 + - 6 + - 7 + - 8 + - 127 + - enum: + - 1 + - 2 + - 5 + - 6 + - 7 + - 8 + - 127 + - enum: + - 1 + - 2 + - 5 + - 6 + - 7 + - 8 + - 127 + - enum: + - 1 + - 2 + - 5 + - 6 + - 7 + - 8 + - 127 + type: integer + type: object + type: array + type: array + required: + - enabled + type: object + mac-address: + description: |- + MacAddress When applying with `[InterfaceIdentifier::MacAddress]`, + nmstate will store original desired interface name as `profile_name` + here and store the real interface name as `name` property. + For [InterfaceIdentifier::Name] (default), this property will change + the interface MAC address to desired one when applying. + For [InterfaceIdentifier::MacAddress], this property will be used + for searching interface on desired MAC address when applying. + MAC address in the format: upper case hex string separated by `:` on + every two characters. Case insensitive when applying. + Serialize and deserialize to/from `mac-address`. + type: string + mac-vlan: + description: MacVlan Deserialize and serialize from/to + `mac-vlan`. + properties: + base-iface: + type: string + mode: + enum: + - vepa + - bridge + - private + - passthru + - source + - unknown + type: string + promiscuous: + description: |- + AcceptAllMac Serialize to `promiscuous`. + Deserialize from `promiscuous` or `accept-all-mac`. + type: boolean + required: + - base-iface + - mode + type: object + mac-vtap: + description: MacVtap Deserialize and serialize from/to + `mac-vtap`. + properties: + base-iface: + type: string + mode: + enum: + - vepa + - bridge + - private + - passthru + - source + - unknown + type: string + promiscuous: + description: |- + AcceptAllMac Serialize to `promiscuous`. + Deserialize from `promiscuous` or `accept-all-mac`. + type: boolean + required: + - base-iface + - mode + type: object + macsec: + description: Macsec Deserialize and serialize to `macsec`. + properties: + base-iface: + description: BaseIface The parent interface used by + the MACsec interface. + type: string + encrypt: + description: Encrypt Wether the transmitted traffic + must be encrypted. + type: boolean + mka-cak: + description: |- + MkaCak The pre-shared CAK (Connectivity Association Key) for MACsec Key + Agreement. Must be a string of 32 hexadecimal characters. + type: string + mka-ckn: + description: |- + MkaCkn The pre-shared CKN (Connectivity-association Key Name) for MACsec Key + Agreement. Must be a string of hexadecimal characters with a even + length between 2 and 64. + type: string + offload: + enum: + - "off" + - phy + - mac + type: string + port: + description: |- + Port The port component of the SCI (Secure Channel Identifier), between 1 + and 65534. + format: int32 + type: integer + send-sci: + description: |- + SendSci Specifies whether the SCI (Secure Channel Identifier) is included in + every packet. + type: boolean + validation: + description: Validation Specifies the validation mode + for incoming frames. + enum: + - disabled + - check + - strict + type: string + required: + - base-iface + - encrypt + - port + - send-sci + - validation + type: object + max-mtu: + description: |- + MaxMtu Maximum MTU allowed. Ignored during apply. + Serialize and deserialize to/from `max-mtu`. + format: int64 + type: integer + min-mtu: + description: |- + MinMtu Minimum MTU allowed. Ignored during apply. + Serialize and deserialize to/from `min-mtu`. + format: int64 + type: integer + mptcp: + description: |- + Mptcp Interface wide MPTCP flags. + Nmstate will apply these flags to all valid IP addresses(both static + and dynamic). + properties: + address-flags: + description: |- + AddressFlags Automatically assign MPTCP flags to all valid IP addresses of this + interface including both static and dynamic ones. + items: + enum: + - signal + - subflow + - backup + - fullmesh + type: string + type: array + type: object + mtu: + anyOf: + - type: integer + - type: string + description: Mtu Maximum transmission unit. + x-kubernetes-int-or-string: true + name: + description: |- + Name Interface name, when applying with `InterfaceIdentifier::MacAddress`, + if `profile_name` not defined, this will be used as profile name. + type: string + ovs-db: + description: Ovsdb Interface specific OpenvSwitch database + configurations. + properties: + external_ids: + additionalProperties: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + other_config: + additionalProperties: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + description: |- + OtherConfig OpenvSwitch specific `other_config`. Please refer to + manpage `ovs-vswitchd.conf.db(5)` for more detail. + When setting to None, nmstate will try to preserve current + `other_config`, otherwise, nmstate will override all `other_config` + for specified interface. + type: object + type: object + patch: + properties: + peer: + type: string + type: object + profile-name: + type: string + state: + description: State Interface state. Default to [InterfaceState::Up] + when applying. + enum: + - up + - down + - absent + - unknown + - ignore + type: string + type: + description: Type Interface type. Serialize and deserialize + to/from `type` + enum: + - bond + - linux-bridge + - dummy + - ethernet + - hsr + - loopback + - mac-vlan + - mac-vtap + - ovs-bridge + - ovs-interface + - veth + - vlan + - vrf + - vxlan + - infiniband + - tun + - macsec + - ipsec + - xfrm + - unknown + type: string + veth: + description: |- + Veth When applying, the [VethConfig] is only valid when + [BaseInterface.iface_type] is set to [InterfaceType::Veth] explicitly. + properties: + peer: + description: Peer The name of veth peer. + type: string + type: object + vlan: + properties: + base-iface: + type: string + id: + type: integer + loose-binding: + description: LooseBinding loose binding of the interface + to its master device's operating state + type: boolean + protocol: + description: Protocol Could be `802.1q` or `802.1ad`. + Default to `802.1q` if not defined. + enum: + - 802.1q + - 802.1ad + type: string + registration-protocol: + description: RegistrationProtocol Could be `gvrp`, + `mvrp` or `none`. Default to none if not defined. + enum: + - gvrp + - mvrp + - none + type: string + reorder-headers: + description: ReorderHeaders reordering of output packet + headers + type: boolean + required: + - base-iface + - id + type: object + vrf: + properties: + port: + description: |- + Port Port list. + Deserialize and serialize from/to `port`. + Also deserialize from `ports`. + items: + type: string + type: array + route-table-id: + description: |- + TableID Route table ID of this VRF interface. + Use 0 to preserve current `table_id`. + Deserialize and serialize from/to `route-table-id`. + format: int32 + type: integer + required: + - port + type: object + vxlan: + properties: + base-iface: + type: string + destination-port: + anyOf: + - type: integer + - type: string + description: DstPort Deserialize and serialize from/to + `destination-port`. + x-kubernetes-int-or-string: true + id: + format: int32 + type: integer + learning: + type: boolean + local: + type: string + remote: + type: string + required: + - id + type: object + wait-ip: + description: |- + WaitIP Whether system should wait certain IP stack before considering + network interface activated. + Serialize and deserialize to/from `wait-ip`. + enum: + - any + - ipv4 + - ipv6 + - ipv4+ipv6 + type: string + required: + - name + type: object + type: array + ovn: + description: OVN The OVN configuration in the system + properties: + bridge-mappings: + items: + properties: + bridge: + type: string + localnet: + type: string + state: + description: |- + State When set to `state: absent`, will delete the existing + `localnet` mapping. + enum: + - present + - absent + type: string + required: + - localnet + type: object + type: array + type: object + ovs-db: + description: Ovsdb The global configurations of OpenvSwitach + daemon + properties: + external_ids: + additionalProperties: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + other_config: + additionalProperties: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + type: object + type: object + route-rules: + description: Rules Route rule, deserialize and serialize from/to + `route-rules`. + properties: + config: + description: |- + Config When applying, `None` means preserve existing route rules. + Nmstate is using partial editing for route rule, which means + desired route rules only append to existing instead of overriding. + To delete any route rule, please set [crate::RouteRuleEntry.state] to + [RouteRuleState::Absent]. Any property set to None in absent route rule + means wildcard. For example, this [crate::NetworkState] will delete all + route rule looking up route table 500: + ```yml + --- + route-rules: + config: + - state: absent + route-table: 500 + ``` + items: + properties: + action: + description: Action Actions for matching packages. + enum: + - blackhole + - unreachable + - prohibit + type: string + family: + description: Family Indicate the address family of + the route rule. + enum: + - ipv4 + - ipv6 + - unknown + type: string + fwmark: + anyOf: + - type: integer + - type: string + description: Fwmark Select the fwmark value to match + x-kubernetes-int-or-string: true + fwmask: + anyOf: + - type: integer + - type: string + description: Fwmask Select the fwmask value to match + x-kubernetes-int-or-string: true + iif: + description: Iif Incoming interface. + type: string + ip-from: + description: |- + IPFrom Source prefix to match. + Serialize and deserialize to/from `ip-from`. + When setting to empty string in absent route rule, it will only delete + route rule __without__ `ip-from`. + type: string + ip-to: + description: |- + IPTo Destination prefix to match. + Serialize and deserialize to/from `ip-to`. + When setting to empty string in absent route rule, it will only delete + route rule __without__ `ip-to`. + type: string + priority: + anyOf: + - type: integer + - type: string + description: |- + Priority Priority of this route rule. + Bigger number means lower priority. + x-kubernetes-int-or-string: true + route-table: + anyOf: + - type: integer + - type: string + description: |- + TableID The routing table ID to lookup if the rule selector matches. + Serialize and deserialize to/from `route-table`. + x-kubernetes-int-or-string: true + state: + description: State Indicate this is normal route rule + or absent route rule. + enum: + - absent + type: string + suppress-prefix-length: + description: |- + SuppressPrefixLength Prefix length of suppressor. + Can deserialize from `suppress-prefix-length` or + `suppress_prefixlength`. + Serialize into `suppress-prefix-length`. + format: int32 + type: integer + type: object + type: array + type: object + routes: + description: Routes Route + properties: + config: + description: |- + Config Static routes containing route from universe or link scope, + and only from these protocols: + * boot (often used by `iproute` command) + * static + + + When applying, `None` means preserve current routes. + This property is not overriding but adding specified routes to + existing routes. To delete a route entry, please [RouteEntry.state] as + [RouteState::Absent]. Any property of absent [RouteEntry] set to + `None` means wildcard. For example, this [crate::NetworkState] could + remove all routes next hop to interface eth1(showing in yaml): + ```yaml + routes: + config: + - next-hop-interface: eth1 + state: absent + ``` + + + To change a route entry, you need to delete old one and add new one(can + be in single transaction). + items: + description: RouteEntry Route entry + properties: + cwnd: + description: Cwnd Congestion window clamp + format: int32 + type: integer + destination: + description: |- + Destination Route destination address or network + Mandatory for every non-absent routes. + type: string + metric: + anyOf: + - type: integer + - type: string + description: |- + Metric Route metric. [RouteEntry::USE_DEFAULT_METRIC] for default + setting of network backend. + x-kubernetes-int-or-string: true + next-hop-address: + description: |- + NextHopAddr Route next hop IP address. + Serialize and deserialize to/from `next-hop-address`. + When setting this as empty string for absent route, it will only delete + routes __without__ `next-hop-address`. + type: string + next-hop-interface: + description: |- + NextHopIface Route next hop interface name. + Serialize and deserialize to/from `next-hop-interface`. + Mandatory for every non-absent routes except for route with + route type `Blackhole`, `Unreachable`, `Prohibit`. + type: string + route-type: + description: |- + RouteType Route type + Serialize and deserialize to/from `route-type`. + enum: + - blackhole + - unreachable + - prohibit + type: string + state: + description: State Only used for delete route when + applying. + enum: + - absent + type: string + table-id: + anyOf: + - type: integer + - type: string + description: |- + TableID Route table id. [RouteEntry::USE_DEFAULT_ROUTE_TABLE] for main + route table 254. + x-kubernetes-int-or-string: true + weight: + anyOf: + - type: integer + - type: string + description: |- + Weight ECMP(Equal-Cost Multi-Path) route weight + The valid range of this property is 1-256. + x-kubernetes-int-or-string: true + type: object + type: array + running: + description: |- + Running Running effected routes containing route from universe or link scope, + and only from these protocols: + * boot (often used by `iproute` command) + * static + * ra + * dhcp + * mrouted + * keepalived + * babel + + + Ignored when applying. + items: + description: RouteEntry Route entry + properties: + cwnd: + description: Cwnd Congestion window clamp + format: int32 + type: integer + destination: + description: |- + Destination Route destination address or network + Mandatory for every non-absent routes. + type: string + metric: + anyOf: + - type: integer + - type: string + description: |- + Metric Route metric. [RouteEntry::USE_DEFAULT_METRIC] for default + setting of network backend. + x-kubernetes-int-or-string: true + next-hop-address: + description: |- + NextHopAddr Route next hop IP address. + Serialize and deserialize to/from `next-hop-address`. + When setting this as empty string for absent route, it will only delete + routes __without__ `next-hop-address`. + type: string + next-hop-interface: + description: |- + NextHopIface Route next hop interface name. + Serialize and deserialize to/from `next-hop-interface`. + Mandatory for every non-absent routes except for route with + route type `Blackhole`, `Unreachable`, `Prohibit`. + type: string + route-type: + description: |- + RouteType Route type + Serialize and deserialize to/from `route-type`. + enum: + - blackhole + - unreachable + - prohibit + type: string + state: + description: State Only used for delete route when + applying. + enum: + - absent + type: string + table-id: + anyOf: + - type: integer + - type: string + description: |- + TableID Route table id. [RouteEntry::USE_DEFAULT_ROUTE_TABLE] for main + route table 254. + x-kubernetes-int-or-string: true + weight: + anyOf: + - type: integer + - type: string + description: |- + Weight ECMP(Equal-Cost Multi-Path) route weight + The valid range of this property is 1-256. + x-kubernetes-int-or-string: true + type: object + type: array + type: object + type: object + type: object + type: object + served: true + storage: true diff --git a/test/crd/setup-testenv.sh b/test/crd/setup-testenv.sh new file mode 100755 index 0000000..5d98708 --- /dev/null +++ b/test/crd/setup-testenv.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# This script install ectd and kube-apiserver at build/_output/bin the steps +# has being copied from kubebuilder container [1] +# +# [1] https://github.com/kubernetes-sigs/kubebuilder/blob/master/build/thirdparty/linux/Dockerfile + +set -xe + +etcd_version=v3.4.27 +apisever_version=v1.26.0 +output_dir=.k8s +bin_dir=$output_dir/bin/ + +etcd_tarball=etcd-${etcd_version}-linux-amd64.tar.gz +apiserver_tarball=kubernetes-server-linux-amd64.tar.gz + +mkdir -p $bin_dir + +if [ ! -f $bin_dir/kube-apiserver ]; then + curl -L https://dl.k8s.io/$apisever_version/$apiserver_tarball | tar xz -C $output_dir + mv $output_dir/kubernetes/server/bin/kube-apiserver $bin_dir +fi + +if [ ! -f $bin_dir/etcd ]; then + curl -L https://github.com/coreos/etcd/releases/download/$etcd_version/$etcd_tarball | tar xz -C $output_dir + mv $output_dir/etcd-$etcd_version-linux-amd64/etcd $bin_dir +fi diff --git a/test/crd/types.go b/test/crd/types.go new file mode 100644 index 0000000..0f2137a --- /dev/null +++ b/test/crd/types.go @@ -0,0 +1,38 @@ +//go:generate ./controller-gen.sh object:headerFile="boilerplate.go.txt" paths="." +//go:generate ./controller-gen.sh crd paths="." output:crd:artifacts:config=. +package v2 + +import ( + nmstatev2 "github.com/nmstate/kubernetes-go-api/v2" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// +genclient +// +kubebuilder:object:root=true +// +kubebuilder:resource:path=clusternetworkstate,shortName=cns,scope=Cluster +// +kubebuilder:storageversion + +// ClusterNetworkState is the Schema for the nodenetworkconfigurationpolicies API +type ClusterNetworkState struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec ClusterNetworkStateSpec `json:"spec,omitempty"` +} + +// +k8s:deepcopy-gen=true +type ClusterNetworkStateSpec struct { + State nmstatev2.NetworkState `json:"state,omitempty"` +} + +// +kubebuilder:object:root=true + +type ClusterNetworkStateList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []ClusterNetworkState `json:"items"` +} + +func init() { + SchemeBuilder.Register(&ClusterNetworkState{}, &ClusterNetworkStateList{}) +} diff --git a/test/crd/types_test.go b/test/crd/types_test.go new file mode 100644 index 0000000..236dc0c --- /dev/null +++ b/test/crd/types_test.go @@ -0,0 +1,126 @@ +package v2 + +import ( + "context" + "fmt" + "io/fs" + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + + "github.com/stretchr/testify/require" + + "go.uber.org/zap/zapcore" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + utilrand "k8s.io/apimachinery/pkg/util/rand" + + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/envtest" + logf "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/controller-runtime/pkg/log/zap" + "sigs.k8s.io/yaml" +) + +const yamlPathKey = "yaml-path" + +func testUnmarshalDir(t *testing.T, dir string) []ClusterNetworkState { + states := []ClusterNetworkState{} + err := filepath.Walk(dir, func(path string, info fs.FileInfo, err error) error { + if err != nil { + return err + } + if info.IsDir() && info.Name() == "policy" { + return filepath.SkipDir + } + if info.IsDir() || filepath.Ext(info.Name()) != ".yml" || strings.Contains(info.Name(), "rollback") { + return nil + } + state, err := ioutil.ReadFile(path) + if err != nil { + return fmt.Errorf("failed reading state '%s': %v", info.Name(), err) + } + clusterNetworkState := ClusterNetworkState{ + ObjectMeta: metav1.ObjectMeta{ + Name: generateName("test"), + Annotations: map[string]string{ + yamlPathKey: path, + "yaml-file": info.Name(), + }, + }, + } + err = yaml.Unmarshal(state, &clusterNetworkState.Spec.State) + if err != nil { + return err + } + states = append(states, clusterNetworkState) + return nil + }) + + require.NoError(t, err, "must succeed reading states") + require.NotEmpty(t, states, "missing test/integration output to test") + return states +} +func TestCRD(t *testing.T) { + tests := []struct { + name, dir string + }{ + { + name: "examples", + dir: os.Getenv("NMSTATE_SOURCE_INSTALL_DIR") + "/examples", + }, + { + name: "e2e-dump", + dir: os.Getenv("NMSTATE_E2E_DUMP"), + }, + } + logf.SetLogger(zap.New(zap.Level(zapcore.DebugLevel))) + + t.Log("Installing apiserver and etcd") + output, err := exec.Command("./setup-testenv.sh").CombinedOutput() + require.NoError(t, err, output) + + // specify testEnv configuration + testEnv := &envtest.Environment{ + BinaryAssetsDirectory: ".k8s/bin", CRDDirectoryPaths: []string{"."}, + } + + t.Log("Starting apiserver and etcd to deploy CRDs") + cfg, err := testEnv.Start() + defer func() { + t.Log("Stoping apiserver and etcd") + testEnv.Stop() + }() + require.NoError(t, err) + + err = AddToScheme(testEnv.Scheme) + require.NoError(t, err) + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + states := testUnmarshalDir(t, tt.dir) + + cli, err := client.New(cfg, client.Options{Scheme: testEnv.Scheme}) + require.NoError(t, err) + + for _, state := range states { + t.Run(state.Annotations["yaml-file"], func(t *testing.T) { + err = cli.Create(context.Background(), &state) + require.NoError(t, err, state.Annotations[yamlPathKey]) + }) + } + }) + } +} + +func generateName(base string) string { + maxNameLength := 100 + randomLength := 10 + maxGeneratedNameLength := maxNameLength - randomLength + if len(base) > maxGeneratedNameLength { + base = base[:maxGeneratedNameLength] + } + return fmt.Sprintf("%s%s", base, utilrand.String(randomLength)) +} diff --git a/test/crd/zz_generated.deepcopy.go b/test/crd/zz_generated.deepcopy.go new file mode 100644 index 0000000..3962a19 --- /dev/null +++ b/test/crd/zz_generated.deepcopy.go @@ -0,0 +1,99 @@ +//go:build !ignore_autogenerated + +/* +Copyright The NMState Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v2 + +import ( + runtime "k8s.io/apimachinery/pkg/runtime" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterNetworkState) DeepCopyInto(out *ClusterNetworkState) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterNetworkState. +func (in *ClusterNetworkState) DeepCopy() *ClusterNetworkState { + if in == nil { + return nil + } + out := new(ClusterNetworkState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterNetworkState) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterNetworkStateList) DeepCopyInto(out *ClusterNetworkStateList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]ClusterNetworkState, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterNetworkStateList. +func (in *ClusterNetworkStateList) DeepCopy() *ClusterNetworkStateList { + if in == nil { + return nil + } + out := new(ClusterNetworkStateList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *ClusterNetworkStateList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ClusterNetworkStateSpec) DeepCopyInto(out *ClusterNetworkStateSpec) { + *out = *in + in.State.DeepCopyInto(&out.State) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterNetworkStateSpec. +func (in *ClusterNetworkStateSpec) DeepCopy() *ClusterNetworkStateSpec { + if in == nil { + return nil + } + out := new(ClusterNetworkStateSpec) + in.DeepCopyInto(out) + return out +} diff --git a/test/go.mod b/test/go.mod new file mode 100644 index 0000000..9878f31 --- /dev/null +++ b/test/go.mod @@ -0,0 +1,62 @@ +module github.com/nmstate/kubernetes-go-api/test + +go 1.22.0 + +toolchain go1.22.2 + +require ( + github.com/nmstate/kubernetes-go-api/v2 v2.0.0 + github.com/stretchr/testify v1.9.0 + go.uber.org/zap v1.27.0 + k8s.io/apimachinery v0.30.0 + sigs.k8s.io/controller-runtime v0.18.1 + sigs.k8s.io/yaml v1.4.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/emicklei/go-restful/v3 v3.11.0 // indirect + github.com/evanphx/json-patch/v5 v5.9.0 // indirect + github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/zapr v1.3.0 // indirect + github.com/go-openapi/jsonpointer v0.19.6 // indirect + github.com/go-openapi/jsonreference v0.20.2 // indirect + github.com/go-openapi/swag v0.22.3 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/gnostic-models v0.6.8 // indirect + github.com/google/gofuzz v1.2.0 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/imdario/mergo v0.3.6 // indirect + github.com/josharian/intern v1.0.0 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/mailru/easyjson v0.7.7 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/net v0.23.0 // indirect + golang.org/x/oauth2 v0.12.0 // indirect + golang.org/x/sys v0.18.0 // indirect + golang.org/x/term v0.18.0 // indirect + golang.org/x/text v0.14.0 // indirect + golang.org/x/time v0.3.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.33.0 // indirect + gopkg.in/inf.v0 v0.9.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/api v0.30.0 // indirect + k8s.io/apiextensions-apiserver v0.30.0 // indirect + k8s.io/client-go v0.30.0 // indirect + k8s.io/klog/v2 v2.120.1 // indirect + k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect + k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect + sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect + sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect +) + +replace github.com/nmstate/kubernetes-go-api/v2 => ../v2 diff --git a/test/go.sum b/test/go.sum new file mode 100644 index 0000000..d81cfcb --- /dev/null +++ b/test/go.sum @@ -0,0 +1,192 @@ +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= +github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v4.12.0+incompatible h1:4onqiflcdA9EOZ4RxV643DvftH5pOlLGNtQ5lPWQu84= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch/v5 v5.9.0 h1:kcBlZQbplgElYIlo/n1hJbls2z/1awpXxpRi0/FOJfg= +github.com/evanphx/json-patch/v5 v5.9.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= +github.com/go-logr/zapr v1.3.0/go.mod h1:YKepepNBd1u/oyhd/yQmtjVXmm9uML4IXUgMOwR8/Gg= +github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= +github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= +github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= +github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= +github.com/go-openapi/swag v0.22.3 h1:yMBqmnQ0gyZvEb/+KzuWZOXgllrXT4SADYbvDaXHv/g= +github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= +github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= +github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= +github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= +github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= +github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= +github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= +github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_golang v1.16.0 h1:yk/hx9hDbrGHovbci4BY+pRMfSuuat626eFsHb7tmT8= +github.com/prometheus/client_golang v1.16.0/go.mod h1:Zsulrv/L9oM40tJ7T815tM89lFEugiJ9HzIqaAx4LKc= +github.com/prometheus/client_model v0.4.0 h1:5lQXD3cAg1OXBf4Wq03gTrXHeaV0TQvGfUooCfx1yqY= +github.com/prometheus/client_model v0.4.0/go.mod h1:oMQmHW1/JoDwqLtg57MGgP/Fb1CJEYF2imWWhWtMkYU= +github.com/prometheus/common v0.44.0 h1:+5BrQJwiBB9xsMygAB3TNvpQKOwlkc25LbISbrdOOfY= +github.com/prometheus/common v0.44.0/go.mod h1:ofAIvZbQ1e/nugmZGz4/qCb9Ap1VoSTIO7x0VV9VvuY= +github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= +github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8= +go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4= +golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= +golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gomodules.xyz/jsonpatch/v2 v2.4.0 h1:Ci3iUJyx9UeRx7CeFN8ARgGbkESwJK+KB9lLcWxY/Zw= +gomodules.xyz/jsonpatch/v2 v2.4.0/go.mod h1:AH3dM2RI6uoBZxn3LVrfvJ3E0/9dG4cSrbuBJT4moAY= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= +google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/api v0.30.0 h1:siWhRq7cNjy2iHssOB9SCGNCl2spiF1dO3dABqZ8niA= +k8s.io/api v0.30.0/go.mod h1:OPlaYhoHs8EQ1ql0R/TsUgaRPhpKNxIMrKQfWUp8QSE= +k8s.io/apiextensions-apiserver v0.30.0 h1:jcZFKMqnICJfRxTgnC4E+Hpcq8UEhT8B2lhBcQ+6uAs= +k8s.io/apiextensions-apiserver v0.30.0/go.mod h1:N9ogQFGcrbWqAY9p2mUAL5mGxsLqwgtUce127VtRX5Y= +k8s.io/apimachinery v0.30.0 h1:qxVPsyDM5XS96NIh9Oj6LavoVFYff/Pon9cZeDIkHHA= +k8s.io/apimachinery v0.30.0/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/client-go v0.30.0 h1:sB1AGGlhY/o7KCyCEQ0bPWzYDL0pwOZO4vAtTSh/gJQ= +k8s.io/client-go v0.30.0/go.mod h1:g7li5O5256qe6TYdAMyX/otJqMhIiGgTapdLchhmOaY= +k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= +k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 h1:BZqlfIlq5YbRMFko6/PM7FjZpUb45WallggurYhKGag= +k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.18.1 h1:RpWbigmuiylbxOCLy0tGnq1cU1qWPwNIQzoJk+QeJx4= +sigs.k8s.io/controller-runtime v0.18.1/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= +sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= +sigs.k8s.io/structured-merge-diff/v4 v4.4.1/go.mod h1:N8hJocpFajUSSeSJ9bOZ77VzejKZaXsTtZo4/u7Io08= +sigs.k8s.io/yaml v1.4.0 h1:Mk1wCc2gy/F0THH0TAp1QYyJNzRm2KCLy3o5ASXVI5E= +sigs.k8s.io/yaml v1.4.0/go.mod h1:Ejl7/uTz7PSA4eKMyQCUTnhZYNmLIl+5c2lQPGR2BPY= diff --git a/v2/.golangci.yml b/v2/.golangci.yml new file mode 100644 index 0000000..235f7c7 --- /dev/null +++ b/v2/.golangci.yml @@ -0,0 +1,108 @@ +linters-settings: + dupl: + threshold: 100 + funlen: + lines: -1 # the number of lines (code + empty lines) is not a right metric and leads to code without empty line or one-liner. + statements: 50 + goconst: + min-len: 2 + min-occurrences: 3 + gocritic: + enabled-tags: + - diagnostic + - experimental + - opinionated + - performance + - style + disabled-checks: + - dupImport # https://github.com/go-critic/go-critic/issues/845 + - ifElseChain + - octalLiteral + - whyNoLint + gocyclo: + min-complexity: 15 + gofmt: + rewrite-rules: + - pattern: 'interface{}' + replacement: 'any' + goheader: + template-path: boilerplate.go.txt + gomnd: + # don't include the "operation" and "assign" + checks: + - argument + - case + - condition + - return + ignored-numbers: + - '0' + - '1' + - '2' + - '3' + ignored-functions: + - strings.SplitN + errorlint: + asserts: false + nolintlint: + allow-unused: false # report any unused nolint directives + require-explanation: false # don't require an explanation for nolint directives + require-specific: false # don't require nolint directives to be specific about which linter is being skipped + revive: + rules: + - name: unexported-return + disabled: true + - name: unused-parameter + +linters: + disable-all: true + enable: + - bodyclose + - depguard + - dogsled + - dupl + - errcheck + - errorlint + - exportloopref + - funlen + - gocheckcompilerdirectives + - gochecknoinits + - goconst + - gocritic + - gocyclo + - gofmt + - goimports + - gomnd + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + - nakedret + - noctx + - nolintlint + - revive + - staticcheck + - stylecheck + - typecheck + - unconvert + - unparam + - unused + - whitespace + + # don't enable: + # - asciicheck + # - scopelint + # - gochecknoglobals + # - gocognit + # - godot + # - godox + # - goerr113 + # - interfacer + # - maligned + # - nestif + # - prealloc + # - testpackage + # - wsl + +run: + timeout: 5m diff --git a/v2/encoding.go b/v2/encoding.go new file mode 100644 index 0000000..b14f837 --- /dev/null +++ b/v2/encoding.go @@ -0,0 +1,222 @@ +/* +Copyright The NMState Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v2 + +import ( + "bytes" + "encoding/json" + "errors" + "fmt" + "strings" +) + +func ReplaceDeprecatedNames(data []byte) []byte { + data = []byte(strings.ReplaceAll(string(data), `"slaves"`, `"port"`)) + data = []byte(strings.ReplaceAll(string(data), "slaves:", "port:")) + return data +} + +func (i *Interface) UnmarshalJSON(data []byte) error { + type InterfaceInternal Interface + var interfaceInternal InterfaceInternal + if err := strictDecoder(ReplaceDeprecatedNames(data)).Decode(&interfaceInternal); err != nil { + return err + } + *i = Interface(interfaceInternal) + return nil +} + +func (o *BridgeOptions) UnmarshalJSON(data []byte) error { + linuxBridgeOptions := LinuxBridgeOptions{} + ovsBridgeOptions := OVSBridgeOptions{} + + var linuxErr, ovsErr error + if linuxErr = strictDecoder(data).Decode(&linuxBridgeOptions); linuxErr == nil { + o.LinuxBridgeOptions = &linuxBridgeOptions + } else if ovsErr = strictDecoder(data).Decode(&ovsBridgeOptions); ovsErr == nil { + o.OVSBridgeOptions = &ovsBridgeOptions + } else { + return errors.Join(linuxErr, ovsErr) + } + return nil +} + +func (o BridgeOptions) MarshalJSON() ([]byte, error) { + if o.LinuxBridgeOptions != nil { + return json.Marshal(o.LinuxBridgeOptions) + } + if o.OVSBridgeOptions != nil { + return json.Marshal(o.OVSBridgeOptions) + } + return nil, nil +} + +func (o *BridgePortConfig) UnmarshalJSON(data []byte) error { + linuxBridgePortConfig := struct { + BridgePortConfigMetaData + *LinuxBridgePortConfig + }{} + ovsBridgePortConfig := struct { + BridgePortConfigMetaData + *OVSBridgePortConfig + }{} + var linuxErr, ovsErr error + if linuxErr = strictDecoder(data).Decode(&linuxBridgePortConfig); linuxErr == nil { + o.BridgePortConfigMetaData = linuxBridgePortConfig.BridgePortConfigMetaData + o.LinuxBridgePortConfig = linuxBridgePortConfig.LinuxBridgePortConfig + } else if ovsErr = strictDecoder(data).Decode(&ovsBridgePortConfig); ovsErr == nil { + o.BridgePortConfigMetaData = ovsBridgePortConfig.BridgePortConfigMetaData + o.OVSBridgePortConfig = ovsBridgePortConfig.OVSBridgePortConfig + } else { + return errors.Join(linuxErr, ovsErr) + } + return nil +} + +func (o BridgePortConfig) MarshalJSON() ([]byte, error) { + if o.LinuxBridgePortConfig != nil { + return json.Marshal(struct { + BridgePortConfigMetaData + *LinuxBridgePortConfig + }{ + o.BridgePortConfigMetaData, + o.LinuxBridgePortConfig, + }) + } + if o.OVSBridgePortConfig != nil { + return json.Marshal(struct { + BridgePortConfigMetaData + *OVSBridgePortConfig + }{ + o.BridgePortConfigMetaData, + o.OVSBridgePortConfig, + }) + } + return json.Marshal(o.BridgePortConfigMetaData) +} + +func (o *OVSBridgeStpOptions) UnmarshalJSON(data []byte) error { + if err := json.Unmarshal(data, &o.Enabled); err == nil { + return nil + } + type ovsBridgeStpOptions OVSBridgeStpOptions + stp := ovsBridgeStpOptions{} + if err := json.Unmarshal(data, &stp); err != nil { + return err + } + o.Enabled = stp.Enabled + return nil +} + +func (o OVSBridgeStpOptions) MarshalJSON() ([]byte, error) { + type ovsBridgeStpOptions OVSBridgeStpOptions + stp := ovsBridgeStpOptions{} + stp.Enabled = o.Enabled + return json.Marshal(&stp) +} + +func (o *LldpNeighborTlv) MarshalJSON() ([]byte, error) { + if o.LldpSystemName != nil { + return json.Marshal(o.LldpSystemName) + } else if o.LldpSystemDescription != nil { + return json.Marshal(o.LldpSystemDescription) + } else if o.LldpSystemCapabilities != nil { + return json.Marshal(o.LldpSystemCapabilities) + } else if o.LldpChassisID != nil { + return json.Marshal(o.LldpChassisID) + } else if o.LldpPortID != nil { + return json.Marshal(o.LldpPortID) + } else if o.LldpVlans != nil { + return json.Marshal(o.LldpVlans) + } else if o.LldpMacPhy != nil { + return json.Marshal(o.LldpMacPhy) + } else if o.LldpPpvids != nil { + return json.Marshal(o.LldpPpvids) + } else if o.LldpMgmtAddrs != nil { + return json.Marshal(o.LldpMgmtAddrs) + } else if o.LldpMaxFrameSize != nil { + return json.Marshal(o.LldpMaxFrameSize) + } else { + return nil, fmt.Errorf("unexpected LldpNeighborTlv: %+v", o) + } +} + +func (o *LldpNeighborTlv) UnmarshalJSON(data []byte) error { + neighbor := struct { + Type LldpNeighborTlvType + Subtype *LldpOrgSubtype + }{} + if err := json.Unmarshal(data, &neighbor); err != nil { + return fmt.Errorf("failed unmarshaling type and subtype: %w", err) + } + switch neighbor.Type { + case LldpNeighborTlvTypeSystemName: + o.LldpSystemName = &LldpSystemName{} + return strictDecoder(data).Decode(o.LldpSystemName) + case LldpNeighborTlvTypeSystemDescription: + o.LldpSystemDescription = &LldpSystemDescription{} + return strictDecoder(data).Decode(o.LldpSystemDescription) + case LldpNeighborTlvTypeSystemCapabilities: + o.LldpSystemCapabilities = &LldpSystemCapabilities{} + return strictDecoder(data).Decode(o.LldpSystemCapabilities) + case LldpNeighborTlvTypeChassisID: + o.LldpChassisID = &LldpChassisID{} + return strictDecoder(data).Decode(o.LldpChassisID) + case LldpNeighborTlvTypePort: + o.LldpPortID = &LldpPortID{} + return strictDecoder(data).Decode(o.LldpPortID) + case LldpNeighborTlvTypeManagementAddress: + o.LldpMgmtAddrs = &LldpMgmtAddrs{} + return strictDecoder(data).Decode(o.LldpMgmtAddrs) + case LldpNeighborTlvTypeOrganizationSpecific: + if neighbor.Subtype == nil { + return fmt.Errorf("missing lldp neighbor org subtype") + } + switch *neighbor.Subtype { + case LldpOrgSubtypeVlan: + o.LldpVlans = &LldpVlans{} + return strictDecoder(data).Decode(o.LldpVlans) + case LldpOrgSubtypePpvids: + o.LldpPpvids = &LldpPpvids{} + return strictDecoder(data).Decode(o.LldpPpvids) + case LldpOrgSubtypeMacPhyConf: + o.LldpMacPhy = &LldpMacPhy{} + return strictDecoder(data).Decode(o.LldpMacPhy) + case LldpOrgSubtypeMaxFrameSize: + o.LldpMaxFrameSize = &LldpMaxFrameSize{} + return strictDecoder(data).Decode(o.LldpMaxFrameSize) + default: + return fmt.Errorf("unknown lldp neighbor org subtype: %+v", neighbor.Subtype) + } + default: + return fmt.Errorf("unknown lldp neighbor type: %+v", neighbor.Type) + } +} + +func strictDecoder(data []byte) *json.Decoder { + decoder := json.NewDecoder(bytes.NewBuffer(data)) + decoder.DisallowUnknownFields() + return decoder +} + +func (s NetworkState) String() string { + raw, err := json.Marshal(&s) + if err != nil { + return "" + } + return string(raw) +} diff --git a/v2/go.mod b/v2/go.mod new file mode 100644 index 0000000..855a665 --- /dev/null +++ b/v2/go.mod @@ -0,0 +1,21 @@ +module github.com/nmstate/kubernetes-go-api/v2 + +go 1.21 + +require ( + github.com/stretchr/testify v1.8.1 + k8s.io/apimachinery v0.27.4 + sigs.k8s.io/yaml v1.3.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/gogo/protobuf v1.3.2 // indirect + github.com/google/gofuzz v1.1.0 // indirect + github.com/jstemmer/go-junit-report/v2 v2.1.0 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + k8s.io/klog/v2 v2.90.1 // indirect +) diff --git a/v2/go.sum b/v2/go.sum new file mode 100644 index 0000000..f26aa4a --- /dev/null +++ b/v2/go.sum @@ -0,0 +1,64 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/jstemmer/go-junit-report/v2 v2.1.0 h1:X3+hPYlSczH9IMIpSC9CQSZA0L+BipYafciZUWHEmsc= +github.com/jstemmer/go-junit-report/v2 v2.1.0/go.mod h1:mgHVr7VUo5Tn8OLVr1cKnLuEy0M92wdRntM99h7RkgQ= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +k8s.io/apimachinery v0.27.4 h1:CdxflD4AF61yewuid0fLl6bM4a3q04jWel0IlP+aYjs= +k8s.io/apimachinery v0.27.4/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= +k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw= +k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= diff --git a/v2/zz_generated.deepcopy.go b/v2/zz_generated.deepcopy.go new file mode 100644 index 0000000..3537dc8 --- /dev/null +++ b/v2/zz_generated.deepcopy.go @@ -0,0 +1,3357 @@ +//go:build !ignore_autogenerated + +/* +Copyright The NMState Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by controller-gen. DO NOT EDIT. + +package v2 + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BaseInterface) DeepCopyInto(out *BaseInterface) { + *out = *in + if in.ProfileName != nil { + in, out := &in.ProfileName, &out.ProfileName + *out = new(string) + **out = **in + } + if in.Description != nil { + in, out := &in.Description, &out.Description + *out = new(string) + **out = **in + } + if in.Driver != nil { + in, out := &in.Driver, &out.Driver + *out = new(string) + **out = **in + } + if in.Identifier != nil { + in, out := &in.Identifier, &out.Identifier + *out = new(InterfaceIdentifier) + **out = **in + } + if in.MacAddress != nil { + in, out := &in.MacAddress, &out.MacAddress + *out = new(string) + **out = **in + } + if in.Mtu != nil { + in, out := &in.Mtu, &out.Mtu + *out = new(intstr.IntOrString) + **out = **in + } + if in.MinMtu != nil { + in, out := &in.MinMtu, &out.MinMtu + *out = new(uint64) + **out = **in + } + if in.MaxMtu != nil { + in, out := &in.MaxMtu, &out.MaxMtu + *out = new(uint64) + **out = **in + } + if in.WaitIP != nil { + in, out := &in.WaitIP, &out.WaitIP + *out = new(WaitIP) + **out = **in + } + if in.Ipv4 != nil { + in, out := &in.Ipv4, &out.Ipv4 + *out = new(InterfaceIP) + (*in).DeepCopyInto(*out) + } + if in.Ipv6 != nil { + in, out := &in.Ipv6, &out.Ipv6 + *out = new(InterfaceIP) + (*in).DeepCopyInto(*out) + } + if in.Mptcp != nil { + in, out := &in.Mptcp, &out.Mptcp + *out = new(MptcpConfig) + (*in).DeepCopyInto(*out) + } + if in.Controller != nil { + in, out := &in.Controller, &out.Controller + *out = new(string) + **out = **in + } + if in.AcceptAllMacAddresses != nil { + in, out := &in.AcceptAllMacAddresses, &out.AcceptAllMacAddresses + *out = new(bool) + **out = **in + } + if in.CopyMacFrom != nil { + in, out := &in.CopyMacFrom, &out.CopyMacFrom + *out = new(string) + **out = **in + } + if in.Ovsdb != nil { + in, out := &in.Ovsdb, &out.Ovsdb + *out = new(OVSDBIfaceConfig) + (*in).DeepCopyInto(*out) + } + if in.Ieee8021X != nil { + in, out := &in.Ieee8021X, &out.Ieee8021X + *out = new(Ieee8021XConfig) + (*in).DeepCopyInto(*out) + } + if in.Lldp != nil { + in, out := &in.Lldp, &out.Lldp + *out = new(LldpConfig) + (*in).DeepCopyInto(*out) + } + if in.Ethtool != nil { + in, out := &in.Ethtool, &out.Ethtool + *out = new(EthtoolConfig) + (*in).DeepCopyInto(*out) + } + if in.Dispatch != nil { + in, out := &in.Dispatch, &out.Dispatch + *out = new(DispatchConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BaseInterface. +func (in *BaseInterface) DeepCopy() *BaseInterface { + if in == nil { + return nil + } + out := new(BaseInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BondConfig) DeepCopyInto(out *BondConfig) { + *out = *in + if in.Mode != nil { + in, out := &in.Mode, &out.Mode + *out = new(BondMode) + **out = **in + } + if in.Options != nil { + in, out := &in.Options, &out.Options + *out = new(BondOptions) + (*in).DeepCopyInto(*out) + } + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new([]string) + if **in != nil { + in, out := *in, *out + *out = make([]string, len(*in)) + copy(*out, *in) + } + } + if in.PortsConfig != nil { + in, out := &in.PortsConfig, &out.PortsConfig + *out = new([]BondPortConfig) + if **in != nil { + in, out := *in, *out + *out = make([]BondPortConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BondConfig. +func (in *BondConfig) DeepCopy() *BondConfig { + if in == nil { + return nil + } + out := new(BondConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BondInterface) DeepCopyInto(out *BondInterface) { + *out = *in + if in.Bond != nil { + in, out := &in.Bond, &out.Bond + *out = new(BondConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BondInterface. +func (in *BondInterface) DeepCopy() *BondInterface { + if in == nil { + return nil + } + out := new(BondInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BondOptions) DeepCopyInto(out *BondOptions) { + *out = *in + if in.AdActorSysPrio != nil { + in, out := &in.AdActorSysPrio, &out.AdActorSysPrio + *out = new(intstr.IntOrString) + **out = **in + } + if in.AdActorSystem != nil { + in, out := &in.AdActorSystem, &out.AdActorSystem + *out = new(string) + **out = **in + } + if in.AdSelect != nil { + in, out := &in.AdSelect, &out.AdSelect + *out = new(BondAdSelect) + **out = **in + } + if in.AdUserPortKey != nil { + in, out := &in.AdUserPortKey, &out.AdUserPortKey + *out = new(intstr.IntOrString) + **out = **in + } + if in.AllSlavesActive != nil { + in, out := &in.AllSlavesActive, &out.AllSlavesActive + *out = new(BondAllPortsActive) + **out = **in + } + if in.ArpAllTargets != nil { + in, out := &in.ArpAllTargets, &out.ArpAllTargets + *out = new(BondArpAllTargets) + **out = **in + } + if in.ArpInterval != nil { + in, out := &in.ArpInterval, &out.ArpInterval + *out = new(intstr.IntOrString) + **out = **in + } + if in.ArpIPTarget != nil { + in, out := &in.ArpIPTarget, &out.ArpIPTarget + *out = new(string) + **out = **in + } + if in.ArpValidate != nil { + in, out := &in.ArpValidate, &out.ArpValidate + *out = new(BondArpValidate) + **out = **in + } + if in.Downdelay != nil { + in, out := &in.Downdelay, &out.Downdelay + *out = new(intstr.IntOrString) + **out = **in + } + if in.FailOverMac != nil { + in, out := &in.FailOverMac, &out.FailOverMac + *out = new(BondFailOverMac) + **out = **in + } + if in.LacpRate != nil { + in, out := &in.LacpRate, &out.LacpRate + *out = new(BondLacpRate) + **out = **in + } + if in.LpInterval != nil { + in, out := &in.LpInterval, &out.LpInterval + *out = new(intstr.IntOrString) + **out = **in + } + if in.Miimon != nil { + in, out := &in.Miimon, &out.Miimon + *out = new(intstr.IntOrString) + **out = **in + } + if in.MinLinks != nil { + in, out := &in.MinLinks, &out.MinLinks + *out = new(intstr.IntOrString) + **out = **in + } + if in.NumGratArp != nil { + in, out := &in.NumGratArp, &out.NumGratArp + *out = new(intstr.IntOrString) + **out = **in + } + if in.NumUnsolNa != nil { + in, out := &in.NumUnsolNa, &out.NumUnsolNa + *out = new(intstr.IntOrString) + **out = **in + } + if in.PacketsPerSlave != nil { + in, out := &in.PacketsPerSlave, &out.PacketsPerSlave + *out = new(intstr.IntOrString) + **out = **in + } + if in.Primary != nil { + in, out := &in.Primary, &out.Primary + *out = new(string) + **out = **in + } + if in.PrimaryReselect != nil { + in, out := &in.PrimaryReselect, &out.PrimaryReselect + *out = new(BondPrimaryReselect) + **out = **in + } + if in.ResendIgmp != nil { + in, out := &in.ResendIgmp, &out.ResendIgmp + *out = new(intstr.IntOrString) + **out = **in + } + if in.TlbDynamicLb != nil { + in, out := &in.TlbDynamicLb, &out.TlbDynamicLb + *out = new(bool) + **out = **in + } + if in.Updelay != nil { + in, out := &in.Updelay, &out.Updelay + *out = new(intstr.IntOrString) + **out = **in + } + if in.UseCarrier != nil { + in, out := &in.UseCarrier, &out.UseCarrier + *out = new(bool) + **out = **in + } + if in.XmitHashPolicy != nil { + in, out := &in.XmitHashPolicy, &out.XmitHashPolicy + *out = new(BondXmitHashPolicy) + **out = **in + } + if in.BalanceSlb != nil { + in, out := &in.BalanceSlb, &out.BalanceSlb + *out = new(bool) + **out = **in + } + if in.ArpMissedMax != nil { + in, out := &in.ArpMissedMax, &out.ArpMissedMax + *out = new(intstr.IntOrString) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BondOptions. +func (in *BondOptions) DeepCopy() *BondOptions { + if in == nil { + return nil + } + out := new(BondOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BondPortConfig) DeepCopyInto(out *BondPortConfig) { + *out = *in + if in.Priority != nil { + in, out := &in.Priority, &out.Priority + *out = new(intstr.IntOrString) + **out = **in + } + if in.QueueID != nil { + in, out := &in.QueueID, &out.QueueID + *out = new(intstr.IntOrString) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BondPortConfig. +func (in *BondPortConfig) DeepCopy() *BondPortConfig { + if in == nil { + return nil + } + out := new(BondPortConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BridgeConfig) DeepCopyInto(out *BridgeConfig) { + *out = *in + if in.OVSBridgeConfig != nil { + in, out := &in.OVSBridgeConfig, &out.OVSBridgeConfig + *out = new(OVSBridgeConfig) + (*in).DeepCopyInto(*out) + } + if in.Options != nil { + in, out := &in.Options, &out.Options + *out = new(BridgeOptions) + (*in).DeepCopyInto(*out) + } + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = new([]BridgePortConfig) + if **in != nil { + in, out := *in, *out + *out = make([]BridgePortConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BridgeConfig. +func (in *BridgeConfig) DeepCopy() *BridgeConfig { + if in == nil { + return nil + } + out := new(BridgeConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BridgeInterface) DeepCopyInto(out *BridgeInterface) { + *out = *in + if in.BridgeConfig != nil { + in, out := &in.BridgeConfig, &out.BridgeConfig + *out = new(BridgeConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BridgeInterface. +func (in *BridgeInterface) DeepCopy() *BridgeInterface { + if in == nil { + return nil + } + out := new(BridgeInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BridgeOptions) DeepCopyInto(out *BridgeOptions) { + *out = *in + if in.LinuxBridgeOptions != nil { + in, out := &in.LinuxBridgeOptions, &out.LinuxBridgeOptions + *out = new(LinuxBridgeOptions) + (*in).DeepCopyInto(*out) + } + if in.OVSBridgeOptions != nil { + in, out := &in.OVSBridgeOptions, &out.OVSBridgeOptions + *out = new(OVSBridgeOptions) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BridgeOptions. +func (in *BridgeOptions) DeepCopy() *BridgeOptions { + if in == nil { + return nil + } + out := new(BridgeOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BridgePortConfig) DeepCopyInto(out *BridgePortConfig) { + *out = *in + in.BridgePortConfigMetaData.DeepCopyInto(&out.BridgePortConfigMetaData) + if in.OVSBridgePortConfig != nil { + in, out := &in.OVSBridgePortConfig, &out.OVSBridgePortConfig + *out = new(OVSBridgePortConfig) + (*in).DeepCopyInto(*out) + } + if in.LinuxBridgePortConfig != nil { + in, out := &in.LinuxBridgePortConfig, &out.LinuxBridgePortConfig + *out = new(LinuxBridgePortConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BridgePortConfig. +func (in *BridgePortConfig) DeepCopy() *BridgePortConfig { + if in == nil { + return nil + } + out := new(BridgePortConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BridgePortConfigMetaData) DeepCopyInto(out *BridgePortConfigMetaData) { + *out = *in + if in.Vlan != nil { + in, out := &in.Vlan, &out.Vlan + *out = new(BridgePortVlanConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BridgePortConfigMetaData. +func (in *BridgePortConfigMetaData) DeepCopy() *BridgePortConfigMetaData { + if in == nil { + return nil + } + out := new(BridgePortConfigMetaData) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BridgePortTrunkTag) DeepCopyInto(out *BridgePortTrunkTag) { + *out = *in + if in.ID != nil { + in, out := &in.ID, &out.ID + *out = new(uint16) + **out = **in + } + if in.IDRange != nil { + in, out := &in.IDRange, &out.IDRange + *out = new(BridgePortVlanRange) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BridgePortTrunkTag. +func (in *BridgePortTrunkTag) DeepCopy() *BridgePortTrunkTag { + if in == nil { + return nil + } + out := new(BridgePortTrunkTag) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BridgePortVlanConfig) DeepCopyInto(out *BridgePortVlanConfig) { + *out = *in + if in.EnableNative != nil { + in, out := &in.EnableNative, &out.EnableNative + *out = new(bool) + **out = **in + } + if in.Mode != nil { + in, out := &in.Mode, &out.Mode + *out = new(BridgePortVlanMode) + **out = **in + } + if in.Tag != nil { + in, out := &in.Tag, &out.Tag + *out = new(intstr.IntOrString) + **out = **in + } + if in.TrunkTags != nil { + in, out := &in.TrunkTags, &out.TrunkTags + *out = new([]BridgePortTrunkTag) + if **in != nil { + in, out := *in, *out + *out = make([]BridgePortTrunkTag, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BridgePortVlanConfig. +func (in *BridgePortVlanConfig) DeepCopy() *BridgePortVlanConfig { + if in == nil { + return nil + } + out := new(BridgePortVlanConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BridgePortVlanRange) DeepCopyInto(out *BridgePortVlanRange) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BridgePortVlanRange. +func (in *BridgePortVlanRange) DeepCopy() *BridgePortVlanRange { + if in == nil { + return nil + } + out := new(BridgePortVlanRange) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DNSClientState) DeepCopyInto(out *DNSClientState) { + *out = *in + if in.Server != nil { + in, out := &in.Server, &out.Server + *out = new([]string) + if **in != nil { + in, out := *in, *out + *out = make([]string, len(*in)) + copy(*out, *in) + } + } + if in.Search != nil { + in, out := &in.Search, &out.Search + *out = new([]string) + if **in != nil { + in, out := *in, *out + *out = make([]string, len(*in)) + copy(*out, *in) + } + } + if in.Options != nil { + in, out := &in.Options, &out.Options + *out = new([]string) + if **in != nil { + in, out := *in, *out + *out = make([]string, len(*in)) + copy(*out, *in) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSClientState. +func (in *DNSClientState) DeepCopy() *DNSClientState { + if in == nil { + return nil + } + out := new(DNSClientState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DNSState) DeepCopyInto(out *DNSState) { + *out = *in + if in.Running != nil { + in, out := &in.Running, &out.Running + *out = new(DNSClientState) + (*in).DeepCopyInto(*out) + } + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = new(DNSClientState) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DNSState. +func (in *DNSState) DeepCopy() *DNSState { + if in == nil { + return nil + } + out := new(DNSState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DispatchConfig) DeepCopyInto(out *DispatchConfig) { + *out = *in + if in.PostActivation != nil { + in, out := &in.PostActivation, &out.PostActivation + *out = new(string) + **out = **in + } + if in.PostDeactivation != nil { + in, out := &in.PostDeactivation, &out.PostDeactivation + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DispatchConfig. +func (in *DispatchConfig) DeepCopy() *DispatchConfig { + if in == nil { + return nil + } + out := new(DispatchConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DummyInterface) DeepCopyInto(out *DummyInterface) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DummyInterface. +func (in *DummyInterface) DeepCopy() *DummyInterface { + if in == nil { + return nil + } + out := new(DummyInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EthernetConfig) DeepCopyInto(out *EthernetConfig) { + *out = *in + if in.SrIov != nil { + in, out := &in.SrIov, &out.SrIov + *out = new(SrIovConfig) + (*in).DeepCopyInto(*out) + } + if in.AutoNeg != nil { + in, out := &in.AutoNeg, &out.AutoNeg + *out = new(bool) + **out = **in + } + if in.Speed != nil { + in, out := &in.Speed, &out.Speed + *out = new(intstr.IntOrString) + **out = **in + } + if in.Duplex != nil { + in, out := &in.Duplex, &out.Duplex + *out = new(EthernetDuplex) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EthernetConfig. +func (in *EthernetConfig) DeepCopy() *EthernetConfig { + if in == nil { + return nil + } + out := new(EthernetConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EthernetInterface) DeepCopyInto(out *EthernetInterface) { + *out = *in + if in.Ethernet != nil { + in, out := &in.Ethernet, &out.Ethernet + *out = new(EthernetConfig) + (*in).DeepCopyInto(*out) + } + if in.Veth != nil { + in, out := &in.Veth, &out.Veth + *out = new(VethConfig) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EthernetInterface. +func (in *EthernetInterface) DeepCopy() *EthernetInterface { + if in == nil { + return nil + } + out := new(EthernetInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EthtoolCoalesceConfig) DeepCopyInto(out *EthtoolCoalesceConfig) { + *out = *in + if in.AdaptiveRx != nil { + in, out := &in.AdaptiveRx, &out.AdaptiveRx + *out = new(bool) + **out = **in + } + if in.AdaptiveTx != nil { + in, out := &in.AdaptiveTx, &out.AdaptiveTx + *out = new(bool) + **out = **in + } + if in.PktRateHigh != nil { + in, out := &in.PktRateHigh, &out.PktRateHigh + *out = new(intstr.IntOrString) + **out = **in + } + if in.PktRateLow != nil { + in, out := &in.PktRateLow, &out.PktRateLow + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxFrames != nil { + in, out := &in.RxFrames, &out.RxFrames + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxFramesHigh != nil { + in, out := &in.RxFramesHigh, &out.RxFramesHigh + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxFramesIrq != nil { + in, out := &in.RxFramesIrq, &out.RxFramesIrq + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxFramesLow != nil { + in, out := &in.RxFramesLow, &out.RxFramesLow + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxUsecs != nil { + in, out := &in.RxUsecs, &out.RxUsecs + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxUsecsHigh != nil { + in, out := &in.RxUsecsHigh, &out.RxUsecsHigh + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxUsecsIrq != nil { + in, out := &in.RxUsecsIrq, &out.RxUsecsIrq + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxUsecsLow != nil { + in, out := &in.RxUsecsLow, &out.RxUsecsLow + *out = new(intstr.IntOrString) + **out = **in + } + if in.SampleInterval != nil { + in, out := &in.SampleInterval, &out.SampleInterval + *out = new(intstr.IntOrString) + **out = **in + } + if in.StatsBlockUsecs != nil { + in, out := &in.StatsBlockUsecs, &out.StatsBlockUsecs + *out = new(intstr.IntOrString) + **out = **in + } + if in.TxFrames != nil { + in, out := &in.TxFrames, &out.TxFrames + *out = new(intstr.IntOrString) + **out = **in + } + if in.TxFramesHigh != nil { + in, out := &in.TxFramesHigh, &out.TxFramesHigh + *out = new(intstr.IntOrString) + **out = **in + } + if in.TxFramesIrq != nil { + in, out := &in.TxFramesIrq, &out.TxFramesIrq + *out = new(intstr.IntOrString) + **out = **in + } + if in.TxFramesLow != nil { + in, out := &in.TxFramesLow, &out.TxFramesLow + *out = new(intstr.IntOrString) + **out = **in + } + if in.TxUsecs != nil { + in, out := &in.TxUsecs, &out.TxUsecs + *out = new(intstr.IntOrString) + **out = **in + } + if in.TxUsecsHigh != nil { + in, out := &in.TxUsecsHigh, &out.TxUsecsHigh + *out = new(intstr.IntOrString) + **out = **in + } + if in.TxUsecsIrq != nil { + in, out := &in.TxUsecsIrq, &out.TxUsecsIrq + *out = new(intstr.IntOrString) + **out = **in + } + if in.TxUsecsLow != nil { + in, out := &in.TxUsecsLow, &out.TxUsecsLow + *out = new(intstr.IntOrString) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EthtoolCoalesceConfig. +func (in *EthtoolCoalesceConfig) DeepCopy() *EthtoolCoalesceConfig { + if in == nil { + return nil + } + out := new(EthtoolCoalesceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EthtoolConfig) DeepCopyInto(out *EthtoolConfig) { + *out = *in + if in.Pause != nil { + in, out := &in.Pause, &out.Pause + *out = new(EthtoolPauseConfig) + (*in).DeepCopyInto(*out) + } + if in.Feature != nil { + in, out := &in.Feature, &out.Feature + *out = make(map[string]bool, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Coalesce != nil { + in, out := &in.Coalesce, &out.Coalesce + *out = new(EthtoolCoalesceConfig) + (*in).DeepCopyInto(*out) + } + if in.Ring != nil { + in, out := &in.Ring, &out.Ring + *out = new(EthtoolRingConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EthtoolConfig. +func (in *EthtoolConfig) DeepCopy() *EthtoolConfig { + if in == nil { + return nil + } + out := new(EthtoolConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EthtoolFeatureConfig) DeepCopyInto(out *EthtoolFeatureConfig) { + *out = *in + if in.Data != nil { + in, out := &in.Data, &out.Data + *out = make(map[string]bool, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EthtoolFeatureConfig. +func (in *EthtoolFeatureConfig) DeepCopy() *EthtoolFeatureConfig { + if in == nil { + return nil + } + out := new(EthtoolFeatureConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EthtoolPauseConfig) DeepCopyInto(out *EthtoolPauseConfig) { + *out = *in + if in.Rx != nil { + in, out := &in.Rx, &out.Rx + *out = new(bool) + **out = **in + } + if in.Tx != nil { + in, out := &in.Tx, &out.Tx + *out = new(bool) + **out = **in + } + if in.Autoneg != nil { + in, out := &in.Autoneg, &out.Autoneg + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EthtoolPauseConfig. +func (in *EthtoolPauseConfig) DeepCopy() *EthtoolPauseConfig { + if in == nil { + return nil + } + out := new(EthtoolPauseConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EthtoolRingConfig) DeepCopyInto(out *EthtoolRingConfig) { + *out = *in + if in.Rx != nil { + in, out := &in.Rx, &out.Rx + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxMax != nil { + in, out := &in.RxMax, &out.RxMax + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxJumbo != nil { + in, out := &in.RxJumbo, &out.RxJumbo + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxJumboMax != nil { + in, out := &in.RxJumboMax, &out.RxJumboMax + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxMini != nil { + in, out := &in.RxMini, &out.RxMini + *out = new(intstr.IntOrString) + **out = **in + } + if in.RxMiniMax != nil { + in, out := &in.RxMiniMax, &out.RxMiniMax + *out = new(intstr.IntOrString) + **out = **in + } + if in.Tx != nil { + in, out := &in.Tx, &out.Tx + *out = new(intstr.IntOrString) + **out = **in + } + if in.TxMax != nil { + in, out := &in.TxMax, &out.TxMax + *out = new(intstr.IntOrString) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EthtoolRingConfig. +func (in *EthtoolRingConfig) DeepCopy() *EthtoolRingConfig { + if in == nil { + return nil + } + out := new(EthtoolRingConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HostNameState) DeepCopyInto(out *HostNameState) { + *out = *in + if in.Running != nil { + in, out := &in.Running, &out.Running + *out = new(string) + **out = **in + } + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HostNameState. +func (in *HostNameState) DeepCopy() *HostNameState { + if in == nil { + return nil + } + out := new(HostNameState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HsrConfig) DeepCopyInto(out *HsrConfig) { + *out = *in + if in.SupervisionAddress != nil { + in, out := &in.SupervisionAddress, &out.SupervisionAddress + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HsrConfig. +func (in *HsrConfig) DeepCopy() *HsrConfig { + if in == nil { + return nil + } + out := new(HsrConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *HsrInterface) DeepCopyInto(out *HsrInterface) { + *out = *in + if in.Hsr != nil { + in, out := &in.Hsr, &out.Hsr + *out = new(HsrConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HsrInterface. +func (in *HsrInterface) DeepCopy() *HsrInterface { + if in == nil { + return nil + } + out := new(HsrInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Ieee8021XConfig) DeepCopyInto(out *Ieee8021XConfig) { + *out = *in + if in.Identity != nil { + in, out := &in.Identity, &out.Identity + *out = new(string) + **out = **in + } + if in.Eap != nil { + in, out := &in.Eap, &out.Eap + *out = new([]string) + if **in != nil { + in, out := *in, *out + *out = make([]string, len(*in)) + copy(*out, *in) + } + } + if in.PrivateKey != nil { + in, out := &in.PrivateKey, &out.PrivateKey + *out = new(string) + **out = **in + } + if in.ClientCert != nil { + in, out := &in.ClientCert, &out.ClientCert + *out = new(string) + **out = **in + } + if in.CaCert != nil { + in, out := &in.CaCert, &out.CaCert + *out = new(string) + **out = **in + } + if in.PrivateKeyPassword != nil { + in, out := &in.PrivateKeyPassword, &out.PrivateKeyPassword + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Ieee8021XConfig. +func (in *Ieee8021XConfig) DeepCopy() *Ieee8021XConfig { + if in == nil { + return nil + } + out := new(Ieee8021XConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InfiniBandConfig) DeepCopyInto(out *InfiniBandConfig) { + *out = *in + if in.BaseIface != nil { + in, out := &in.BaseIface, &out.BaseIface + *out = new(string) + **out = **in + } + if in.Pkey != nil { + in, out := &in.Pkey, &out.Pkey + *out = new(intstr.IntOrString) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfiniBandConfig. +func (in *InfiniBandConfig) DeepCopy() *InfiniBandConfig { + if in == nil { + return nil + } + out := new(InfiniBandConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InfiniBandInterface) DeepCopyInto(out *InfiniBandInterface) { + *out = *in + if in.Ib != nil { + in, out := &in.Ib, &out.Ib + *out = new(InfiniBandConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InfiniBandInterface. +func (in *InfiniBandInterface) DeepCopy() *InfiniBandInterface { + if in == nil { + return nil + } + out := new(InfiniBandInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Interface) DeepCopyInto(out *Interface) { + *out = *in + in.BaseInterface.DeepCopyInto(&out.BaseInterface) + if in.BridgeInterface != nil { + in, out := &in.BridgeInterface, &out.BridgeInterface + *out = new(BridgeInterface) + (*in).DeepCopyInto(*out) + } + if in.BondInterface != nil { + in, out := &in.BondInterface, &out.BondInterface + *out = new(BondInterface) + (*in).DeepCopyInto(*out) + } + if in.EthernetInterface != nil { + in, out := &in.EthernetInterface, &out.EthernetInterface + *out = new(EthernetInterface) + (*in).DeepCopyInto(*out) + } + if in.HsrInterface != nil { + in, out := &in.HsrInterface, &out.HsrInterface + *out = new(HsrInterface) + (*in).DeepCopyInto(*out) + } + if in.OVSInterface != nil { + in, out := &in.OVSInterface, &out.OVSInterface + *out = new(OVSInterface) + (*in).DeepCopyInto(*out) + } + if in.VlanInterface != nil { + in, out := &in.VlanInterface, &out.VlanInterface + *out = new(VlanInterface) + (*in).DeepCopyInto(*out) + } + if in.VxlanInterface != nil { + in, out := &in.VxlanInterface, &out.VxlanInterface + *out = new(VxlanInterface) + (*in).DeepCopyInto(*out) + } + if in.MacVlanInterface != nil { + in, out := &in.MacVlanInterface, &out.MacVlanInterface + *out = new(MacVlanInterface) + (*in).DeepCopyInto(*out) + } + if in.MacVtapInterface != nil { + in, out := &in.MacVtapInterface, &out.MacVtapInterface + *out = new(MacVtapInterface) + (*in).DeepCopyInto(*out) + } + if in.VrfInterface != nil { + in, out := &in.VrfInterface, &out.VrfInterface + *out = new(VrfInterface) + (*in).DeepCopyInto(*out) + } + if in.InfiniBandInterface != nil { + in, out := &in.InfiniBandInterface, &out.InfiniBandInterface + *out = new(InfiniBandInterface) + (*in).DeepCopyInto(*out) + } + if in.MacSecInterface != nil { + in, out := &in.MacSecInterface, &out.MacSecInterface + *out = new(MacSecInterface) + (*in).DeepCopyInto(*out) + } + if in.IpsecInterface != nil { + in, out := &in.IpsecInterface, &out.IpsecInterface + *out = new(IpsecInterface) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Interface. +func (in *Interface) DeepCopy() *Interface { + if in == nil { + return nil + } + out := new(Interface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InterfaceIP) DeepCopyInto(out *InterfaceIP) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.Dhcp != nil { + in, out := &in.Dhcp, &out.Dhcp + *out = new(bool) + **out = **in + } + if in.Autoconf != nil { + in, out := &in.Autoconf, &out.Autoconf + *out = new(bool) + **out = **in + } + if in.DhcpClientID != nil { + in, out := &in.DhcpClientID, &out.DhcpClientID + *out = new(Dhcpv4ClientID) + **out = **in + } + if in.DhcpDuid != nil { + in, out := &in.DhcpDuid, &out.DhcpDuid + *out = new(Dhcpv6Duid) + **out = **in + } + if in.Addresses != nil { + in, out := &in.Addresses, &out.Addresses + *out = new([]InterfaceIPAddr) + if **in != nil { + in, out := *in, *out + *out = make([]InterfaceIPAddr, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } + if in.AutoDNS != nil { + in, out := &in.AutoDNS, &out.AutoDNS + *out = new(bool) + **out = **in + } + if in.AutoGateway != nil { + in, out := &in.AutoGateway, &out.AutoGateway + *out = new(bool) + **out = **in + } + if in.AutoRoutes != nil { + in, out := &in.AutoRoutes, &out.AutoRoutes + *out = new(bool) + **out = **in + } + if in.AutoTableID != nil { + in, out := &in.AutoTableID, &out.AutoTableID + *out = new(intstr.IntOrString) + **out = **in + } + if in.AutoRouteMetric != nil { + in, out := &in.AutoRouteMetric, &out.AutoRouteMetric + *out = new(intstr.IntOrString) + **out = **in + } + if in.AddrGenMode != nil { + in, out := &in.AddrGenMode, &out.AddrGenMode + *out = new(Ipv6AddrGenMode) + **out = **in + } + if in.AllowExtraAddress != nil { + in, out := &in.AllowExtraAddress, &out.AllowExtraAddress + *out = new(bool) + **out = **in + } + if in.Token != nil { + in, out := &in.Token, &out.Token + *out = new(string) + **out = **in + } + if in.DhcpSendHostname != nil { + in, out := &in.DhcpSendHostname, &out.DhcpSendHostname + *out = new(bool) + **out = **in + } + if in.DhcpCustomHostname != nil { + in, out := &in.DhcpCustomHostname, &out.DhcpCustomHostname + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InterfaceIP. +func (in *InterfaceIP) DeepCopy() *InterfaceIP { + if in == nil { + return nil + } + out := new(InterfaceIP) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *InterfaceIPAddr) DeepCopyInto(out *InterfaceIPAddr) { + *out = *in + if in.MptcpFlags != nil { + in, out := &in.MptcpFlags, &out.MptcpFlags + *out = new([]MptcpAddressFlag) + if **in != nil { + in, out := *in, *out + *out = make([]MptcpAddressFlag, len(*in)) + copy(*out, *in) + } + } + if in.ValidLifeTime != nil { + in, out := &in.ValidLifeTime, &out.ValidLifeTime + *out = new(string) + **out = **in + } + if in.PreferredLifeTime != nil { + in, out := &in.PreferredLifeTime, &out.PreferredLifeTime + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InterfaceIPAddr. +func (in *InterfaceIPAddr) DeepCopy() *InterfaceIPAddr { + if in == nil { + return nil + } + out := new(InterfaceIPAddr) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *IpsecInterface) DeepCopyInto(out *IpsecInterface) { + *out = *in + if in.Libreswan != nil { + in, out := &in.Libreswan, &out.Libreswan + *out = new(LibreswanConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new IpsecInterface. +func (in *IpsecInterface) DeepCopy() *IpsecInterface { + if in == nil { + return nil + } + out := new(IpsecInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LibreswanConfig) DeepCopyInto(out *LibreswanConfig) { + *out = *in + if in.Rightid != nil { + in, out := &in.Rightid, &out.Rightid + *out = new(string) + **out = **in + } + if in.Rightrsasigkey != nil { + in, out := &in.Rightrsasigkey, &out.Rightrsasigkey + *out = new(string) + **out = **in + } + if in.Left != nil { + in, out := &in.Left, &out.Left + *out = new(string) + **out = **in + } + if in.Leftid != nil { + in, out := &in.Leftid, &out.Leftid + *out = new(string) + **out = **in + } + if in.Leftrsasigkey != nil { + in, out := &in.Leftrsasigkey, &out.Leftrsasigkey + *out = new(string) + **out = **in + } + if in.Leftcert != nil { + in, out := &in.Leftcert, &out.Leftcert + *out = new(string) + **out = **in + } + if in.Ikev2 != nil { + in, out := &in.Ikev2, &out.Ikev2 + *out = new(string) + **out = **in + } + if in.Psk != nil { + in, out := &in.Psk, &out.Psk + *out = new(string) + **out = **in + } + if in.Ikelifetime != nil { + in, out := &in.Ikelifetime, &out.Ikelifetime + *out = new(string) + **out = **in + } + if in.Salifetime != nil { + in, out := &in.Salifetime, &out.Salifetime + *out = new(string) + **out = **in + } + if in.Ike != nil { + in, out := &in.Ike, &out.Ike + *out = new(string) + **out = **in + } + if in.Esp != nil { + in, out := &in.Esp, &out.Esp + *out = new(string) + **out = **in + } + if in.Dpddelay != nil { + in, out := &in.Dpddelay, &out.Dpddelay + *out = new(intstr.IntOrString) + **out = **in + } + if in.Dpdtimeout != nil { + in, out := &in.Dpdtimeout, &out.Dpdtimeout + *out = new(intstr.IntOrString) + **out = **in + } + if in.Dpdaction != nil { + in, out := &in.Dpdaction, &out.Dpdaction + *out = new(string) + **out = **in + } + if in.IpsecInterface != nil { + in, out := &in.IpsecInterface, &out.IpsecInterface + *out = new(intstr.IntOrString) + **out = **in + } + if in.Authby != nil { + in, out := &in.Authby, &out.Authby + *out = new(string) + **out = **in + } + if in.Rightsubnet != nil { + in, out := &in.Rightsubnet, &out.Rightsubnet + *out = new(string) + **out = **in + } + if in.Leftmodecfgclient != nil { + in, out := &in.Leftmodecfgclient, &out.Leftmodecfgclient + *out = new(bool) + **out = **in + } + if in.Kind != nil { + in, out := &in.Kind, &out.Kind + *out = new(LibreswanConnectionType) + **out = **in + } + if in.Hostaddrfamily != nil { + in, out := &in.Hostaddrfamily, &out.Hostaddrfamily + *out = new(LibreswanAddressFamily) + **out = **in + } + if in.Clientaddrfamily != nil { + in, out := &in.Clientaddrfamily, &out.Clientaddrfamily + *out = new(LibreswanAddressFamily) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LibreswanConfig. +func (in *LibreswanConfig) DeepCopy() *LibreswanConfig { + if in == nil { + return nil + } + out := new(LibreswanConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LinuxBridgeConfig) DeepCopyInto(out *LinuxBridgeConfig) { + *out = *in + if in.Options != nil { + in, out := &in.Options, &out.Options + *out = new(LinuxBridgeOptions) + (*in).DeepCopyInto(*out) + } + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new([]LinuxBridgePortConfig) + if **in != nil { + in, out := *in, *out + *out = make([]LinuxBridgePortConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LinuxBridgeConfig. +func (in *LinuxBridgeConfig) DeepCopy() *LinuxBridgeConfig { + if in == nil { + return nil + } + out := new(LinuxBridgeConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LinuxBridgeOptions) DeepCopyInto(out *LinuxBridgeOptions) { + *out = *in + if in.GcTimer != nil { + in, out := &in.GcTimer, &out.GcTimer + *out = new(uint64) + **out = **in + } + if in.GroupAddr != nil { + in, out := &in.GroupAddr, &out.GroupAddr + *out = new(string) + **out = **in + } + if in.GroupForwardMask != nil { + in, out := &in.GroupForwardMask, &out.GroupForwardMask + *out = new(intstr.IntOrString) + **out = **in + } + if in.GroupFwdMask != nil { + in, out := &in.GroupFwdMask, &out.GroupFwdMask + *out = new(intstr.IntOrString) + **out = **in + } + if in.HashMax != nil { + in, out := &in.HashMax, &out.HashMax + *out = new(intstr.IntOrString) + **out = **in + } + if in.HelloTimer != nil { + in, out := &in.HelloTimer, &out.HelloTimer + *out = new(uint64) + **out = **in + } + if in.MacAgeingTime != nil { + in, out := &in.MacAgeingTime, &out.MacAgeingTime + *out = new(intstr.IntOrString) + **out = **in + } + if in.MulticastLastMemberCount != nil { + in, out := &in.MulticastLastMemberCount, &out.MulticastLastMemberCount + *out = new(intstr.IntOrString) + **out = **in + } + if in.MulticastLastMemberInterval != nil { + in, out := &in.MulticastLastMemberInterval, &out.MulticastLastMemberInterval + *out = new(intstr.IntOrString) + **out = **in + } + if in.MulticastMembershipInterval != nil { + in, out := &in.MulticastMembershipInterval, &out.MulticastMembershipInterval + *out = new(intstr.IntOrString) + **out = **in + } + if in.MulticastQuerier != nil { + in, out := &in.MulticastQuerier, &out.MulticastQuerier + *out = new(bool) + **out = **in + } + if in.MulticastQuerierInterval != nil { + in, out := &in.MulticastQuerierInterval, &out.MulticastQuerierInterval + *out = new(intstr.IntOrString) + **out = **in + } + if in.MulticastQueryInterval != nil { + in, out := &in.MulticastQueryInterval, &out.MulticastQueryInterval + *out = new(intstr.IntOrString) + **out = **in + } + if in.MulticastQueryResponseInterval != nil { + in, out := &in.MulticastQueryResponseInterval, &out.MulticastQueryResponseInterval + *out = new(intstr.IntOrString) + **out = **in + } + if in.MulticastQueryUseIfaddr != nil { + in, out := &in.MulticastQueryUseIfaddr, &out.MulticastQueryUseIfaddr + *out = new(bool) + **out = **in + } + if in.MulticastRouter != nil { + in, out := &in.MulticastRouter, &out.MulticastRouter + *out = new(LinuxBridgeMulticastRouterType) + **out = **in + } + if in.MulticastSnooping != nil { + in, out := &in.MulticastSnooping, &out.MulticastSnooping + *out = new(bool) + **out = **in + } + if in.MulticastStartupQueryCount != nil { + in, out := &in.MulticastStartupQueryCount, &out.MulticastStartupQueryCount + *out = new(intstr.IntOrString) + **out = **in + } + if in.MulticastStartupQueryInterval != nil { + in, out := &in.MulticastStartupQueryInterval, &out.MulticastStartupQueryInterval + *out = new(intstr.IntOrString) + **out = **in + } + if in.Stp != nil { + in, out := &in.Stp, &out.Stp + *out = new(LinuxBridgeStpOptions) + (*in).DeepCopyInto(*out) + } + if in.VlanProtocol != nil { + in, out := &in.VlanProtocol, &out.VlanProtocol + *out = new(VlanProtocol) + **out = **in + } + if in.VlanDefaultPvid != nil { + in, out := &in.VlanDefaultPvid, &out.VlanDefaultPvid + *out = new(uint16) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LinuxBridgeOptions. +func (in *LinuxBridgeOptions) DeepCopy() *LinuxBridgeOptions { + if in == nil { + return nil + } + out := new(LinuxBridgeOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LinuxBridgePortConfig) DeepCopyInto(out *LinuxBridgePortConfig) { + *out = *in + if in.StpHairpinMode != nil { + in, out := &in.StpHairpinMode, &out.StpHairpinMode + *out = new(bool) + **out = **in + } + if in.StpPathCost != nil { + in, out := &in.StpPathCost, &out.StpPathCost + *out = new(intstr.IntOrString) + **out = **in + } + if in.StpPriority != nil { + in, out := &in.StpPriority, &out.StpPriority + *out = new(intstr.IntOrString) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LinuxBridgePortConfig. +func (in *LinuxBridgePortConfig) DeepCopy() *LinuxBridgePortConfig { + if in == nil { + return nil + } + out := new(LinuxBridgePortConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LinuxBridgeStpOptions) DeepCopyInto(out *LinuxBridgeStpOptions) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } + if in.ForwardDelay != nil { + in, out := &in.ForwardDelay, &out.ForwardDelay + *out = new(intstr.IntOrString) + **out = **in + } + if in.HelloTime != nil { + in, out := &in.HelloTime, &out.HelloTime + *out = new(intstr.IntOrString) + **out = **in + } + if in.MaxAge != nil { + in, out := &in.MaxAge, &out.MaxAge + *out = new(intstr.IntOrString) + **out = **in + } + if in.Priority != nil { + in, out := &in.Priority, &out.Priority + *out = new(intstr.IntOrString) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LinuxBridgeStpOptions. +func (in *LinuxBridgeStpOptions) DeepCopy() *LinuxBridgeStpOptions { + if in == nil { + return nil + } + out := new(LinuxBridgeStpOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpChassisID) DeepCopyInto(out *LldpChassisID) { + *out = *in + if in.Ty != nil { + in, out := &in.Ty, &out.Ty + *out = new(LldpNeighborTlvType) + **out = **in + } + if in.ChassisID != nil { + in, out := &in.ChassisID, &out.ChassisID + *out = new(string) + **out = **in + } + if in.ChassisIDType != nil { + in, out := &in.ChassisIDType, &out.ChassisIDType + *out = new(LldpChassisIDType) + **out = **in + } + if in.Description != nil { + in, out := &in.Description, &out.Description + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpChassisID. +func (in *LldpChassisID) DeepCopy() *LldpChassisID { + if in == nil { + return nil + } + out := new(LldpChassisID) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpConfig) DeepCopyInto(out *LldpConfig) { + *out = *in + if in.Neighbors != nil { + in, out := &in.Neighbors, &out.Neighbors + *out = make([][]LldpNeighborTlv, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = make([]LldpNeighborTlv, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpConfig. +func (in *LldpConfig) DeepCopy() *LldpConfig { + if in == nil { + return nil + } + out := new(LldpConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpMacPhy) DeepCopyInto(out *LldpMacPhy) { + *out = *in + if in.Ty != nil { + in, out := &in.Ty, &out.Ty + *out = new(LldpNeighborTlvType) + **out = **in + } + if in.Ieee8023MacPhyConf != nil { + in, out := &in.Ieee8023MacPhyConf, &out.Ieee8023MacPhyConf + *out = new(LldpMacPhyConf) + (*in).DeepCopyInto(*out) + } + if in.Oui != nil { + in, out := &in.Oui, &out.Oui + *out = new(LldpOrgOiu) + **out = **in + } + if in.Subtype != nil { + in, out := &in.Subtype, &out.Subtype + *out = new(LldpOrgSubtype) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpMacPhy. +func (in *LldpMacPhy) DeepCopy() *LldpMacPhy { + if in == nil { + return nil + } + out := new(LldpMacPhy) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpMacPhyConf) DeepCopyInto(out *LldpMacPhyConf) { + *out = *in + if in.Autoneg != nil { + in, out := &in.Autoneg, &out.Autoneg + *out = new(bool) + **out = **in + } + if in.OperationalMauType != nil { + in, out := &in.OperationalMauType, &out.OperationalMauType + *out = new(uint16) + **out = **in + } + if in.PmdAutonegCap != nil { + in, out := &in.PmdAutonegCap, &out.PmdAutonegCap + *out = new(uint16) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpMacPhyConf. +func (in *LldpMacPhyConf) DeepCopy() *LldpMacPhyConf { + if in == nil { + return nil + } + out := new(LldpMacPhyConf) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpMaxFrameSize) DeepCopyInto(out *LldpMaxFrameSize) { + *out = *in + if in.Ty != nil { + in, out := &in.Ty, &out.Ty + *out = new(LldpNeighborTlvType) + **out = **in + } + if in.Ieee8023MaxFrameSize != nil { + in, out := &in.Ieee8023MaxFrameSize, &out.Ieee8023MaxFrameSize + *out = new(uint32) + **out = **in + } + if in.Oui != nil { + in, out := &in.Oui, &out.Oui + *out = new(LldpOrgOiu) + **out = **in + } + if in.Subtype != nil { + in, out := &in.Subtype, &out.Subtype + *out = new(LldpOrgSubtype) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpMaxFrameSize. +func (in *LldpMaxFrameSize) DeepCopy() *LldpMaxFrameSize { + if in == nil { + return nil + } + out := new(LldpMaxFrameSize) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpMgmtAddr) DeepCopyInto(out *LldpMgmtAddr) { + *out = *in + if in.Address != nil { + in, out := &in.Address, &out.Address + *out = new(string) + **out = **in + } + if in.AddressSubtype != nil { + in, out := &in.AddressSubtype, &out.AddressSubtype + *out = new(LldpAddressFamily) + **out = **in + } + if in.InterfaceNumber != nil { + in, out := &in.InterfaceNumber, &out.InterfaceNumber + *out = new(uint32) + **out = **in + } + if in.InterfaceNumberSubtype != nil { + in, out := &in.InterfaceNumberSubtype, &out.InterfaceNumberSubtype + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpMgmtAddr. +func (in *LldpMgmtAddr) DeepCopy() *LldpMgmtAddr { + if in == nil { + return nil + } + out := new(LldpMgmtAddr) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpMgmtAddrs) DeepCopyInto(out *LldpMgmtAddrs) { + *out = *in + if in.Ty != nil { + in, out := &in.Ty, &out.Ty + *out = new(LldpNeighborTlvType) + **out = **in + } + if in.ManagementAddresses != nil { + in, out := &in.ManagementAddresses, &out.ManagementAddresses + *out = new([]LldpMgmtAddr) + if **in != nil { + in, out := *in, *out + *out = make([]LldpMgmtAddr, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpMgmtAddrs. +func (in *LldpMgmtAddrs) DeepCopy() *LldpMgmtAddrs { + if in == nil { + return nil + } + out := new(LldpMgmtAddrs) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpNeighborTlv) DeepCopyInto(out *LldpNeighborTlv) { + *out = *in + if in.LldpSystemName != nil { + in, out := &in.LldpSystemName, &out.LldpSystemName + *out = new(LldpSystemName) + (*in).DeepCopyInto(*out) + } + if in.LldpSystemDescription != nil { + in, out := &in.LldpSystemDescription, &out.LldpSystemDescription + *out = new(LldpSystemDescription) + (*in).DeepCopyInto(*out) + } + if in.LldpSystemCapabilities != nil { + in, out := &in.LldpSystemCapabilities, &out.LldpSystemCapabilities + *out = new(LldpSystemCapabilities) + (*in).DeepCopyInto(*out) + } + if in.LldpChassisID != nil { + in, out := &in.LldpChassisID, &out.LldpChassisID + *out = new(LldpChassisID) + (*in).DeepCopyInto(*out) + } + if in.LldpPortID != nil { + in, out := &in.LldpPortID, &out.LldpPortID + *out = new(LldpPortID) + (*in).DeepCopyInto(*out) + } + if in.LldpVlans != nil { + in, out := &in.LldpVlans, &out.LldpVlans + *out = new(LldpVlans) + (*in).DeepCopyInto(*out) + } + if in.LldpMacPhy != nil { + in, out := &in.LldpMacPhy, &out.LldpMacPhy + *out = new(LldpMacPhy) + (*in).DeepCopyInto(*out) + } + if in.LldpPpvids != nil { + in, out := &in.LldpPpvids, &out.LldpPpvids + *out = new(LldpPpvids) + (*in).DeepCopyInto(*out) + } + if in.LldpMgmtAddrs != nil { + in, out := &in.LldpMgmtAddrs, &out.LldpMgmtAddrs + *out = new(LldpMgmtAddrs) + (*in).DeepCopyInto(*out) + } + if in.LldpMaxFrameSize != nil { + in, out := &in.LldpMaxFrameSize, &out.LldpMaxFrameSize + *out = new(LldpMaxFrameSize) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpNeighborTlv. +func (in *LldpNeighborTlv) DeepCopy() *LldpNeighborTlv { + if in == nil { + return nil + } + out := new(LldpNeighborTlv) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpPortID) DeepCopyInto(out *LldpPortID) { + *out = *in + if in.Ty != nil { + in, out := &in.Ty, &out.Ty + *out = new(LldpNeighborTlvType) + **out = **in + } + if in.PortID != nil { + in, out := &in.PortID, &out.PortID + *out = new(string) + **out = **in + } + if in.PortIDType != nil { + in, out := &in.PortIDType, &out.PortIDType + *out = new(LldpPortIDType) + **out = **in + } + if in.Description != nil { + in, out := &in.Description, &out.Description + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpPortID. +func (in *LldpPortID) DeepCopy() *LldpPortID { + if in == nil { + return nil + } + out := new(LldpPortID) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpPpvids) DeepCopyInto(out *LldpPpvids) { + *out = *in + if in.Ty != nil { + in, out := &in.Ty, &out.Ty + *out = new(LldpNeighborTlvType) + **out = **in + } + if in.Ieee8021Ppvids != nil { + in, out := &in.Ieee8021Ppvids, &out.Ieee8021Ppvids + *out = new([]uint32) + if **in != nil { + in, out := *in, *out + *out = make([]uint32, len(*in)) + copy(*out, *in) + } + } + if in.Oui != nil { + in, out := &in.Oui, &out.Oui + *out = new(LldpOrgOiu) + **out = **in + } + if in.Subtype != nil { + in, out := &in.Subtype, &out.Subtype + *out = new(LldpOrgSubtype) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpPpvids. +func (in *LldpPpvids) DeepCopy() *LldpPpvids { + if in == nil { + return nil + } + out := new(LldpPpvids) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpSystemCapabilities) DeepCopyInto(out *LldpSystemCapabilities) { + *out = *in + if in.Ty != nil { + in, out := &in.Ty, &out.Ty + *out = new(LldpNeighborTlvType) + **out = **in + } + if in.SystemCapabilities != nil { + in, out := &in.SystemCapabilities, &out.SystemCapabilities + *out = new([]LldpSystemCapability) + if **in != nil { + in, out := *in, *out + *out = make([]LldpSystemCapability, len(*in)) + copy(*out, *in) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpSystemCapabilities. +func (in *LldpSystemCapabilities) DeepCopy() *LldpSystemCapabilities { + if in == nil { + return nil + } + out := new(LldpSystemCapabilities) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpSystemDescription) DeepCopyInto(out *LldpSystemDescription) { + *out = *in + if in.Ty != nil { + in, out := &in.Ty, &out.Ty + *out = new(LldpNeighborTlvType) + **out = **in + } + if in.SystemDescription != nil { + in, out := &in.SystemDescription, &out.SystemDescription + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpSystemDescription. +func (in *LldpSystemDescription) DeepCopy() *LldpSystemDescription { + if in == nil { + return nil + } + out := new(LldpSystemDescription) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpSystemName) DeepCopyInto(out *LldpSystemName) { + *out = *in + if in.Ty != nil { + in, out := &in.Ty, &out.Ty + *out = new(LldpNeighborTlvType) + **out = **in + } + if in.SystemName != nil { + in, out := &in.SystemName, &out.SystemName + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpSystemName. +func (in *LldpSystemName) DeepCopy() *LldpSystemName { + if in == nil { + return nil + } + out := new(LldpSystemName) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpVlan) DeepCopyInto(out *LldpVlan) { + *out = *in + if in.Name != nil { + in, out := &in.Name, &out.Name + *out = new(string) + **out = **in + } + if in.Vid != nil { + in, out := &in.Vid, &out.Vid + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpVlan. +func (in *LldpVlan) DeepCopy() *LldpVlan { + if in == nil { + return nil + } + out := new(LldpVlan) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LldpVlans) DeepCopyInto(out *LldpVlans) { + *out = *in + if in.Ty != nil { + in, out := &in.Ty, &out.Ty + *out = new(LldpNeighborTlvType) + **out = **in + } + if in.Ieee8021Vlans != nil { + in, out := &in.Ieee8021Vlans, &out.Ieee8021Vlans + *out = new([]LldpVlan) + if **in != nil { + in, out := *in, *out + *out = make([]LldpVlan, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } + if in.Oui != nil { + in, out := &in.Oui, &out.Oui + *out = new(LldpOrgOiu) + **out = **in + } + if in.Subtype != nil { + in, out := &in.Subtype, &out.Subtype + *out = new(LldpOrgSubtype) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LldpVlans. +func (in *LldpVlans) DeepCopy() *LldpVlans { + if in == nil { + return nil + } + out := new(LldpVlans) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *LoopbackInterface) DeepCopyInto(out *LoopbackInterface) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new LoopbackInterface. +func (in *LoopbackInterface) DeepCopy() *LoopbackInterface { + if in == nil { + return nil + } + out := new(LoopbackInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MacSecConfig) DeepCopyInto(out *MacSecConfig) { + *out = *in + if in.MkaCak != nil { + in, out := &in.MkaCak, &out.MkaCak + *out = new(string) + **out = **in + } + if in.MkaCkn != nil { + in, out := &in.MkaCkn, &out.MkaCkn + *out = new(string) + **out = **in + } + if in.Offload != nil { + in, out := &in.Offload, &out.Offload + *out = new(MacSecOffload) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MacSecConfig. +func (in *MacSecConfig) DeepCopy() *MacSecConfig { + if in == nil { + return nil + } + out := new(MacSecConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MacSecInterface) DeepCopyInto(out *MacSecInterface) { + *out = *in + if in.Macsec != nil { + in, out := &in.Macsec, &out.Macsec + *out = new(MacSecConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MacSecInterface. +func (in *MacSecInterface) DeepCopy() *MacSecInterface { + if in == nil { + return nil + } + out := new(MacSecInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MacVlanConfig) DeepCopyInto(out *MacVlanConfig) { + *out = *in + if in.AcceptAllMac != nil { + in, out := &in.AcceptAllMac, &out.AcceptAllMac + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MacVlanConfig. +func (in *MacVlanConfig) DeepCopy() *MacVlanConfig { + if in == nil { + return nil + } + out := new(MacVlanConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MacVlanInterface) DeepCopyInto(out *MacVlanInterface) { + *out = *in + if in.MacVlan != nil { + in, out := &in.MacVlan, &out.MacVlan + *out = new(MacVlanConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MacVlanInterface. +func (in *MacVlanInterface) DeepCopy() *MacVlanInterface { + if in == nil { + return nil + } + out := new(MacVlanInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MacVtapConfig) DeepCopyInto(out *MacVtapConfig) { + *out = *in + if in.AcceptAllMac != nil { + in, out := &in.AcceptAllMac, &out.AcceptAllMac + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MacVtapConfig. +func (in *MacVtapConfig) DeepCopy() *MacVtapConfig { + if in == nil { + return nil + } + out := new(MacVtapConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MacVtapInterface) DeepCopyInto(out *MacVtapInterface) { + *out = *in + if in.MacVtap != nil { + in, out := &in.MacVtap, &out.MacVtap + *out = new(MacVtapConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MacVtapInterface. +func (in *MacVtapInterface) DeepCopy() *MacVtapInterface { + if in == nil { + return nil + } + out := new(MacVtapInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *MptcpConfig) DeepCopyInto(out *MptcpConfig) { + *out = *in + if in.AddressFlags != nil { + in, out := &in.AddressFlags, &out.AddressFlags + *out = new([]MptcpAddressFlag) + if **in != nil { + in, out := *in, *out + *out = make([]MptcpAddressFlag, len(*in)) + copy(*out, *in) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new MptcpConfig. +func (in *MptcpConfig) DeepCopy() *MptcpConfig { + if in == nil { + return nil + } + out := new(MptcpConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *NetworkState) DeepCopyInto(out *NetworkState) { + *out = *in + if in.Hostname != nil { + in, out := &in.Hostname, &out.Hostname + *out = new(HostNameState) + (*in).DeepCopyInto(*out) + } + if in.DNS != nil { + in, out := &in.DNS, &out.DNS + *out = new(DNSState) + (*in).DeepCopyInto(*out) + } + if in.Rules != nil { + in, out := &in.Rules, &out.Rules + *out = new(RouteRules) + (*in).DeepCopyInto(*out) + } + if in.Routes != nil { + in, out := &in.Routes, &out.Routes + *out = new(Routes) + (*in).DeepCopyInto(*out) + } + if in.Interfaces != nil { + in, out := &in.Interfaces, &out.Interfaces + *out = make([]Interface, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Ovsdb != nil { + in, out := &in.Ovsdb, &out.Ovsdb + *out = new(OVSDBGlobalConfig) + (*in).DeepCopyInto(*out) + } + if in.OVN != nil { + in, out := &in.OVN, &out.OVN + *out = new(OVNConfiguration) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new NetworkState. +func (in *NetworkState) DeepCopy() *NetworkState { + if in == nil { + return nil + } + out := new(NetworkState) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVNBridgeMapping) DeepCopyInto(out *OVNBridgeMapping) { + *out = *in + if in.State != nil { + in, out := &in.State, &out.State + *out = new(OVNBridgeMappingState) + **out = **in + } + if in.Bridge != nil { + in, out := &in.Bridge, &out.Bridge + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVNBridgeMapping. +func (in *OVNBridgeMapping) DeepCopy() *OVNBridgeMapping { + if in == nil { + return nil + } + out := new(OVNBridgeMapping) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVNConfiguration) DeepCopyInto(out *OVNConfiguration) { + *out = *in + if in.BridgeMappings != nil { + in, out := &in.BridgeMappings, &out.BridgeMappings + *out = new([]OVNBridgeMapping) + if **in != nil { + in, out := *in, *out + *out = make([]OVNBridgeMapping, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVNConfiguration. +func (in *OVNConfiguration) DeepCopy() *OVNConfiguration { + if in == nil { + return nil + } + out := new(OVNConfiguration) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVSBridgeBondConfig) DeepCopyInto(out *OVSBridgeBondConfig) { + *out = *in + if in.Mode != nil { + in, out := &in.Mode, &out.Mode + *out = new(OVSBridgeBondMode) + **out = **in + } + if in.Ports != nil { + in, out := &in.Ports, &out.Ports + *out = new([]OVSBridgeBondPortConfig) + if **in != nil { + in, out := *in, *out + *out = make([]OVSBridgeBondPortConfig, len(*in)) + copy(*out, *in) + } + } + if in.BondDowndelay != nil { + in, out := &in.BondDowndelay, &out.BondDowndelay + *out = new(intstr.IntOrString) + **out = **in + } + if in.BondUpdelay != nil { + in, out := &in.BondUpdelay, &out.BondUpdelay + *out = new(intstr.IntOrString) + **out = **in + } + if in.Ovsdb != nil { + in, out := &in.Ovsdb, &out.Ovsdb + *out = new(OVSDBIfaceConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVSBridgeBondConfig. +func (in *OVSBridgeBondConfig) DeepCopy() *OVSBridgeBondConfig { + if in == nil { + return nil + } + out := new(OVSBridgeBondConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVSBridgeBondPortConfig) DeepCopyInto(out *OVSBridgeBondPortConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVSBridgeBondPortConfig. +func (in *OVSBridgeBondPortConfig) DeepCopy() *OVSBridgeBondPortConfig { + if in == nil { + return nil + } + out := new(OVSBridgeBondPortConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVSBridgeConfig) DeepCopyInto(out *OVSBridgeConfig) { + *out = *in + if in.AllowExtraPatchPorts != nil { + in, out := &in.AllowExtraPatchPorts, &out.AllowExtraPatchPorts + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVSBridgeConfig. +func (in *OVSBridgeConfig) DeepCopy() *OVSBridgeConfig { + if in == nil { + return nil + } + out := new(OVSBridgeConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVSBridgeOptions) DeepCopyInto(out *OVSBridgeOptions) { + *out = *in + if in.Stp != nil { + in, out := &in.Stp, &out.Stp + *out = new(OVSBridgeStpOptions) + (*in).DeepCopyInto(*out) + } + if in.Rstp != nil { + in, out := &in.Rstp, &out.Rstp + *out = new(bool) + **out = **in + } + if in.McastSnoopingEnable != nil { + in, out := &in.McastSnoopingEnable, &out.McastSnoopingEnable + *out = new(bool) + **out = **in + } + if in.FailMode != nil { + in, out := &in.FailMode, &out.FailMode + *out = new(string) + **out = **in + } + if in.Datapath != nil { + in, out := &in.Datapath, &out.Datapath + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVSBridgeOptions. +func (in *OVSBridgeOptions) DeepCopy() *OVSBridgeOptions { + if in == nil { + return nil + } + out := new(OVSBridgeOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVSBridgePortConfig) DeepCopyInto(out *OVSBridgePortConfig) { + *out = *in + if in.Bond != nil { + in, out := &in.Bond, &out.Bond + *out = new(OVSBridgeBondConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVSBridgePortConfig. +func (in *OVSBridgePortConfig) DeepCopy() *OVSBridgePortConfig { + if in == nil { + return nil + } + out := new(OVSBridgePortConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVSBridgeStpOptions) DeepCopyInto(out *OVSBridgeStpOptions) { + *out = *in + if in.Enabled != nil { + in, out := &in.Enabled, &out.Enabled + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVSBridgeStpOptions. +func (in *OVSBridgeStpOptions) DeepCopy() *OVSBridgeStpOptions { + if in == nil { + return nil + } + out := new(OVSBridgeStpOptions) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVSDBGlobalConfig) DeepCopyInto(out *OVSDBGlobalConfig) { + *out = *in + if in.ExternalIds != nil { + in, out := &in.ExternalIds, &out.ExternalIds + *out = new(map[string]*intstr.IntOrString) + if **in != nil { + in, out := *in, *out + *out = make(map[string]*intstr.IntOrString, len(*in)) + for key, val := range *in { + var outVal *intstr.IntOrString + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = new(intstr.IntOrString) + **out = **in + } + (*out)[key] = outVal + } + } + } + if in.OtherConfig != nil { + in, out := &in.OtherConfig, &out.OtherConfig + *out = new(map[string]*intstr.IntOrString) + if **in != nil { + in, out := *in, *out + *out = make(map[string]*intstr.IntOrString, len(*in)) + for key, val := range *in { + var outVal *intstr.IntOrString + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = new(intstr.IntOrString) + **out = **in + } + (*out)[key] = outVal + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVSDBGlobalConfig. +func (in *OVSDBGlobalConfig) DeepCopy() *OVSDBGlobalConfig { + if in == nil { + return nil + } + out := new(OVSDBGlobalConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVSDBIfaceConfig) DeepCopyInto(out *OVSDBIfaceConfig) { + *out = *in + if in.ExternalIds != nil { + in, out := &in.ExternalIds, &out.ExternalIds + *out = new(map[string]*intstr.IntOrString) + if **in != nil { + in, out := *in, *out + *out = make(map[string]*intstr.IntOrString, len(*in)) + for key, val := range *in { + var outVal *intstr.IntOrString + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = new(intstr.IntOrString) + **out = **in + } + (*out)[key] = outVal + } + } + } + if in.OtherConfig != nil { + in, out := &in.OtherConfig, &out.OtherConfig + *out = new(map[string]*intstr.IntOrString) + if **in != nil { + in, out := *in, *out + *out = make(map[string]*intstr.IntOrString, len(*in)) + for key, val := range *in { + var outVal *intstr.IntOrString + if val == nil { + (*out)[key] = nil + } else { + inVal := (*in)[key] + in, out := &inVal, &outVal + *out = new(intstr.IntOrString) + **out = **in + } + (*out)[key] = outVal + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVSDBIfaceConfig. +func (in *OVSDBIfaceConfig) DeepCopy() *OVSDBIfaceConfig { + if in == nil { + return nil + } + out := new(OVSDBIfaceConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVSDpdkConfig) DeepCopyInto(out *OVSDpdkConfig) { + *out = *in + if in.RxQueue != nil { + in, out := &in.RxQueue, &out.RxQueue + *out = new(uint32) + **out = **in + } + if in.NRxqDesc != nil { + in, out := &in.NRxqDesc, &out.NRxqDesc + *out = new(uint32) + **out = **in + } + if in.NTxqDesc != nil { + in, out := &in.NTxqDesc, &out.NTxqDesc + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVSDpdkConfig. +func (in *OVSDpdkConfig) DeepCopy() *OVSDpdkConfig { + if in == nil { + return nil + } + out := new(OVSDpdkConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVSInterface) DeepCopyInto(out *OVSInterface) { + *out = *in + if in.Patch != nil { + in, out := &in.Patch, &out.Patch + *out = new(OVSPatchConfig) + **out = **in + } + if in.Dpdk != nil { + in, out := &in.Dpdk, &out.Dpdk + *out = new(OVSDpdkConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVSInterface. +func (in *OVSInterface) DeepCopy() *OVSInterface { + if in == nil { + return nil + } + out := new(OVSInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *OVSPatchConfig) DeepCopyInto(out *OVSPatchConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OVSPatchConfig. +func (in *OVSPatchConfig) DeepCopy() *OVSPatchConfig { + if in == nil { + return nil + } + out := new(OVSPatchConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RouteEntry) DeepCopyInto(out *RouteEntry) { + *out = *in + if in.State != nil { + in, out := &in.State, &out.State + *out = new(RouteState) + **out = **in + } + if in.Destination != nil { + in, out := &in.Destination, &out.Destination + *out = new(string) + **out = **in + } + if in.NextHopIface != nil { + in, out := &in.NextHopIface, &out.NextHopIface + *out = new(string) + **out = **in + } + if in.NextHopAddr != nil { + in, out := &in.NextHopAddr, &out.NextHopAddr + *out = new(string) + **out = **in + } + if in.Metric != nil { + in, out := &in.Metric, &out.Metric + *out = new(intstr.IntOrString) + **out = **in + } + if in.TableID != nil { + in, out := &in.TableID, &out.TableID + *out = new(intstr.IntOrString) + **out = **in + } + if in.Weight != nil { + in, out := &in.Weight, &out.Weight + *out = new(intstr.IntOrString) + **out = **in + } + if in.RouteType != nil { + in, out := &in.RouteType, &out.RouteType + *out = new(RouteType) + **out = **in + } + if in.Cwnd != nil { + in, out := &in.Cwnd, &out.Cwnd + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteEntry. +func (in *RouteEntry) DeepCopy() *RouteEntry { + if in == nil { + return nil + } + out := new(RouteEntry) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RouteRuleEntry) DeepCopyInto(out *RouteRuleEntry) { + *out = *in + if in.Family != nil { + in, out := &in.Family, &out.Family + *out = new(AddressFamily) + **out = **in + } + if in.State != nil { + in, out := &in.State, &out.State + *out = new(RouteRuleState) + **out = **in + } + if in.IPFrom != nil { + in, out := &in.IPFrom, &out.IPFrom + *out = new(string) + **out = **in + } + if in.IPTo != nil { + in, out := &in.IPTo, &out.IPTo + *out = new(string) + **out = **in + } + if in.Priority != nil { + in, out := &in.Priority, &out.Priority + *out = new(intstr.IntOrString) + **out = **in + } + if in.TableID != nil { + in, out := &in.TableID, &out.TableID + *out = new(intstr.IntOrString) + **out = **in + } + if in.Fwmark != nil { + in, out := &in.Fwmark, &out.Fwmark + *out = new(intstr.IntOrString) + **out = **in + } + if in.Fwmask != nil { + in, out := &in.Fwmask, &out.Fwmask + *out = new(intstr.IntOrString) + **out = **in + } + if in.Action != nil { + in, out := &in.Action, &out.Action + *out = new(RouteRuleAction) + **out = **in + } + if in.Iif != nil { + in, out := &in.Iif, &out.Iif + *out = new(string) + **out = **in + } + if in.SuppressPrefixLength != nil { + in, out := &in.SuppressPrefixLength, &out.SuppressPrefixLength + *out = new(uint32) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteRuleEntry. +func (in *RouteRuleEntry) DeepCopy() *RouteRuleEntry { + if in == nil { + return nil + } + out := new(RouteRuleEntry) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *RouteRules) DeepCopyInto(out *RouteRules) { + *out = *in + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = new([]RouteRuleEntry) + if **in != nil { + in, out := *in, *out + *out = make([]RouteRuleEntry, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new RouteRules. +func (in *RouteRules) DeepCopy() *RouteRules { + if in == nil { + return nil + } + out := new(RouteRules) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Routes) DeepCopyInto(out *Routes) { + *out = *in + if in.Running != nil { + in, out := &in.Running, &out.Running + *out = new([]RouteEntry) + if **in != nil { + in, out := *in, *out + *out = make([]RouteEntry, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } + if in.Config != nil { + in, out := &in.Config, &out.Config + *out = new([]RouteEntry) + if **in != nil { + in, out := *in, *out + *out = make([]RouteEntry, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Routes. +func (in *Routes) DeepCopy() *Routes { + if in == nil { + return nil + } + out := new(Routes) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SrIovConfig) DeepCopyInto(out *SrIovConfig) { + *out = *in + if in.TotalVfs != nil { + in, out := &in.TotalVfs, &out.TotalVfs + *out = new(intstr.IntOrString) + **out = **in + } + if in.Vfs != nil { + in, out := &in.Vfs, &out.Vfs + *out = new([]SrIovVfConfig) + if **in != nil { + in, out := *in, *out + *out = make([]SrIovVfConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SrIovConfig. +func (in *SrIovConfig) DeepCopy() *SrIovConfig { + if in == nil { + return nil + } + out := new(SrIovConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SrIovVfConfig) DeepCopyInto(out *SrIovVfConfig) { + *out = *in + if in.MacAddress != nil { + in, out := &in.MacAddress, &out.MacAddress + *out = new(string) + **out = **in + } + if in.SpoofCheck != nil { + in, out := &in.SpoofCheck, &out.SpoofCheck + *out = new(bool) + **out = **in + } + if in.Trust != nil { + in, out := &in.Trust, &out.Trust + *out = new(bool) + **out = **in + } + if in.MinTxRate != nil { + in, out := &in.MinTxRate, &out.MinTxRate + *out = new(intstr.IntOrString) + **out = **in + } + if in.MaxTxRate != nil { + in, out := &in.MaxTxRate, &out.MaxTxRate + *out = new(intstr.IntOrString) + **out = **in + } + if in.VlanID != nil { + in, out := &in.VlanID, &out.VlanID + *out = new(intstr.IntOrString) + **out = **in + } + if in.Qos != nil { + in, out := &in.Qos, &out.Qos + *out = new(intstr.IntOrString) + **out = **in + } + if in.VlanProto != nil { + in, out := &in.VlanProto, &out.VlanProto + *out = new(VlanProtocol) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SrIovVfConfig. +func (in *SrIovVfConfig) DeepCopy() *SrIovVfConfig { + if in == nil { + return nil + } + out := new(SrIovVfConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *UnknownInterface) DeepCopyInto(out *UnknownInterface) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new UnknownInterface. +func (in *UnknownInterface) DeepCopy() *UnknownInterface { + if in == nil { + return nil + } + out := new(UnknownInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VethConfig) DeepCopyInto(out *VethConfig) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VethConfig. +func (in *VethConfig) DeepCopy() *VethConfig { + if in == nil { + return nil + } + out := new(VethConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VlanConfig) DeepCopyInto(out *VlanConfig) { + *out = *in + if in.Protocol != nil { + in, out := &in.Protocol, &out.Protocol + *out = new(VlanProtocol) + **out = **in + } + if in.RegistrationProtocol != nil { + in, out := &in.RegistrationProtocol, &out.RegistrationProtocol + *out = new(VlanRegistrationProtocol) + **out = **in + } + if in.ReorderHeaders != nil { + in, out := &in.ReorderHeaders, &out.ReorderHeaders + *out = new(bool) + **out = **in + } + if in.LooseBinding != nil { + in, out := &in.LooseBinding, &out.LooseBinding + *out = new(bool) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VlanConfig. +func (in *VlanConfig) DeepCopy() *VlanConfig { + if in == nil { + return nil + } + out := new(VlanConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VlanInterface) DeepCopyInto(out *VlanInterface) { + *out = *in + if in.Vlan != nil { + in, out := &in.Vlan, &out.Vlan + *out = new(VlanConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VlanInterface. +func (in *VlanInterface) DeepCopy() *VlanInterface { + if in == nil { + return nil + } + out := new(VlanInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VrfConfig) DeepCopyInto(out *VrfConfig) { + *out = *in + if in.Port != nil { + in, out := &in.Port, &out.Port + *out = new([]string) + if **in != nil { + in, out := *in, *out + *out = make([]string, len(*in)) + copy(*out, *in) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VrfConfig. +func (in *VrfConfig) DeepCopy() *VrfConfig { + if in == nil { + return nil + } + out := new(VrfConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VrfInterface) DeepCopyInto(out *VrfInterface) { + *out = *in + if in.Vrf != nil { + in, out := &in.Vrf, &out.Vrf + *out = new(VrfConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VrfInterface. +func (in *VrfInterface) DeepCopy() *VrfInterface { + if in == nil { + return nil + } + out := new(VrfInterface) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VxlanConfig) DeepCopyInto(out *VxlanConfig) { + *out = *in + if in.Learning != nil { + in, out := &in.Learning, &out.Learning + *out = new(bool) + **out = **in + } + if in.Local != nil { + in, out := &in.Local, &out.Local + *out = new(string) + **out = **in + } + if in.Remote != nil { + in, out := &in.Remote, &out.Remote + *out = new(string) + **out = **in + } + if in.DstPort != nil { + in, out := &in.DstPort, &out.DstPort + *out = new(intstr.IntOrString) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VxlanConfig. +func (in *VxlanConfig) DeepCopy() *VxlanConfig { + if in == nil { + return nil + } + out := new(VxlanConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VxlanInterface) DeepCopyInto(out *VxlanInterface) { + *out = *in + if in.Vxlan != nil { + in, out := &in.Vxlan, &out.Vxlan + *out = new(VxlanConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VxlanInterface. +func (in *VxlanInterface) DeepCopy() *VxlanInterface { + if in == nil { + return nil + } + out := new(VxlanInterface) + in.DeepCopyInto(out) + return out +} diff --git a/v2/zz_generated.types.go b/v2/zz_generated.types.go new file mode 100644 index 0000000..6dac7b5 --- /dev/null +++ b/v2/zz_generated.types.go @@ -0,0 +1,2854 @@ +/* +Copyright The NMState Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v2 + +import ( + "k8s.io/apimachinery/pkg/util/intstr" +) + +// +kubebuilder:validation:Enum=1;2;5;6;7;8;127; +type LldpNeighborTlvType uint8 + +const LldpNeighborTlvTypeChassisID = LldpNeighborTlvType(1) +const LldpNeighborTlvTypePort = LldpNeighborTlvType(2) +const LldpNeighborTlvTypeSystemName = LldpNeighborTlvType(5) +const LldpNeighborTlvTypeSystemDescription = LldpNeighborTlvType(6) +const LldpNeighborTlvTypeSystemCapabilities = LldpNeighborTlvType(7) +const LldpNeighborTlvTypeManagementAddress = LldpNeighborTlvType(8) +const LldpNeighborTlvTypeOrganizationSpecific = LldpNeighborTlvType(127) + +// enum LldpNeighborTlvType + +// +kubebuilder:validation:Enum=3;1;2;4; +type LldpOrgSubtype uint8 + +const LldpOrgSubtypeVlan = LldpOrgSubtype(3) +const LldpOrgSubtypeMacPhyConf = LldpOrgSubtype(1) +const LldpOrgSubtypePpvids = LldpOrgSubtype(2) +const LldpOrgSubtypeMaxFrameSize = LldpOrgSubtype(4) + +// enum LldpOrgSubtype + +// +kubebuilder:validation:Enum="00:80:c2";"00:12:0f";"00:80:c2";"00:12:0f"; +type LldpOrgOiu string + +const LldpOrgOiuVlan = LldpOrgOiu("00:80:c2") +const LldpOrgOiuMacPhyConf = LldpOrgOiu("00:12:0f") +const LldpOrgOiuPpvids = LldpOrgOiu("00:80:c2") +const LldpOrgOiuMaxFrameSize = LldpOrgOiu("00:12:0f") + +// enum LldpOrgOiu + +// +k8s:deepcopy-gen=true +type LldpConfig struct { + Enabled bool `json:"enabled"` + Neighbors [][]LldpNeighborTlv `json:"neighbors,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LldpNeighborTlv struct { + *LldpSystemName `json:",omitempty"` + *LldpSystemDescription `json:",omitempty"` + *LldpSystemCapabilities `json:",omitempty"` + *LldpChassisID `json:",omitempty"` + *LldpPortID `json:",omitempty"` + *LldpVlans `json:",omitempty"` + *LldpMacPhy `json:",omitempty"` + *LldpPpvids `json:",omitempty"` + *LldpMgmtAddrs `json:",omitempty"` + *LldpMaxFrameSize `json:",omitempty"` +} + +// +k8s:deepcopy-gen=true +type LldpSystemName struct { + Ty *LldpNeighborTlvType `json:"type,omitempty"` + SystemName *string `json:"system-name,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LldpSystemDescription struct { + Ty *LldpNeighborTlvType `json:"type,omitempty"` + SystemDescription *string `json:"system-description,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LldpChassisID struct { + Ty *LldpNeighborTlvType `json:"type,omitempty"` + ChassisID *string `json:"chassis-id,omitempty"` + ChassisIDType *LldpChassisIDType `json:"chassis-id-type,omitempty"` + Description *string `json:"_description,omitempty"` +} + +// +kubebuilder:validation:Enum=0;1;2;3;4;5;6;7; +type LldpChassisIDType uint8 + +const LldpChassisIDTypeReserved = LldpChassisIDType(0) +const LldpChassisIDTypeChassisComponent = LldpChassisIDType(1) +const LldpChassisIDTypeInterfaceAlias = LldpChassisIDType(2) +const LldpChassisIDTypePortComponent = LldpChassisIDType(3) +const LldpChassisIDTypeMacAddress = LldpChassisIDType(4) +const LldpChassisIDTypeNetworkAddress = LldpChassisIDType(5) +const LldpChassisIDTypeInterfaceName = LldpChassisIDType(6) +const LldpChassisIDTypeLocallyAssigned = LldpChassisIDType(7) + +// enum LldpChassisIDType + +// +k8s:deepcopy-gen=true +type LldpSystemCapabilities struct { + Ty *LldpNeighborTlvType `json:"type,omitempty"` + SystemCapabilities *[]LldpSystemCapability `json:"system-capabilities,omitempty"` +} + +type LldpSystemCapability string + +const LldpSystemCapabilityRepeater = LldpSystemCapability("Repeater") +const LldpSystemCapabilityMacBridgeComponent = LldpSystemCapability("MAC Bridge component") +const LldpSystemCapabilityAccessPoint = LldpSystemCapability("802.11 Access Point (AP)") +const LldpSystemCapabilityRouter = LldpSystemCapability("Router") +const LldpSystemCapabilityTelephone = LldpSystemCapability("Telephone") +const LldpSystemCapabilityDocsisCableDevice = LldpSystemCapability("DOCSIS cable device") +const LldpSystemCapabilityStationOnly = LldpSystemCapability("Station Only") +const LldpSystemCapabilityCVlanComponent = LldpSystemCapability("C-VLAN component") +const LldpSystemCapabilitySVlanComponent = LldpSystemCapability("S-VLAN component") +const LldpSystemCapabilityTwoPortMacRelayComponent = LldpSystemCapability("Two-port MAC Relay component") + +// enum LldpSystemCapability + +// +k8s:deepcopy-gen=true +type LldpPortID struct { + Ty *LldpNeighborTlvType `json:"type,omitempty"` + PortID *string `json:"port-id,omitempty"` + PortIDType *LldpPortIDType `json:"port-id-type,omitempty"` + Description *string `json:"_description,omitempty"` +} + +// +kubebuilder:validation:Enum=0;1;2;3;4;5;6;7; +type LldpPortIDType uint8 + +const LldpPortIDTypeReserved = LldpPortIDType(0) +const LldpPortIDTypeInterfaceAlias = LldpPortIDType(1) +const LldpPortIDTypePortComponent = LldpPortIDType(2) +const LldpPortIDTypeMacAddress = LldpPortIDType(3) +const LldpPortIDTypeNetworkAddress = LldpPortIDType(4) +const LldpPortIDTypeInterfaceName = LldpPortIDType(5) +const LldpPortIDTypeAgentCircuitID = LldpPortIDType(6) +const LldpPortIDTypeLocallyAssigned = LldpPortIDType(7) + +// enum LldpPortIDType + +// +k8s:deepcopy-gen=true +type LldpVlans struct { + Ty *LldpNeighborTlvType `json:"type,omitempty"` + Ieee8021Vlans *[]LldpVlan `json:"ieee-802-1-vlans,omitempty"` + Oui *LldpOrgOiu `json:"oui,omitempty"` + Subtype *LldpOrgSubtype `json:"subtype,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LldpVlan struct { + Name *string `json:"name,omitempty"` + Vid *uint32 `json:"vid,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LldpMacPhy struct { + Ty *LldpNeighborTlvType `json:"type,omitempty"` + Ieee8023MacPhyConf *LldpMacPhyConf `json:"ieee-802-3-mac-phy-conf,omitempty"` + Oui *LldpOrgOiu `json:"oui,omitempty"` + Subtype *LldpOrgSubtype `json:"subtype,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LldpMacPhyConf struct { + Autoneg *bool `json:"autoneg,omitempty"` + OperationalMauType *uint16 `json:"operational-mau-type,omitempty"` + PmdAutonegCap *uint16 `json:"pmd-autoneg-cap,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LldpPpvids struct { + Ty *LldpNeighborTlvType `json:"type,omitempty"` + Ieee8021Ppvids *[]uint32 `json:"ieee-802-1-ppvids,omitempty"` + Oui *LldpOrgOiu `json:"oui,omitempty"` + Subtype *LldpOrgSubtype `json:"subtype,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LldpMgmtAddrs struct { + Ty *LldpNeighborTlvType `json:"type,omitempty"` + ManagementAddresses *[]LldpMgmtAddr `json:"management-addresses,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LldpMgmtAddr struct { + Address *string `json:"address,omitempty"` + AddressSubtype *LldpAddressFamily `json:"address-subtype,omitempty"` + InterfaceNumber *uint32 `json:"interface-number,omitempty"` + InterfaceNumberSubtype *uint32 `json:"interface-number-subtype,omitempty"` +} + +// +kubebuilder:validation:Enum="Unknown";"IPv4";"IPv6";"MAC"; +type LldpAddressFamily string + +const LldpAddressFamilyUnknown = LldpAddressFamily("Unknown") +const LldpAddressFamilyIpv4 = LldpAddressFamily("IPv4") +const LldpAddressFamilyIpv6 = LldpAddressFamily("IPv6") +const LldpAddressFamilyMac = LldpAddressFamily("MAC") + +// enum LldpAddressFamily + +// +k8s:deepcopy-gen=true +type LldpMaxFrameSize struct { + Ty *LldpNeighborTlvType `json:"type,omitempty"` + Ieee8023MaxFrameSize *uint32 `json:"ieee-802-3-max-frame-size,omitempty"` + Oui *LldpOrgOiu `json:"oui,omitempty"` + Subtype *LldpOrgSubtype `json:"subtype,omitempty"` +} + +// Ieee8021XConfig The IEEE 802.1X authentication configuration. The example yaml output of +// [crate::NetworkState] with IEEE 802.1X authentication interface: +// ```yml +// --- +// interfaces: +// - name: eth1 +// type: ethernet +// state: up +// 802.1x: +// ca-cert: /etc/pki/802-1x-test/ca.crt +// client-cert: /etc/pki/802-1x-test/client.example.org.crt +// eap-methods: +// - tls +// identity: client.example.org +// private-key: /etc/pki/802-1x-test/client.example.org.key +// private-key-password: password +// +// ``` +// +k8s:deepcopy-gen=true +type Ieee8021XConfig struct { + Identity *string `json:"identity,omitempty"` + // Eap Deserialize and serialize from/to `eap-methods`. + Eap *[]string `json:"eap-methods,omitempty"` + // PrivateKey Deserialize and serialize from/to `private-key`. + PrivateKey *string `json:"private-key,omitempty"` + // ClientCert Deserialize and serialize from/to `client-cert`. + ClientCert *string `json:"client-cert,omitempty"` + // CaCert Deserialize and serialize from/to `ca-cert`. + CaCert *string `json:"ca-cert,omitempty"` + // PrivateKeyPassword Deserialize and serialize from/to `private-key-password`. + // Replaced to `<_password_hid_by_nmstate>` when querying. + PrivateKeyPassword *string `json:"private-key-password,omitempty"` +} + +// +k8s:deepcopy-gen=true +type MptcpConfig struct { + // AddressFlags Automatically assign MPTCP flags to all valid IP addresses of this + // interface including both static and dynamic ones. + AddressFlags *[]MptcpAddressFlag `json:"address-flags,omitempty"` +} + +// +kubebuilder:validation:Enum="signal";"subflow";"backup";"fullmesh"; +type MptcpAddressFlag string + +// MptcpAddressFlagSignal The endpoint will be announced/signaled to each peer via an MPTCP +// ADD_ADDR sub-option. Upon reception of an ADD_ADDR sub-option, the +// peer can try to create additional subflows. Cannot used along with +// MptcpAddressFlag::Fullmesh as Linux kernel enforced. +const MptcpAddressFlagSignal = MptcpAddressFlag("signal") + +// MptcpAddressFlagSubflow If additional subflow creation is allowed by the MPTCP limits, the +// MPTCP path manager will try to create an additional subflow using +// this endpoint as the source address after the MPTCP connection is +// established. +const MptcpAddressFlagSubflow = MptcpAddressFlag("subflow") + +// MptcpAddressFlagBackup If this is a subflow endpoint, the subflows created using this endpoint +// will have the backup flag set during the connection process. This flag +// instructs the peer to only send data on a given subflow when all +// non-backup subflows are unavailable. This does not affect outgoing +// data, where subflow priority is determined by the backup/non-backup +// flag received from the peer. +const MptcpAddressFlagBackup = MptcpAddressFlag("backup") + +// MptcpAddressFlagFullmesh If this is a subflow endpoint and additional subflow creation is +// allowed by the MPTCP limits, the MPTCP path manager will try to +// create an additional subflow for each known peer address, using +// this endpoint as the source address. This will occur after the +// MPTCP connection is established. If the peer did not announce any +// additional addresses using the MPTCP ADD_ADDR sub-option, this will +// behave the same as a plain subflow endpoint. When the peer does +// announce addresses, each received ADD_ADDR sub-option will trigger +// creation of an additional subflow to generate a full mesh topology. +const MptcpAddressFlagFullmesh = MptcpAddressFlag("fullmesh") + +// enum MptcpAddressFlag + +// +k8s:deepcopy-gen=true +type OVSDBGlobalConfig struct { + ExternalIds *map[string]*intstr.IntOrString `json:"external_ids,omitempty"` + OtherConfig *map[string]*intstr.IntOrString `json:"other_config,omitempty"` +} + +// +k8s:deepcopy-gen=true +type OVSDBIfaceConfig struct { + ExternalIds *map[string]*intstr.IntOrString `json:"external_ids,omitempty"` + // OtherConfig OpenvSwitch specific `other_config`. Please refer to + // manpage `ovs-vswitchd.conf.db(5)` for more detail. + // When setting to None, nmstate will try to preserve current + // `other_config`, otherwise, nmstate will override all `other_config` + // for specified interface. + OtherConfig *map[string]*intstr.IntOrString `json:"other_config,omitempty"` +} + +// InterfaceType Interface type +// +kubebuilder:validation:Enum="bond";"linux-bridge";"dummy";"ethernet";"hsr";"loopback";"mac-vlan";"mac-vtap";"ovs-bridge";"ovs-interface";"veth";"vlan";"vrf";"vxlan";"infiniband";"tun";"macsec";"ipsec";"xfrm";"unknown"; +type InterfaceType string + +// InterfaceTypeBond [Bond interface](https://www.kernel.org/doc/Documentation/networking/bonding.txt) +// Deserialize and serialize from/to 'bond' +const InterfaceTypeBond = InterfaceType("bond") + +// InterfaceTypeLinuxBridge Bridge provided by Linux kernel. +// Deserialize and serialize from/to 'linux-bridge'. +const InterfaceTypeLinuxBridge = InterfaceType("linux-bridge") + +// InterfaceTypeDummy Dummy interface. +// Deserialize and serialize from/to 'dummy'. +const InterfaceTypeDummy = InterfaceType("dummy") + +// InterfaceTypeEthernet Ethernet interface. +// Deserialize and serialize from/to 'ethernet'. +const InterfaceTypeEthernet = InterfaceType("ethernet") + +// InterfaceTypeHsr HSR interface. +// Deserialize and serialize from/to 'hsr'. +const InterfaceTypeHsr = InterfaceType("hsr") + +// InterfaceTypeLoopback Loopback interface. +// Deserialize and serialize from/to 'loopback'. +const InterfaceTypeLoopback = InterfaceType("loopback") + +// InterfaceTypeMacVlan MAC VLAN interface. +// Deserialize and serialize from/to 'mac-vlan'. +const InterfaceTypeMacVlan = InterfaceType("mac-vlan") + +// InterfaceTypeMacVtap MAC VTAP interface. +// Deserialize and serialize from/to 'mac-vtap'. +const InterfaceTypeMacVtap = InterfaceType("mac-vtap") + +// InterfaceTypeOVSBridge OpenvSwitch bridge. +// Deserialize and serialize from/to 'ovs-bridge'. +const InterfaceTypeOVSBridge = InterfaceType("ovs-bridge") + +// InterfaceTypeOVSInterface OpenvSwitch system interface. +// Deserialize and serialize from/to 'ovs-interface'. +const InterfaceTypeOVSInterface = InterfaceType("ovs-interface") + +// InterfaceTypeVeth Virtual ethernet provide by Linux kernel. +// Deserialize and serialize from/to 'veth'. +const InterfaceTypeVeth = InterfaceType("veth") + +// InterfaceTypeVlan VLAN interface. +// Deserialize and serialize from/to 'vlan'. +const InterfaceTypeVlan = InterfaceType("vlan") + +// InterfaceTypeVrf [Virtual Routing and Forwarding interface](https://www.kernel.org/doc/html/latest/networking/vrf.html) +// Deserialize and serialize from/to 'vrf'. +const InterfaceTypeVrf = InterfaceType("vrf") + +// InterfaceTypeVxlan VxVLAN interface. +// Deserialize and serialize from/to 'vxlan'. +const InterfaceTypeVxlan = InterfaceType("vxlan") + +// InterfaceTypeInfiniBand [IP over InfiniBand interface](https://docs.kernel.org/infiniband/ipoib.html) +// Deserialize and serialize from/to 'infiniband'. +const InterfaceTypeInfiniBand = InterfaceType("infiniband") + +// InterfaceTypeTun TUN interface. Only used for query, will be ignored when applying. +// Deserialize and serialize from/to 'tun'. +const InterfaceTypeTun = InterfaceType("tun") + +// InterfaceTypeMacSec MACsec interface. +// Deserialize and serialize from/to 'macsec' +const InterfaceTypeMacSec = InterfaceType("macsec") + +// InterfaceTypeIpsec Ipsec connection. +const InterfaceTypeIpsec = InterfaceType("ipsec") + +// InterfaceTypeXfrm Linux Xfrm kernel interface +const InterfaceTypeXfrm = InterfaceType("xfrm") + +// InterfaceTypeUnknown Unknown interface. +const InterfaceTypeUnknown = InterfaceType("unknown") + +// enum InterfaceType + +// InterfaceState The state of interface +// +kubebuilder:validation:Enum="up";"down";"absent";"unknown";"ignore"; +type InterfaceState string + +// InterfaceStateUp Interface is up and running. +// Deserialize and serialize from/to 'up'. +const InterfaceStateUp = InterfaceState("up") + +// InterfaceStateDown For apply action, down means configuration still exist but +// deactivate. The virtual interface will be removed and other interface +// will be reverted to down state or up with IP disabled state. +// Deserialize and serialize from/to 'down'. +const InterfaceStateDown = InterfaceState("down") + +// InterfaceStateAbsent Only for apply action to remove configuration and deactivate the +// interface. +const InterfaceStateAbsent = InterfaceState("absent") + +// InterfaceStateUnknown Unknown state. +const InterfaceStateUnknown = InterfaceState("unknown") + +// InterfaceStateIgnore Interface is not managed by backend. For apply action, interface marked +// as ignore will not be changed and will not cause verification failure +// neither. +// When desired controller listed currently ignored interfaces as its +// port, nmstate will automatically convert these ignored interfaces from +// 'state: ignore' to 'state: up' only when: +// 1. This ignored port is not mentioned in desire state. +// 2. This ignored port is listed as port of a desired controller. +// 3. Controller interface is new or does not contain ignored interfaces +// currently. +// +// Deserialize and serialize from/to 'ignore'. +const InterfaceStateIgnore = InterfaceState("ignore") + +// enum InterfaceState + +// UnknownInterface Holder for interface with known interface type defined. +// During apply action, nmstate can resolve unknown interface to first +// found interface type. +// +k8s:deepcopy-gen=true +type UnknownInterface struct { + Other string `json:"other,omitempty"` +} + +// Interface Represent a kernel or user space network interface. +// +k8s:deepcopy-gen=true +type Interface struct { + BaseInterface `json:",omitempty"` + *BridgeInterface `json:",omitempty"` + *BondInterface `json:",omitempty"` + *EthernetInterface `json:",omitempty"` + *HsrInterface `json:",omitempty"` + *OVSInterface `json:",omitempty"` + *VlanInterface `json:",omitempty"` + *VxlanInterface `json:",omitempty"` + *MacVlanInterface `json:",omitempty"` + *MacVtapInterface `json:",omitempty"` + *VrfInterface `json:",omitempty"` + *InfiniBandInterface `json:",omitempty"` + *MacSecInterface `json:",omitempty"` + *IpsecInterface `json:",omitempty"` +} + +// InterfaceIdentifier Interface Identifier defines the method for network backend on matching +// network interface +// +kubebuilder:validation:Enum="name";"mac-address"; +type InterfaceIdentifier string + +// InterfaceIdentifierName Use interface name to match the network interface, default value. +// Deserialize and serialize from/to 'name'. +const InterfaceIdentifierName = InterfaceIdentifier("name") + +// InterfaceIdentifierMacAddress Use interface MAC address to match the network interface. +// Deserialize and serialize from/to 'mac-address'. +const InterfaceIdentifierMacAddress = InterfaceIdentifier("mac-address") + +// enum InterfaceIdentifier + +// DNSState DNS resolver state. Example partial yaml output of [NetworkState] with +// static DNS config: +// ```yaml +// --- +// dns-resolver: +// +// running: +// server: +// - 2001:db8:1::250 +// - 192.0.2.250 +// search: +// - example.org +// - example.net +// config: +// search: +// - example.org +// - example.net +// server: +// - 2001:db8:1::250 +// - 192.0.2.250 +// options: +// - trust-ad +// - rotate +// +// ``` +// To purge all static DNS configuration: +// ```yml +// --- +// dns-resolver: +// +// config: {} +// +// ``` +// +k8s:deepcopy-gen=true +type DNSState struct { + // Running The running effective state. The DNS server might be from DHCP(IPv6 + // autoconf) or manual setup. + // Ignored when applying state. + Running *DNSClientState `json:"running,omitempty"` + // Config The static saved DNS resolver config. + // When applying, if this not mentioned(None), current static DNS config + // will be preserved as it was. If defined(Some), will override current + // static DNS config. + Config *DNSClientState `json:"config,omitempty"` +} + +// DNSClientState DNS Client state +// +k8s:deepcopy-gen=true +type DNSClientState struct { + // Server Name server IP address list. + // To remove all existing servers, please use `Some(Vec::new())`. + // If undefined(set to `None`), will preserve current config. + Server *[]string `json:"server,omitempty"` + // Search Search list for host-name lookup. + // To remove all existing search, please use `Some(Vec::new())`. + // If undefined(set to `None`), will preserve current config. + Search *[]string `json:"search,omitempty"` + // Options DNS option list. + // To remove all existing search, please use `Some(Vec::new())`. + // If undefined(set to `None`), will preserve current config. + Options *[]string `json:"options,omitempty"` +} + +// Routes IP routing status +// +k8s:deepcopy-gen=true +type Routes struct { + // Running Running effected routes containing route from universe or link scope, + // and only from these protocols: + // * boot (often used by `iproute` command) + // * static + // * ra + // * dhcp + // * mrouted + // * keepalived + // * babel + // + // Ignored when applying. + Running *[]RouteEntry `json:"running,omitempty"` + // Config Static routes containing route from universe or link scope, + // and only from these protocols: + // * boot (often used by `iproute` command) + // * static + // + // When applying, `None` means preserve current routes. + // This property is not overriding but adding specified routes to + // existing routes. To delete a route entry, please [RouteEntry.state] as + // [RouteState::Absent]. Any property of absent [RouteEntry] set to + // `None` means wildcard. For example, this [crate::NetworkState] could + // remove all routes next hop to interface eth1(showing in yaml): + // ```yaml + // routes: + // config: + // - next-hop-interface: eth1 + // state: absent + // ``` + // + // To change a route entry, you need to delete old one and add new one(can + // be in single transaction). + Config *[]RouteEntry `json:"config,omitempty"` +} + +// +kubebuilder:validation:Enum="absent"; +type RouteState string + +// RouteStateAbsent Mark a route entry as absent to remove it. +const RouteStateAbsent = RouteState("absent") + +// enum RouteState + +// RouteEntry Route entry +// +k8s:deepcopy-gen=true +type RouteEntry struct { + // State Only used for delete route when applying. + State *RouteState `json:"state,omitempty"` + // Destination Route destination address or network + // Mandatory for every non-absent routes. + Destination *string `json:"destination,omitempty"` + // NextHopIface Route next hop interface name. + // Serialize and deserialize to/from `next-hop-interface`. + // Mandatory for every non-absent routes except for route with + // route type `Blackhole`, `Unreachable`, `Prohibit`. + NextHopIface *string `json:"next-hop-interface,omitempty"` + // NextHopAddr Route next hop IP address. + // Serialize and deserialize to/from `next-hop-address`. + // When setting this as empty string for absent route, it will only delete + // routes __without__ `next-hop-address`. + NextHopAddr *string `json:"next-hop-address,omitempty"` + // Metric Route metric. [RouteEntry::USE_DEFAULT_METRIC] for default + // setting of network backend. + Metric *intstr.IntOrString `json:"metric,omitempty"` + // TableID Route table id. [RouteEntry::USE_DEFAULT_ROUTE_TABLE] for main + // route table 254. + TableID *intstr.IntOrString `json:"table-id,omitempty"` + // Weight ECMP(Equal-Cost Multi-Path) route weight + // The valid range of this property is 1-256. + Weight *intstr.IntOrString `json:"weight,omitempty"` + // RouteType Route type + // Serialize and deserialize to/from `route-type`. + RouteType *RouteType `json:"route-type,omitempty"` + // Cwnd Congestion window clamp + Cwnd *uint32 `json:"cwnd,omitempty"` +} + +// +kubebuilder:validation:Enum="blackhole";"unreachable";"prohibit"; +type RouteType string + +const RouteTypeBlackhole = RouteType("blackhole") +const RouteTypeUnreachable = RouteType("unreachable") +const RouteTypeProhibit = RouteType("prohibit") + +// enum RouteType + +// RouteRules Routing rules +// +k8s:deepcopy-gen=true +type RouteRules struct { + // Config When applying, `None` means preserve existing route rules. + // Nmstate is using partial editing for route rule, which means + // desired route rules only append to existing instead of overriding. + // To delete any route rule, please set [crate::RouteRuleEntry.state] to + // [RouteRuleState::Absent]. Any property set to None in absent route rule + // means wildcard. For example, this [crate::NetworkState] will delete all + // route rule looking up route table 500: + // ```yml + // --- + // route-rules: + // config: + // - state: absent + // route-table: 500 + // ``` + Config *[]RouteRuleEntry `json:"config,omitempty"` +} + +// +kubebuilder:validation:Enum="absent"; +type RouteRuleState string + +// RouteRuleStateAbsent Used for delete route rule +const RouteRuleStateAbsent = RouteRuleState("absent") + +// enum RouteRuleState + +// +k8s:deepcopy-gen=true +type RouteRuleEntry struct { + // Family Indicate the address family of the route rule. + Family *AddressFamily `json:"family,omitempty"` + // State Indicate this is normal route rule or absent route rule. + State *RouteRuleState `json:"state,omitempty"` + // IPFrom Source prefix to match. + // Serialize and deserialize to/from `ip-from`. + // When setting to empty string in absent route rule, it will only delete + // route rule __without__ `ip-from`. + IPFrom *string `json:"ip-from,omitempty"` + // IPTo Destination prefix to match. + // Serialize and deserialize to/from `ip-to`. + // When setting to empty string in absent route rule, it will only delete + // route rule __without__ `ip-to`. + IPTo *string `json:"ip-to,omitempty"` + // Priority Priority of this route rule. + // Bigger number means lower priority. + Priority *intstr.IntOrString `json:"priority,omitempty"` + // TableID The routing table ID to lookup if the rule selector matches. + // Serialize and deserialize to/from `route-table`. + TableID *intstr.IntOrString `json:"route-table,omitempty"` + // Fwmark Select the fwmark value to match + Fwmark *intstr.IntOrString `json:"fwmark,omitempty"` + // Fwmask Select the fwmask value to match + Fwmask *intstr.IntOrString `json:"fwmask,omitempty"` + // Action Actions for matching packages. + Action *RouteRuleAction `json:"action,omitempty"` + // Iif Incoming interface. + Iif *string `json:"iif,omitempty"` + // SuppressPrefixLength Prefix length of suppressor. + // Can deserialize from `suppress-prefix-length` or + // `suppress_prefixlength`. + // Serialize into `suppress-prefix-length`. + SuppressPrefixLength *uint32 `json:"suppress-prefix-length,omitempty"` +} + +// +kubebuilder:validation:Enum="blackhole";"unreachable";"prohibit"; +type RouteRuleAction string + +const RouteRuleActionBlackhole = RouteRuleAction("blackhole") +const RouteRuleActionUnreachable = RouteRuleAction("unreachable") +const RouteRuleActionProhibit = RouteRuleAction("prohibit") + +// enum RouteRuleAction + +// +k8s:deepcopy-gen=true +type InterfaceIP struct { + Enabled *bool `json:"enabled,omitempty"` + Dhcp *bool `json:"dhcp,omitempty"` + Autoconf *bool `json:"autoconf,omitempty"` + DhcpClientID *Dhcpv4ClientID `json:"dhcp-client-id,omitempty"` + DhcpDuid *Dhcpv6Duid `json:"dhcp-duid,omitempty"` + Addresses *[]InterfaceIPAddr `json:"address,omitempty"` + AutoDNS *bool `json:"auto-dns,omitempty"` + AutoGateway *bool `json:"auto-gateway,omitempty"` + AutoRoutes *bool `json:"auto-routes,omitempty"` + AutoTableID *intstr.IntOrString `json:"auto-route-table-id,omitempty"` + AutoRouteMetric *intstr.IntOrString `json:"auto-route-metric,omitempty"` + AddrGenMode *Ipv6AddrGenMode `json:"addr-gen-mode,omitempty"` + AllowExtraAddress *bool `json:"allow-extra-address,omitempty"` + Token *string `json:"token,omitempty"` + DhcpSendHostname *bool `json:"dhcp-send-hostname,omitempty"` + DhcpCustomHostname *string `json:"dhcp-custom-hostname,omitempty"` +} + +// +k8s:deepcopy-gen=true +type InterfaceIPAddr struct { + // IP IP address. + IP string `json:"ip"` + // PrefixLength Prefix length. + // Serialize and deserialize to/from `prefix-length`. + PrefixLength uint8 `json:"prefix-length"` + // MptcpFlags MPTCP flag on this IP address. + // Ignored when applying as nmstate does not support support IP address + // specific MPTCP flags. You should apply MPTCP flags at interface level + // via [BaseInterface.mptcp]. + MptcpFlags *[]MptcpAddressFlag `json:"mptcp-flags,omitempty"` + // ValidLifeTime Remaining time for IP address been valid. The output format is + // "32sec" or "forever". + // This property is query only, it will be ignored when applying. + // Serialize to `valid-life-time`. + // Deserialize from `valid-life-time` or `valid-left` or `valid-lft`. + ValidLifeTime *string `json:"valid-life-time,omitempty"` + // PreferredLifeTime Remaining time for IP address been preferred. The output format is + // "32sec" or "forever". + // This property is query only, it will be ignored when applying. + // Serialize to `preferred-life-time`. + // Deserialize from `preferred-life-time` or `preferred-left` or + // `preferred-lft`. + PreferredLifeTime *string `json:"preferred-life-time,omitempty"` +} + +// Dhcpv4ClientID DHCPv4 client ID +type Dhcpv4ClientID string + +// Dhcpv4ClientIDLinkLayerAddress Use link layer address as DHCPv4 client ID. +// Serialize and deserialize to/from `ll`. +const Dhcpv4ClientIDLinkLayerAddress = Dhcpv4ClientID("ll") + +// Dhcpv4ClientIDIaidPlusDuid RFC 4361 type 255, 32 bits IAID followed by DUID. +// Serialize and deserialize to/from `iaid+duid`. +const Dhcpv4ClientIDIaidPlusDuid = Dhcpv4ClientID("iaid+duid") + +// enum Dhcpv4ClientID + +// Dhcpv6Duid DHCPv6 Unique Identifier +type Dhcpv6Duid string + +// Dhcpv6DuidLinkLayerAddressPlusTime DUID Based on Link-Layer Address Plus Time +// Serialize and deserialize to/from `llt`. +const Dhcpv6DuidLinkLayerAddressPlusTime = Dhcpv6Duid("llt") + +// Dhcpv6DuidEnterpriseNumber DUID Assigned by Vendor Based on Enterprise Number +// Serialize and deserialize to/from `en`. +const Dhcpv6DuidEnterpriseNumber = Dhcpv6Duid("en") + +// Dhcpv6DuidLinkLayerAddress DUID Assigned by Vendor Based on Enterprise Number +// Serialize and deserialize to/from `ll`. +const Dhcpv6DuidLinkLayerAddress = Dhcpv6Duid("ll") + +// Dhcpv6DuidUUID DUID Based on Universally Unique Identifier +// Serialize and deserialize to/from `uuid`. +const Dhcpv6DuidUUID = Dhcpv6Duid("uuid") + +// enum Dhcpv6Duid + +// Ipv6AddrGenMode IPv6 address generation mode +type Ipv6AddrGenMode string + +// Ipv6AddrGenModeEui64 EUI-64 format defined by RFC 4862 +// Serialize and deserialize to/from `eui64`. +const Ipv6AddrGenModeEui64 = Ipv6AddrGenMode("eui64") + +// Ipv6AddrGenModeStablePrivacy Semantically Opaque Interface Identifiers defined by RFC 7217 +// Serialize and deserialize to/from `stable-privacy`. +const Ipv6AddrGenModeStablePrivacy = Ipv6AddrGenMode("stable-privacy") + +// enum Ipv6AddrGenMode + +// WaitIP Which IP stack should network backend wait before considering the interface +// activation finished. +// +kubebuilder:validation:Enum="any";"ipv4";"ipv6";"ipv4+ipv6"; +type WaitIP string + +// WaitIPAny The activation is considered done once IPv4 stack or IPv6 stack is +// configure +// Serialize and deserialize to/from `any`. +const WaitIPAny = WaitIP("any") + +// WaitIPIpv4 The activation is considered done once IPv4 stack is configured. +// Serialize and deserialize to/from `ipv4`. +const WaitIPIpv4 = WaitIP("ipv4") + +// WaitIPIpv6 The activation is considered done once IPv6 stack is configured. +// Serialize and deserialize to/from `ipv6`. +const WaitIPIpv6 = WaitIP("ipv6") + +// WaitIPIpv4AndIpv6 The activation is considered done once both IPv4 and IPv6 stack are +// configured. +// Serialize and deserialize to/from `ipv4+ipv6`. +const WaitIPIpv4AndIpv6 = WaitIP("ipv4+ipv6") + +// enum WaitIP + +// +kubebuilder:validation:Enum="ipv4";"ipv6";"unknown"; +type AddressFamily string + +const AddressFamilyIPv4 = AddressFamily("ipv4") +const AddressFamilyIPv6 = AddressFamily("ipv6") +const AddressFamilyUnknown = AddressFamily("unknown") + +// enum AddressFamily + +// +k8s:deepcopy-gen=true +type HostNameState struct { + Running *string `json:"running,omitempty"` + Config *string `json:"config,omitempty"` +} + +// BondInterface Bond interface. When serializing or deserializing, the [BaseInterface] will +// be flatted and [BondConfig] stored as `link-aggregation` section. The yaml +// output [crate::NetworkState] containing an example bond interface: +// ```yml +// interfaces: +// - name: bond99 +// type: bond +// state: up +// mac-address: 1A:24:D5:CA:76:54 +// mtu: 1500 +// min-mtu: 68 +// max-mtu: 65535 +// wait-ip: any +// ipv4: +// enabled: false +// ipv6: +// enabled: false +// accept-all-mac-addresses: false +// link-aggregation: +// mode: balance-rr +// options: +// all_slaves_active: dropped +// arp_all_targets: any +// arp_interval: 0 +// arp_validate: none +// downdelay: 0 +// lp_interval: 1 +// miimon: 100 +// min_links: 0 +// packets_per_slave: 1 +// primary_reselect: always +// resend_igmp: 1 +// updelay: 0 +// use_carrier: true +// port: +// - eth1 +// - eth2 +// +// ``` +// +k8s:deepcopy-gen=true +type BondInterface struct { + // Bond Bond specific settings. + Bond *BondConfig `json:"link-aggregation,omitempty"` +} + +// BondMode Bond mode +// +kubebuilder:validation:Enum="balance-rr";"0";"active-backup";"1";"balance-xor";"2";"broadcast";"3";"802.3ad";"4";"balance-tlb";"5";"balance-alb";"6";"unknown"; +type BondMode string + +// BondModeRoundRobin Deserialize and serialize from/to `balance-rr`. +// You can use integer 0 for deserializing to this mode. +const BondModeRoundRobin = BondMode("balance-rr") + +// BondModeActiveBackup Deserialize and serialize from/to `active-backup`. +// You can use integer 1 for deserializing to this mode. +const BondModeActiveBackup = BondMode("active-backup") + +// BondModeXor Deserialize and serialize from/to `balance-xor`. +// You can use integer 2 for deserializing to this mode. +const BondModeXor = BondMode("balance-xor") + +// BondModeBroadcast Deserialize and serialize from/to `broadcast`. +// You can use integer 3 for deserializing to this mode. +const BondModeBroadcast = BondMode("broadcast") + +// BondModeLacp Deserialize and serialize from/to `802.3ad`. +// You can use integer 4 for deserializing to this mode. +const BondModeLacp = BondMode("802.3ad") + +// BondModeTlb Deserialize and serialize from/to `balance-tlb`. +// You can use integer 5 for deserializing to this mode. +const BondModeTlb = BondMode("balance-tlb") + +// BondModeAlb Deserialize and serialize from/to `balance-alb`. +// You can use integer 6 for deserializing to this mode. +const BondModeAlb = BondMode("balance-alb") +const BondModeUnknown = BondMode("unknown") + +// enum BondMode + +// +k8s:deepcopy-gen=true +type BondConfig struct { + // Mode Mode is mandatory when create new bond interface. + Mode *BondMode `json:"mode,omitempty"` + // Options When applying, if defined, it will override current port list. + // The verification will not fail on bond options miss-match but an + // warning message. + // Please refer to [kernel documentation](https://www.kernel.org/doc/Documentation/networking/bonding.txt) for detail + Options *BondOptions `json:"options,omitempty"` + // Port Deserialize and serialize from/to `port`. + // You can also use `ports` for deserializing. + // When applying, if defined, it will override current port list. + Port *[]string `json:"port,omitempty"` + // PortsConfig Deserialize and serialize from/to `ports-config`. + // When applying, if defined, it will override current ports + // configuration. Note that `port` is not required to set with + // `ports-config`. An error will be raised during apply when the port + // names specified in `port` and `ports-config` conflict with each + // other. + PortsConfig *[]BondPortConfig `json:"ports-config,omitempty"` +} + +// BondAdSelect Specifies the 802.3ad aggregation selection logic to use. +// +kubebuilder:validation:Enum="stable";"0";"bandwidth";"1";"count";"2"; +type BondAdSelect string + +// BondAdSelectStable Deserialize and serialize from/to `stable`. +const BondAdSelectStable = BondAdSelect("stable") + +// BondAdSelectBandwidth Deserialize and serialize from/to `bandwidth`. +const BondAdSelectBandwidth = BondAdSelect("bandwidth") + +// BondAdSelectCount Deserialize and serialize from/to `count`. +const BondAdSelectCount = BondAdSelect("count") + +// enum BondAdSelect + +// BondLacpRate Option specifying the rate in which we'll ask our link partner to transmit +// LACPDU packets in 802.3ad mode +// +kubebuilder:validation:Enum="slow";"0";"fast";"1"; +type BondLacpRate string + +// BondLacpRateSlow Request partner to transmit LACPDUs every 30 seconds. +// Serialize to `slow`. +// Deserialize from 0 or `slow`. +const BondLacpRateSlow = BondLacpRate("slow") + +// BondLacpRateFast Request partner to transmit LACPDUs every 1 second +// Serialize to `fast`. +// Deserialize from 1 or `fast`. +const BondLacpRateFast = BondLacpRate("fast") + +// enum BondLacpRate + +// BondAllPortsActive Equal to kernel `all_slaves_active` option. +// Specifies that duplicate frames (received on inactive ports) should be +// dropped (0) or delivered (1). +// +kubebuilder:validation:Enum="dropped";"0";"delivered";"1"; +type BondAllPortsActive string + +// BondAllPortsActiveDropped Drop the duplicate frames +// Serialize to `dropped`. +// Deserialize from 0 or `dropped`. +const BondAllPortsActiveDropped = BondAllPortsActive("dropped") + +// BondAllPortsActiveDelivered Deliver the duplicate frames +// Serialize to `delivered`. +// Deserialize from 1 or `delivered`. +const BondAllPortsActiveDelivered = BondAllPortsActive("delivered") + +// enum BondAllPortsActive + +// BondArpAllTargets The `arp_all_targets` kernel bond option: Specifies the quantity of +// arp_ip_targets that must be reachable in order for the ARP monitor to +// consider a port as being up. This option affects only active-backup mode +// for ports with arp_validation enabled. +// +kubebuilder:validation:Enum="any";"0";"all";"1"; +type BondArpAllTargets string + +// BondArpAllTargetsAny consider the port up only when any of the `arp_ip_targets` is reachable +const BondArpAllTargetsAny = BondArpAllTargets("any") + +// BondArpAllTargetsAll consider the port up only when all of the `arp_ip_targets` are +// reachable +const BondArpAllTargetsAll = BondArpAllTargets("all") + +// enum BondArpAllTargets + +// BondArpValidate The `arp_validate` kernel bond option: Specifies whether or not ARP probes +// and replies should be validated in any mode that supports arp monitoring, or +// whether non-ARP traffic should be filtered (disregarded) for link monitoring +// purposes. +// +kubebuilder:validation:Enum="none";"0";"active";"1";"backup";"2";"all";"3";"filter";"4";"filter_active";"5";"filter_backup";"6"; +type BondArpValidate string + +// BondArpValidateNone No validation or filtering is performed. +// Serialize to `none`. +// Deserialize from 0 or `none`. +const BondArpValidateNone = BondArpValidate("none") + +// BondArpValidateActive Validation is performed only for the active port. +// Serialize to `active`. +// Deserialize from 1 or `active`. +const BondArpValidateActive = BondArpValidate("active") + +// BondArpValidateBackup Validation is performed only for backup ports. +// Serialize to `backup`. +// Deserialize from 2 or `backup`. +const BondArpValidateBackup = BondArpValidate("backup") + +// BondArpValidateAll Validation is performed for all ports. +// Serialize to `all`. +// Deserialize from 3 or `all`. +const BondArpValidateAll = BondArpValidate("all") + +// BondArpValidateFilter Filtering is applied to all ports. No validation is performed. +// Serialize to `filter`. +// Deserialize from 4 or `filter`. +const BondArpValidateFilter = BondArpValidate("filter") + +// BondArpValidateFilterActive Filtering is applied to all ports, validation is performed only for +// the active port. +// Serialize to `filter_active`. +// Deserialize from 5 or `filter-active`. +const BondArpValidateFilterActive = BondArpValidate("filter_active") + +// BondArpValidateFilterBackup Filtering is applied to all ports, validation is performed only for +// backup port. +// Serialize to `filter_backup`. +// Deserialize from 6 or `filter_backup`. +const BondArpValidateFilterBackup = BondArpValidate("filter_backup") + +// enum BondArpValidate + +// BondFailOverMac The `fail_over_mac` kernel bond option: Specifies whether active-backup mode +// should set all ports to the same MAC address at port attachment (the +// traditional behavior), or, when enabled, perform special handling of the +// bond's MAC address in accordance with the selected policy. +// +kubebuilder:validation:Enum="none";"0";"active";"1";"follow";"2"; +type BondFailOverMac string + +// BondFailOverMacNone This setting disables fail_over_mac, and causes bonding to set all +// ports of an active-backup bond to the same MAC address at attachment +// time. +// Serialize to `none`. +// Deserialize from 0 or `none`. +const BondFailOverMacNone = BondFailOverMac("none") + +// BondFailOverMacActive The "active" fail_over_mac policy indicates that the MAC address of the +// bond should always be the MAC address of the currently active port. +// The MAC address of the ports is not changed; instead, the MAC address +// of the bond changes during a failover. +// Serialize to `active`. +// Deserialize from 1 or `active`. +const BondFailOverMacActive = BondFailOverMac("active") + +// BondFailOverMacFollow The "follow" fail_over_mac policy causes the MAC address of the bond to +// be selected normally (normally the MAC address of the first port added +// to the bond). However, the second and subsequent ports are not set to +// this MAC address while they are in a backup role; a port is programmed +// with the bond's MAC address at failover time (and the formerly active +// port receives the newly active port's MAC address). +// Serialize to `follow`. +// Deserialize from 2 or `follow`. +const BondFailOverMacFollow = BondFailOverMac("follow") + +// enum BondFailOverMac + +// BondPrimaryReselect The `primary_reselect` kernel bond option: Specifies the reselection policy +// for the primary port. This affects how the primary port is chosen to +// become the active port when failure of the active port or recovery of the +// primary port occurs. This option is designed to prevent flip-flopping +// between the primary port and other ports. +// +kubebuilder:validation:Enum="always";"0";"better";"1";"failure";"2"; +type BondPrimaryReselect string + +// BondPrimaryReselectAlways The primary port becomes the active port whenever it comes back up. +// Serialize to `always`. +// Deserialize from 0 or `always`. +const BondPrimaryReselectAlways = BondPrimaryReselect("always") + +// BondPrimaryReselectBetter The primary port becomes the active port when it comes back up, if the +// speed and duplex of the primary port is better than the speed and +// duplex of the current active port. +// Serialize to `better`. +// Deserialize from 1 or `better`. +const BondPrimaryReselectBetter = BondPrimaryReselect("better") + +// BondPrimaryReselectFailure The primary port becomes the active port only if the current active +// port fails and the primary port is up. +// Serialize to `failure`. +// Deserialize from 2 or `failure`. +const BondPrimaryReselectFailure = BondPrimaryReselect("failure") + +// enum BondPrimaryReselect + +// BondXmitHashPolicy The `xmit_hash_policy` kernel bond option: Selects the transmit hash policy +// to use for port selection in balance-xor, 802.3ad, and tlb modes. +// +kubebuilder:validation:Enum="layer2";"0";"layer3+4";"1";"layer2+3";"2";"encap2+3";"3";"encap3+4";"4";"vlan+srcmac";"5"; +type BondXmitHashPolicy string + +// BondXmitHashPolicyLayer2 Serialize to `layer2`. +// Deserialize from 0 or `layer2`. +const BondXmitHashPolicyLayer2 = BondXmitHashPolicy("layer2") + +// BondXmitHashPolicyLayer34 Serialize to `layer3+4`. +// Deserialize from 1 or `layer3+4`. +const BondXmitHashPolicyLayer34 = BondXmitHashPolicy("layer3+4") + +// BondXmitHashPolicyLayer23 Serialize to `layer2+3`. +// Deserialize from 2 or `layer2+3`. +const BondXmitHashPolicyLayer23 = BondXmitHashPolicy("layer2+3") + +// BondXmitHashPolicyEncap23 Serialize to `encap2+3`. +// Deserialize from 3 or `encap2+3`. +const BondXmitHashPolicyEncap23 = BondXmitHashPolicy("encap2+3") + +// BondXmitHashPolicyEncap34 Serialize to `encap3+4`. +// Deserialize from 4 or `encap3+4`. +const BondXmitHashPolicyEncap34 = BondXmitHashPolicy("encap3+4") + +// BondXmitHashPolicyVlanSrcMac Serialize to `vlan+srcmac`. +// Deserialize from 5 or `vlan+srcmac`. +const BondXmitHashPolicyVlanSrcMac = BondXmitHashPolicy("vlan+srcmac") + +// enum BondXmitHashPolicy + +// +k8s:deepcopy-gen=true +type BondOptions struct { + // AdActorSysPrio In an AD system, this specifies the system priority. The allowed range + // is 1 - 65535. + AdActorSysPrio *intstr.IntOrString `json:"ad_actor_sys_prio,omitempty"` + // AdActorSystem In an AD system, this specifies the mac-address for the actor in + // protocol packet exchanges (LACPDUs). The value cannot be NULL or + // multicast. It is preferred to have the local-admin bit set for this mac + // but driver does not enforce it. If the value is not given then system + // defaults to using the controller's mac address as actors' system + // address. + AdActorSystem *string `json:"ad_actor_system,omitempty"` + // AdSelect Specifies the 802.3ad aggregation selection logic to use. The + // possible values and their effects are: + AdSelect *BondAdSelect `json:"ad_select,omitempty"` + // AdUserPortKey In an AD system, the port-key has three parts as shown below - + // + // ```text + // Bits Use + // 00 Duplex + // 01-05 Speed + // 06-15 User-defined + // ``` + // + // This defines the upper 10 bits of the port key. The values can be from + // 0 + // - 1023. If not given, the system defaults to 0. + // + // This parameter has effect only in 802.3ad mode. + AdUserPortKey *intstr.IntOrString `json:"ad_user_port_key,omitempty"` + // AllSlavesActive Specifies that duplicate frames (received on inactive ports) should be + // dropped (0) or delivered (1). + // + // Normally, bonding will drop duplicate frames (received on inactive + // ports), which is desirable for most users. But there are some times it + // is nice to allow duplicate frames to be delivered. + AllSlavesActive *BondAllPortsActive `json:"all_slaves_active,omitempty"` + // ArpAllTargets Specifies the quantity of arp_ip_targets that must be reachable in + // order for the ARP monitor to consider a port as being up. This + // option affects only active-backup mode for ports with + // arp_validation enabled. + ArpAllTargets *BondArpAllTargets `json:"arp_all_targets,omitempty"` + // ArpInterval Specifies the ARP link monitoring frequency in milliseconds. + // + // The ARP monitor works by periodically checking the port devices to + // determine whether they have sent or received traffic recently (the + // precise criteria depends upon the bonding mode, and the state of the + // port). Regular traffic is generated via ARP probes issued for the + // addresses specified by the arp_ip_target option. + // + // This behavior can be modified by the arp_validate option, + // below. + // + // If ARP monitoring is used in an etherchannel compatible mode (modes 0 + // and 2), the switch should be configured in a mode that evenly + // distributes packets across all links. If the switch is configured to + // distribute the packets in an XOR fashion, all replies from the ARP + // targets will be received on the same link which could cause the other + // team members to fail. ARP monitoring should not be used in conjunction + // with miimon. A value of 0 disables ARP monitoring. The default value + // is 0. + ArpInterval *intstr.IntOrString `json:"arp_interval,omitempty"` + // ArpIPTarget Specifies the IP addresses to use as ARP monitoring peers when + // arp_interval is > 0. These are the targets of the ARP request sent to + // determine the health of the link to the targets. Specify these values + // in ddd.ddd.ddd.ddd format. Multiple IP addresses must be separated by a + // comma. At least one IP address must be given for ARP monitoring to + // function. The maximum number of targets that can be specified is 16. + // The default value is no IP addresses. + ArpIPTarget *string `json:"arp_ip_target,omitempty"` + // ArpValidate Specifies whether or not ARP probes and replies should be validated in + // any mode that supports arp monitoring, or whether non-ARP traffic + // should be filtered (disregarded) for link monitoring purposes. + ArpValidate *BondArpValidate `json:"arp_validate,omitempty"` + // Downdelay Specifies the time, in milliseconds, to wait before disabling a port + // after a link failure has been detected. This option is only valid for + // the miimon link monitor. The downdelay value should be a multiple of + // the miimon value; if not, it will be rounded down to the nearest + // multiple. The default value is 0. + Downdelay *intstr.IntOrString `json:"downdelay,omitempty"` + // FailOverMac Specifies whether active-backup mode should set all ports to the same + // MAC address at enportment (the traditional behavior), or, when enabled, + // perform special handling of the bond's MAC address in accordance with + // the selected policy. + FailOverMac *BondFailOverMac `json:"fail_over_mac,omitempty"` + // LacpRate Option specifying the rate in which we'll ask our link partner to + // transmit LACPDU packets in 802.3ad mode. + LacpRate *BondLacpRate `json:"lacp_rate,omitempty"` + // LpInterval Specifies the number of seconds between instances where the bonding + // driver sends learning packets to each slaves peer switch. + // + // The valid range is 1 - 0x7fffffff; the default value is 1. This Option + // has effect only in balance-tlb and balance-alb modes. + LpInterval *intstr.IntOrString `json:"lp_interval,omitempty"` + // Miimon Specifies the MII link monitoring frequency in milliseconds. + // This determines how often the link state of each port is + // inspected for link failures. A value of zero disables MII + // link monitoring. A value of 100 is a good starting point. + // The use_carrier option, below, affects how the link state is + // determined. See the High Availability section for additional + // information. The default value is 0. + Miimon *intstr.IntOrString `json:"miimon,omitempty"` + // MinLinks Specifies the minimum number of links that must be active before + // asserting carrier. It is similar to the Cisco EtherChannel min-links + // feature. This allows setting the minimum number of member ports that + // must be up (link-up state) before marking the bond device as up + // (carrier on). This is useful for situations where higher level services + // such as clustering want to ensure a minimum number of low bandwidth + // links are active before switchover. This option only affect 802.3ad + // mode. + // + // The default value is 0. This will cause carrier to be asserted (for + // 802.3ad mode) whenever there is an active aggregator, regardless of the + // number of available links in that aggregator. Note that, because an + // aggregator cannot be active without at least one available link, + // setting this option to 0 or to 1 has the exact same effect. + MinLinks *intstr.IntOrString `json:"min_links,omitempty"` + // NumGratArp Specify the number of peer notifications (gratuitous ARPs and + // unsolicited IPv6 Neighbor Advertisements) to be issued after a + // failover event. As soon as the link is up on the new port + // (possibly immediately) a peer notification is sent on the + // bonding device and each VLAN sub-device. This is repeated at + // the rate specified by peer_notif_delay if the number is + // greater than 1. + // + // The valid range is 0 - 255; the default value is 1. These options + // affect only the active-backup mode. These options were added for + // bonding versions 3.3.0 and 3.4.0 respectively. + // + // From Linux 3.0 and bonding version 3.7.1, these notifications are + // generated by the ipv4 and ipv6 code and the numbers of repetitions + // cannot be set independently. + NumGratArp *intstr.IntOrString `json:"num_grat_arp,omitempty"` + // NumUnsolNa Identical to [BondOptions.num_grat_arp] + NumUnsolNa *intstr.IntOrString `json:"num_unsol_na,omitempty"` + // PacketsPerSlave Specify the number of packets to transmit through a port before moving + // to the next one. When set to 0 then a port is chosen at random. + // + // The valid range is 0 - 65535; the default value is 1. This option has + // effect only in balance-rr mode. + PacketsPerSlave *intstr.IntOrString `json:"packets_per_slave,omitempty"` + // Primary A string (eth0, eth2, etc) specifying which slave is the primary + // device. The specified device will always be the active slave while + // it is available. Only when the primary is off-line will alternate + // devices be used. This is useful when one slave is preferred over + // another, e.g., when one slave has higher throughput than another. + // + // The primary option is only valid for active-backup(1), balance-tlb (5) + // and balance-alb (6) mode. + Primary *string `json:"primary,omitempty"` + // PrimaryReselect Specifies the reselection policy for the primary port. This affects + // how the primary port is chosen to become the active port when failure + // of the active port or recovery of the primary port occurs. This + // option is designed to prevent flip-flopping between the primary port + // and other ports. + PrimaryReselect *BondPrimaryReselect `json:"primary_reselect,omitempty"` + // ResendIgmp Specifies the number of IGMP membership reports to be issued after + // a failover event. One membership report is issued immediately after + // the failover, subsequent packets are sent in each 200ms interval. + // + // The valid range is 0 - 255; the default value is 1. A value of 0 + // prevents the IGMP membership report from being issued in response + // to the failover event. + // + // This option is useful for bonding modes balance-rr (0), active-backup + // (1), balance-tlb (5) and balance-alb (6), in which a failover can + // switch the IGMP traffic from one port to another. Therefore a + // fresh IGMP report must be issued to cause the switch to forward the + // incoming IGMP traffic over the newly selected port. + ResendIgmp *intstr.IntOrString `json:"resend_igmp,omitempty"` + // TlbDynamicLb Specifies if dynamic shuffling of flows is enabled in tlb mode. The + // value has no effect on any other modes. + // + // The default behavior of tlb mode is to shuffle active flows across + // ports based on the load in that interval. This gives nice lb + // characteristics but can cause packet reordering. If re-ordering is a + // concern use this variable to disable flow shuffling and rely on load + // balancing provided solely by the hash distribution. xmit-hash-policy + // can be used to select the appropriate hashing for the setup. + // + // The sysfs entry can be used to change the setting per bond device and + // the initial value is derived from the module parameter. The sysfs entry + // is allowed to be changed only if the bond device is down. + // + // The default value is "1" that enables flow shuffling while value "0" + // disables it. This option was added in bonding driver 3.7.1 + TlbDynamicLb *bool `json:"tlb_dynamic_lb,omitempty"` + // Updelay Specifies the time, in milliseconds, to wait before enabling a port + // after a link recovery has been detected. This option is only valid for + // the miimon link monitor. The updelay value should be a multiple of the + // miimon value; if not, it will be rounded down to the nearest multiple. + // The default value is 0. + Updelay *intstr.IntOrString `json:"updelay,omitempty"` + // UseCarrier Specifies whether or not miimon should use MII or ETHTOOL + // ioctls vs. netif_carrier_ok() to determine the link + // status. The MII or ETHTOOL ioctls are less efficient and + // utilize a deprecated calling sequence within the kernel. The + // netif_carrier_ok() relies on the device driver to maintain its + // state with netif_carrier_on/off; at this writing, most, but + // not all, device drivers support this facility. + // + // If bonding insists that the link is up when it should not be, + // it may be that your network device driver does not support + // netif_carrier_on/off. The default state for netif_carrier is + // "carrier on," so if a driver does not support netif_carrier, + // it will appear as if the link is always up. In this case, + // setting use_carrier to 0 will cause bonding to revert to the + // MII / ETHTOOL ioctl method to determine the link state. + // + // A value of 1 enables the use of netif_carrier_ok(), a value of + // 0 will use the deprecated MII / ETHTOOL ioctls. The default + // value is 1. + UseCarrier *bool `json:"use_carrier,omitempty"` + // XmitHashPolicy Selects the transmit hash policy to use for slave selection in + // balance-xor, 802.3ad, and tlb modes. + XmitHashPolicy *BondXmitHashPolicy `json:"xmit_hash_policy,omitempty"` + BalanceSlb *bool `json:"balance_slb,omitempty"` + ArpMissedMax *intstr.IntOrString `json:"arp_missed_max,omitempty"` +} + +// +k8s:deepcopy-gen=true +type BondPortConfig struct { + // Name name is mandatory when specifying the ports configuration. + Name string `json:"name"` + // Priority Deserialize and serialize from/to `priority`. + // When applying, if defined, it will override the current bond port + // priority. The verification will fail if bonding mode is not + // active-backup(1) or balance-tlb (5) or balance-alb (6). + Priority *intstr.IntOrString `json:"priority,omitempty"` + // QueueID Deserialize and serialize from/to `queue-id`. + QueueID *intstr.IntOrString `json:"queue-id,omitempty"` +} + +// DummyInterface Dummy interface. Only contain information of [BaseInterface]. +// Example yaml outpuf of `[crate::NetworkState]` with dummy interface: +// ```yml +// interfaces: +// - name: dummy1 +// type: dummy +// state: up +// mac-address: BE:25:F0:6D:55:64 +// mtu: 1500 +// wait-ip: any +// ipv4: +// enabled: false +// ipv6: +// enabled: false +// accept-all-mac-addresses: false +// lldp: +// enabled: false +// ethtool: +// feature: +// tx-checksum-ip-generic: true +// tx-ipxip6-segmentation: true +// rx-gro: true +// tx-generic-segmentation: true +// tx-udp-segmentation: true +// tx-udp_tnl-csum-segmentation: true +// rx-udp-gro-forwarding: false +// tx-tcp-segmentation: true +// tx-sctp-segmentation: true +// tx-ipxip4-segmentation: true +// tx-nocache-copy: false +// tx-gre-csum-segmentation: true +// tx-udp_tnl-segmentation: true +// tx-tcp-mangleid-segmentation: true +// rx-gro-list: false +// tx-scatter-gather-fraglist: true +// tx-gre-segmentation: true +// tx-tcp-ecn-segmentation: true +// tx-gso-list: true +// highdma: true +// tx-tcp6-segmentation: true +// +// ``` +// +k8s:deepcopy-gen=true +type DummyInterface struct { +} + +// LinuxBridgeConfig Linux bridge specific configuration. +// +k8s:deepcopy-gen=true +type LinuxBridgeConfig struct { + // Options Linux bridge options. When applying, existing options will merged into + // desired. + Options *LinuxBridgeOptions `json:"options,omitempty"` + // Port Linux bridge ports. When applying, desired port list will __override__ + // current port list. + Port *[]LinuxBridgePortConfig `json:"port,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LinuxBridgePortConfig struct { + // StpHairpinMode Controls whether traffic may be send back out of the port on which it + // was received. + StpHairpinMode *bool `json:"stp-hairpin-mode,omitempty"` + // StpPathCost The STP path cost of the specified port. + StpPathCost *intstr.IntOrString `json:"stp-path-cost,omitempty"` + // StpPriority The STP port priority. The priority value is an unsigned 8-bit quantity + // (number between 0 and 255). This metric is used in the designated port + // an droot port selecā€ tion algorithms. + StpPriority *intstr.IntOrString `json:"stp-priority,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LinuxBridgeOptions struct { + GcTimer *uint64 `json:"gc-timer,omitempty"` + GroupAddr *string `json:"group-addr,omitempty"` + // GroupForwardMask Alias of [LinuxBridgeOptions.group_fwd_mask], not preferred, please + // use [LinuxBridgeOptions.group_fwd_mask] instead. + GroupForwardMask *intstr.IntOrString `json:"group-forward-mask,omitempty"` + GroupFwdMask *intstr.IntOrString `json:"group-fwd-mask,omitempty"` + HashMax *intstr.IntOrString `json:"hash-max,omitempty"` + HelloTimer *uint64 `json:"hello-timer,omitempty"` + MacAgeingTime *intstr.IntOrString `json:"mac-ageing-time,omitempty"` + MulticastLastMemberCount *intstr.IntOrString `json:"multicast-last-member-count,omitempty"` + MulticastLastMemberInterval *intstr.IntOrString `json:"multicast-last-member-interval,omitempty"` + MulticastMembershipInterval *intstr.IntOrString `json:"multicast-membership-interval,omitempty"` + MulticastQuerier *bool `json:"multicast-querier,omitempty"` + MulticastQuerierInterval *intstr.IntOrString `json:"multicast-querier-interval,omitempty"` + MulticastQueryInterval *intstr.IntOrString `json:"multicast-query-interval,omitempty"` + MulticastQueryResponseInterval *intstr.IntOrString `json:"multicast-query-response-interval,omitempty"` + MulticastQueryUseIfaddr *bool `json:"multicast-query-use-ifaddr,omitempty"` + MulticastRouter *LinuxBridgeMulticastRouterType `json:"multicast-router,omitempty"` + MulticastSnooping *bool `json:"multicast-snooping,omitempty"` + MulticastStartupQueryCount *intstr.IntOrString `json:"multicast-startup-query-count,omitempty"` + MulticastStartupQueryInterval *intstr.IntOrString `json:"multicast-startup-query-interval,omitempty"` + Stp *LinuxBridgeStpOptions `json:"stp,omitempty"` + VlanProtocol *VlanProtocol `json:"vlan-protocol,omitempty"` + VlanDefaultPvid *uint16 `json:"vlan-default-pvid,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LinuxBridgeStpOptions struct { + // Enabled If disabled during applying, the remaining STP options will be discard. + Enabled *bool `json:"enabled,omitempty"` + ForwardDelay *intstr.IntOrString `json:"forward-delay,omitempty"` + HelloTime *intstr.IntOrString `json:"hello-time,omitempty"` + MaxAge *intstr.IntOrString `json:"max-age,omitempty"` + Priority *intstr.IntOrString `json:"priority,omitempty"` +} + +// +kubebuilder:validation:XIntOrString +// +kubebuilder:validation:Enum=1;"auto";0;"disabled";2;"enabled"; +type LinuxBridgeMulticastRouterType intstr.IntOrString + +func (o LinuxBridgeMulticastRouterType) MarshalJSON() ([]byte, error) { + return intstr.IntOrString(o).MarshalJSON() +} + +func (o *LinuxBridgeMulticastRouterType) UnmarshalJSON(data []byte) error { + oi := intstr.IntOrString(*o) + if err := oi.UnmarshalJSON(data); err != nil { + return err + } + *o = LinuxBridgeMulticastRouterType(oi) + return nil +} + +var LinuxBridgeMulticastRouterTypeAuto = LinuxBridgeMulticastRouterType(intstr.FromString("auto")) +var LinuxBridgeMulticastRouterTypeDisabled = LinuxBridgeMulticastRouterType(intstr.FromString("disabled")) +var LinuxBridgeMulticastRouterTypeEnabled = LinuxBridgeMulticastRouterType(intstr.FromString("enabled")) + +// enum LinuxBridgeMulticastRouterType + +// BridgePortVlanConfig Bridge VLAN filtering configuration +// +k8s:deepcopy-gen=true +type BridgePortVlanConfig struct { + // EnableNative Enable native VLAN. + // Deserialize and serialize from/to `enable-native`. + EnableNative *bool `json:"enable-native,omitempty"` + // Mode Bridge VLAN filtering mode + Mode *BridgePortVlanMode `json:"mode,omitempty"` + // Tag VLAN Tag for native VLAN. + Tag *intstr.IntOrString `json:"tag,omitempty"` + // TrunkTags Trunk tags. + // Deserialize and serialize from/to `trunk-tags`. + TrunkTags *[]BridgePortTrunkTag `json:"trunk-tags,omitempty"` +} + +// +kubebuilder:validation:Enum="trunk";"access"; +type BridgePortVlanMode string + +// BridgePortVlanModeTrunk Trunk mode +const BridgePortVlanModeTrunk = BridgePortVlanMode("trunk") + +// BridgePortVlanModeAccess Access mode +const BridgePortVlanModeAccess = BridgePortVlanMode("access") + +// enum BridgePortVlanMode + +// +k8s:deepcopy-gen=true +type BridgePortTrunkTag struct { + // ID Single VLAN trunk ID + ID *uint16 `json:"id,omitempty"` + // IDRange VLAN trunk ID range + IDRange *BridgePortVlanRange `json:"id-range,omitempty"` +} + +// +k8s:deepcopy-gen=true +type BridgePortVlanRange struct { + // Min Minimum VLAN ID(included). + Min uint16 `json:"min"` + // Max Maximum VLAN ID(included). + Max uint16 `json:"max"` +} + +// +k8s:deepcopy-gen=true +type OVSBridgeConfig struct { + // AllowExtraPatchPorts Only validate for applying, when set to `true`, extra OVS patch ports + // will not fail the verification. Default is false. + // This property will not be persisted, every time you modify + // ports of specified OVS bridge, you need to explicitly define this + // property if not using default value. + // Deserialize from `allow-extra-patch-ports`. + AllowExtraPatchPorts *bool `json:"allow-extra-patch-ports,omitempty"` +} + +// +k8s:deepcopy-gen=true +type OVSBridgeOptions struct { + Stp *OVSBridgeStpOptions `json:"stp,omitempty"` + Rstp *bool `json:"rstp,omitempty"` + // McastSnoopingEnable Deserialize and serialize from/to `mcast-snooping-enable`. + McastSnoopingEnable *bool `json:"mcast-snooping-enable,omitempty"` + // FailMode Deserialize and serialize from/to `fail-mode`. + FailMode *string `json:"fail-mode,omitempty"` + // Datapath Set to `netdev` for DPDK. + // Deserialize and serialize from/to `datapath`. + Datapath *string `json:"datapath,omitempty"` +} + +// +k8s:deepcopy-gen=true +type OVSBridgePortConfig struct { + Bond *OVSBridgeBondConfig `json:"link-aggregation,omitempty"` +} + +// OVSInterface OpenvSwitch internal interface. Example yaml output of [crate::NetworkState] +// with an DPDK enabled OVS interface: +// ```yml +// --- +// interfaces: +// - name: ovs0 +// type: ovs-interface +// state: up +// dpdk: +// devargs: "0000:af:00.1" +// rx-queue: 100 +// - name: br0 +// type: ovs-bridge +// state: up +// bridge: +// options: +// datapath: "netdev" +// port: +// - name: ovs0 +// +// ovs-db: +// +// other_config: +// dpdk-init: "true" +// +// ``` +// +// The yaml example of OVS pathing: +// ```yml +// --- +// interfaces: +// - name: patch0 +// type: ovs-interface +// state: up +// patch: +// peer: patch1 +// - name: ovs-br0 +// type: ovs-bridge +// state: up +// bridge: +// port: +// - name: patch0 +// - name: patch1 +// type: ovs-interface +// state: up +// patch: +// peer: patch0 +// - name: ovs-br1 +// type: ovs-bridge +// state: up +// bridge: +// port: +// - name: patch1 +// +// ``` +// +k8s:deepcopy-gen=true +type OVSInterface struct { + Patch *OVSPatchConfig `json:"patch,omitempty"` + Dpdk *OVSDpdkConfig `json:"dpdk,omitempty"` +} + +// OVSBridgeBondConfig The example yaml output of OVS bond: +// ```yml +// --- +// interfaces: +// - name: eth1 +// type: ethernet +// state: up +// - name: eth2 +// type: ethernet +// state: up +// - name: br0 +// type: ovs-bridge +// state: up +// bridge: +// port: +// - name: veth1 +// - name: ovs0 +// - name: bond1 +// link-aggregation: +// mode: balance-slb +// port: +// - name: eth2 +// - name: eth1 +// +// ``` +// +k8s:deepcopy-gen=true +type OVSBridgeBondConfig struct { + Mode *OVSBridgeBondMode `json:"mode,omitempty"` + // Ports Serialize to 'port'. Deserialize from `port` or `ports`. + Ports *[]OVSBridgeBondPortConfig `json:"port,omitempty"` + // BondDowndelay Deserialize and serialize from/to `bond-downdelay`. + BondDowndelay *intstr.IntOrString `json:"bond-downdelay,omitempty"` + // BondUpdelay Deserialize and serialize from/to `bond-updelay`. + BondUpdelay *intstr.IntOrString `json:"bond-updelay,omitempty"` + // Ovsdb OpenvSwitch specific `other_config` for OVS bond. Please refer to + // manpage `ovs-vswitchd.conf.db(5)` for more detail. + // When setting to None, nmstate will try to preserve current + // `other_config`, otherwise, nmstate will override all `other_config` + // for specified OVS bond. + Ovsdb *OVSDBIfaceConfig `json:"ovs-db,omitempty"` +} + +// +k8s:deepcopy-gen=true +type OVSBridgeBondPortConfig struct { + Name string `json:"name"` +} + +// +kubebuilder:validation:Enum="active-backup";"balance-slb";"balance-tcp";"lacp"; +type OVSBridgeBondMode string + +// OVSBridgeBondModeActiveBackup Deserialize and serialize from/to `active-backup`. +const OVSBridgeBondModeActiveBackup = OVSBridgeBondMode("active-backup") + +// OVSBridgeBondModeBalanceSlb Deserialize and serialize from/to `balance-slb`. +const OVSBridgeBondModeBalanceSlb = OVSBridgeBondMode("balance-slb") + +// OVSBridgeBondModeBalanceTCP Deserialize and serialize from/to `balance-tcp`. +const OVSBridgeBondModeBalanceTCP = OVSBridgeBondMode("balance-tcp") + +// OVSBridgeBondModeLacp Deserialize and serialize from/to `lacp`. +const OVSBridgeBondModeLacp = OVSBridgeBondMode("lacp") + +// enum OVSBridgeBondMode + +// +k8s:deepcopy-gen=true +type OVSPatchConfig struct { + Peer string `json:"peer,omitempty"` +} + +// +k8s:deepcopy-gen=true +type OVSDpdkConfig struct { + Devargs string `json:"devargs"` + // RxQueue Deserialize and serialize from/to `rx-queue`. You may also use + // OVS terminology `n_rxq` for this property. + RxQueue *uint32 `json:"rx-queue,omitempty"` + // NRxqDesc Specifies the rx queue size (number rx descriptors) for dpdk ports. + // Must be power of 2 in the range of 1 to 4096. + // Setting to 0 means remove this setting from OVS database. + NRxqDesc *uint32 `json:"n_rxq_desc,omitempty"` + // NTxqDesc Specifies the tx queue size (number tx descriptors) for dpdk ports. + // Must be power of 2 in the range of 1 to 4096. + // Setting to 0 means remove this setting from OVS database. + NTxqDesc *uint32 `json:"n_txq_desc,omitempty"` +} + +// VlanInterface Linux kernel VLAN interface. The example yaml output of +// [crate::NetworkState] with a VLAN interface would be: +// ```yaml +// interfaces: +// - name: eth1.101 +// type: vlan +// state: up +// mac-address: BE:E8:17:8F:D2:70 +// mtu: 1500 +// max-mtu: 65535 +// wait-ip: any +// ipv4: +// enabled: false +// ipv6: +// enabled: false +// accept-all-mac-addresses: false +// vlan: +// base-iface: eth1 +// id: 101 +// +// ``` +// +k8s:deepcopy-gen=true +type VlanInterface struct { + Vlan *VlanConfig `json:"vlan,omitempty"` +} + +// +k8s:deepcopy-gen=true +type VlanConfig struct { + BaseIface string `json:"base-iface"` + ID uint16 `json:"id"` + // Protocol Could be `802.1q` or `802.1ad`. Default to `802.1q` if not defined. + Protocol *VlanProtocol `json:"protocol,omitempty"` + // RegistrationProtocol Could be `gvrp`, `mvrp` or `none`. Default to none if not defined. + RegistrationProtocol *VlanRegistrationProtocol `json:"registration-protocol,omitempty"` + // ReorderHeaders reordering of output packet headers + ReorderHeaders *bool `json:"reorder-headers,omitempty"` + // LooseBinding loose binding of the interface to its master device's operating state + LooseBinding *bool `json:"loose-binding,omitempty"` +} + +// +kubebuilder:validation:Enum="802.1q";"802.1ad"; +type VlanProtocol string + +// VlanProtocolIeee8021Q Deserialize and serialize from/to `802.1q`. +const VlanProtocolIeee8021Q = VlanProtocol("802.1q") + +// VlanProtocolIeee8021Ad Deserialize and serialize from/to `802.1ad`. +const VlanProtocolIeee8021Ad = VlanProtocol("802.1ad") + +// enum VlanProtocol + +// +kubebuilder:validation:Enum="gvrp";"mvrp";"none"; +type VlanRegistrationProtocol string + +// VlanRegistrationProtocolGvrp GARP VLAN Registration Protocol +const VlanRegistrationProtocolGvrp = VlanRegistrationProtocol("gvrp") + +// VlanRegistrationProtocolMvrp Multiple VLAN Registration Protocol +const VlanRegistrationProtocolMvrp = VlanRegistrationProtocol("mvrp") + +// VlanRegistrationProtocolNone No Registration Protocol +const VlanRegistrationProtocolNone = VlanRegistrationProtocol("none") + +// enum VlanRegistrationProtocol + +// VxlanInterface Linux kernel VxLAN interface. The example yaml output of +// [crate::NetworkState] with a VxLAN interface would be: +// ```yml +// interfaces: +// - name: eth1.102 +// type: vxlan +// state: up +// mac-address: 0E:00:95:53:19:55 +// mtu: 1450 +// min-mtu: 68 +// max-mtu: 65535 +// vxlan: +// base-iface: eth1 +// id: 102 +// remote: 239.1.1.1 +// destination-port: 1235 +// +// ``` +// +k8s:deepcopy-gen=true +type VxlanInterface struct { + Vxlan *VxlanConfig `json:"vxlan,omitempty"` +} + +// +k8s:deepcopy-gen=true +type VxlanConfig struct { + BaseIface string `json:"base-iface,omitempty"` + ID uint32 `json:"id"` + Learning *bool `json:"learning,omitempty"` + Local *string `json:"local,omitempty"` + Remote *string `json:"remote,omitempty"` + // DstPort Deserialize and serialize from/to `destination-port`. + DstPort *intstr.IntOrString `json:"destination-port,omitempty"` +} + +// MacVlanInterface Linux kernel MAC VLAN interface. The example yaml output of +// [crate::NetworkState] with a mac vlan interface would be: +// ```yaml +// --- +// interfaces: +// - name: mac0 +// type: mac-vlan +// state: up +// mac-vlan: +// base-iface: eth1 +// mode: vepa +// promiscuous: true +// +// ``` +// +k8s:deepcopy-gen=true +type MacVlanInterface struct { + // MacVlan Deserialize and serialize from/to `mac-vlan`. + MacVlan *MacVlanConfig `json:"mac-vlan,omitempty"` +} + +// +k8s:deepcopy-gen=true +type MacVlanConfig struct { + BaseIface string `json:"base-iface"` + Mode MacVlanMode `json:"mode"` + // AcceptAllMac Serialize to `promiscuous`. + // Deserialize from `promiscuous` or `accept-all-mac`. + AcceptAllMac *bool `json:"promiscuous,omitempty"` +} + +// +kubebuilder:validation:Enum="vepa";"bridge";"private";"passthru";"source";"unknown"; +type MacVlanMode string + +// MacVlanModeVepa Deserialize and serialize from/to `vepa`. +const MacVlanModeVepa = MacVlanMode("vepa") + +// MacVlanModeBridge Deserialize and serialize from/to `bridge`. +const MacVlanModeBridge = MacVlanMode("bridge") + +// MacVlanModePrivate Deserialize and serialize from/to `private`. +const MacVlanModePrivate = MacVlanMode("private") + +// MacVlanModePassthru Deserialize and serialize from/to `passthru`. +const MacVlanModePassthru = MacVlanMode("passthru") + +// MacVlanModeSource Deserialize and serialize from/to `source`. +const MacVlanModeSource = MacVlanMode("source") +const MacVlanModeUnknown = MacVlanMode("unknown") + +// enum MacVlanMode + +// MacVtapInterface Linux kernel MAC VTAP interface. The example output of [crate::NetworkState] +// with a mac vtap interface would be: +// ```yml +// --- +// interfaces: +// - name: mac0 +// type: mac-vtap +// state: up +// mac-vtap: +// base-iface: eth1 +// mode: passthru +// promiscuous: true +// +// ``` +// +k8s:deepcopy-gen=true +type MacVtapInterface struct { + // MacVtap Deserialize and serialize from/to `mac-vtap`. + MacVtap *MacVtapConfig `json:"mac-vtap,omitempty"` +} + +// +k8s:deepcopy-gen=true +type MacVtapConfig struct { + BaseIface string `json:"base-iface"` + Mode MacVtapMode `json:"mode"` + // AcceptAllMac Serialize to `promiscuous`. + // Deserialize from `promiscuous` or `accept-all-mac`. + AcceptAllMac *bool `json:"promiscuous,omitempty"` +} + +// +kubebuilder:validation:Enum="vepa";"bridge";"private";"passthru";"source";"unknown"; +type MacVtapMode string + +// MacVtapModeVepa Deserialize and serialize from/to `vepa`. +const MacVtapModeVepa = MacVtapMode("vepa") + +// MacVtapModeBridge Deserialize and serialize from/to `bridge`. +const MacVtapModeBridge = MacVtapMode("bridge") + +// MacVtapModePrivate Deserialize and serialize from/to `private`. +const MacVtapModePrivate = MacVtapMode("private") + +// MacVtapModePassthru Deserialize and serialize from/to `passthru`. +const MacVtapModePassthru = MacVtapMode("passthru") + +// MacVtapModeSource Deserialize and serialize from/to `source`. +const MacVtapModeSource = MacVtapMode("source") +const MacVtapModeUnknown = MacVtapMode("unknown") + +// enum MacVtapMode + +// VrfInterface Linux kernel Virtual Routing and Forwarding(VRF) interface. The example +// yaml output of a [crate::NetworkState] with a VRF interface would be: +// ```yml +// interfaces: +// - name: vrf0 +// type: vrf +// state: up +// mac-address: 42:6C:4A:0B:A3:C0 +// mtu: 65575 +// min-mtu: 1280 +// max-mtu: 65575 +// wait-ip: any +// ipv4: +// enabled: false +// ipv6: +// enabled: false +// accept-all-mac-addresses: false +// vrf: +// port: +// - eth1 +// - eth2 +// route-table-id: 100 +// +// ``` +// +k8s:deepcopy-gen=true +type VrfInterface struct { + Vrf *VrfConfig `json:"vrf,omitempty"` +} + +// +k8s:deepcopy-gen=true +type VrfConfig struct { + // Port Port list. + // Deserialize and serialize from/to `port`. + // Also deserialize from `ports`. + Port *[]string `json:"port"` + // TableID Route table ID of this VRF interface. + // Use 0 to preserve current `table_id`. + // Deserialize and serialize from/to `route-table-id`. + TableID uint32 `json:"route-table-id,omitempty"` +} + +// InfiniBandInterface IP over InfiniBand interface. The example yaml output of a +// [crate::NetworkState] with an infiniband interface would be: +// ```yaml +// --- +// interfaces: +// - name: ib2.8001 +// type: infiniband +// state: up +// mtu: 1280 +// infiniband: +// pkey: "0x8001" +// mode: "connected" +// base-iface: "ib2" +// +// ``` +// +k8s:deepcopy-gen=true +type InfiniBandInterface struct { + Ib *InfiniBandConfig `json:"infiniband,omitempty"` +} + +// +kubebuilder:validation:Enum="datagram";"connected"; +type InfiniBandMode string + +// InfiniBandModeDatagram Deserialize and serialize from/to `datagram`. +const InfiniBandModeDatagram = InfiniBandMode("datagram") + +// InfiniBandModeConnected Deserialize and serialize from/to `connected`. +const InfiniBandModeConnected = InfiniBandMode("connected") + +// enum InfiniBandMode + +// +k8s:deepcopy-gen=true +type InfiniBandConfig struct { + // Mode Mode of InfiniBand interface. + Mode InfiniBandMode `json:"mode"` + // BaseIface For pkey sub-interface only. Empty for base interface. + BaseIface *string `json:"base-iface,omitempty"` + // Pkey P-key of sub-interface. + // Serialize in hex string format(lower case). + // For base interface, it is set to None. + // The `0xffff` value also indicate this is a InfiniBand base interface. + Pkey *intstr.IntOrString `json:"pkey,omitempty"` +} + +// LoopbackInterface Loopback interface. Only contain information of [BaseInterface]. +// Limitations +// - Cannot enable DHCP or autoconf. +// - The [InterfaceState::Absent] can only restore the loopback configure back +// to default. +// - Ignore the request of disable IPv4 or IPv6. +// - Even not desired, the `127.0.0.1/8` and `::1` are always appended to +// static IP address list. +// - Require NetworkManager 1.41+ unless in kernel only mode. +// +// Example yaml outpuf of `[crate::NetworkState]` with loopback interface: +// ```yml +// interfaces: +// - name: lo +// type: loopback +// state: up +// mtu: 65535 +// ipv4: +// enabled: true +// address: +// - ip: 127.0.0.1 +// prefix-length: 8 +// ipv6: +// enabled: true +// address: +// - ip: ::1 +// prefix-length: 128 +// accept-all-mac-addresses: false +// +// ``` +// +k8s:deepcopy-gen=true +type LoopbackInterface struct { +} + +// SrIovConfig Single Root I/O Virtualization(SRIOV) configuration. The example yaml output +// of [crate::NetworkState] with SR-IOV enabled ethernet interface would be: +// ```yml +// interfaces: +// - name: ens1f1 +// type: ethernet +// state: up +// mac-address: 00:11:22:33:44:55 +// mtu: 1500 +// min-mtu: 68 +// max-mtu: 9702 +// ethernet: +// sr-iov: +// total-vfs: 2 +// vfs: +// - id: 0 +// mac-address: 00:11:22:33:00:ff +// spoof-check: true +// trust: false +// min-tx-rate: 0 +// max-tx-rate: 0 +// vlan-id: 0 +// qos: 0 +// - id: 1 +// mac-address: 00:11:22:33:00:ef +// spoof-check: true +// trust: false +// min-tx-rate: 0 +// max-tx-rate: 0 +// vlan-id: 0 +// qos: 0 +// +// ``` +// +k8s:deepcopy-gen=true +type SrIovConfig struct { + // TotalVfs The number of VFs enabled on PF. + // Deserialize and serialize from/to `total-vfs`. + TotalVfs *intstr.IntOrString `json:"total-vfs,omitempty"` + // Vfs VF specific configurations. + // * Setting to `Some(Vec::new())` will revert all VF configurations back + // to defaults. + // * If not empty, missing [SrIovVfConfig] will use current configuration. + Vfs *[]SrIovVfConfig `json:"vfs,omitempty"` +} + +// +k8s:deepcopy-gen=true +type SrIovVfConfig struct { + ID uint32 `json:"id"` + // IfaceName Interface name for this VF, only for querying, will be ignored + // when applying network state. + IfaceName string `json:"iface-name,omitempty"` + // MacAddress Deserialize and serialize from/to `mac-address`. + MacAddress *string `json:"mac-address,omitempty"` + // SpoofCheck Deserialize and serialize from/to `spoof-check`. + SpoofCheck *bool `json:"spoof-check,omitempty"` + Trust *bool `json:"trust,omitempty"` + // MinTxRate Deserialize and serialize from/to `min_tx_rate`. + MinTxRate *intstr.IntOrString `json:"min-tx-rate,omitempty"` + // MaxTxRate Deserialize and serialize from/to `max-tx-rate`. + MaxTxRate *intstr.IntOrString `json:"max-tx-rate,omitempty"` + // VlanID Deserialize and serialize from/to `vlan-id`. + VlanID *intstr.IntOrString `json:"vlan-id,omitempty"` + Qos *intstr.IntOrString `json:"qos,omitempty"` + VlanProto *VlanProtocol `json:"vlan-proto,omitempty"` +} + +// +k8s:deepcopy-gen=true +type EthtoolFeatureConfig struct { + Data map[string]bool `json:"data"` +} + +// EthtoolConfig The ethtool configurations. +// The yaml output of [crate::NetworkState] containing ethtool information of +// an ethernet interface would be: +// ```yml +// interfaces: +// - name: ens3 +// type: ethernet +// state: up +// ethtool: +// feature: +// tx-tcp-ecn-segmentation: true +// tx-tcp-mangleid-segmentation: false +// tx-tcp6-segmentation: true +// tx-tcp-segmentation: true +// rx-gro-list: false +// rx-udp-gro-forwarding: false +// rx-gro-hw: true +// tx-checksum-ip-generic: true +// tx-generic-segmentation: true +// rx-gro: true +// tx-nocache-copy: false +// coalesce: +// rx-frames: 1 +// tx-frames: 1 +// ring: +// rx: 256 +// rx-max: 256 +// tx: 256 +// tx-max: 256 +// +// ``` +// +k8s:deepcopy-gen=true +type EthtoolConfig struct { + // Pause The pause parameters of the specified Ethernet device. + Pause *EthtoolPauseConfig `json:"pause,omitempty"` + // Feature The protocol offload and other features of specified network device. + // Only changeable features are included when querying. + Feature map[string]bool `json:"feature,omitempty"` + // Coalesce The coalescing settings of the specified network device. + Coalesce *EthtoolCoalesceConfig `json:"coalesce,omitempty"` + // Ring The rx/tx ring parameters of the specified network device. + Ring *EthtoolRingConfig `json:"ring,omitempty"` +} + +// +k8s:deepcopy-gen=true +type EthtoolPauseConfig struct { + Rx *bool `json:"rx,omitempty"` + Tx *bool `json:"tx,omitempty"` + Autoneg *bool `json:"autoneg,omitempty"` +} + +// +k8s:deepcopy-gen=true +type EthtoolCoalesceConfig struct { + // AdaptiveRx Deserialize and serialize from/to `adaptive-rx`. + AdaptiveRx *bool `json:"adaptive-rx,omitempty"` + // AdaptiveTx Deserialize and serialize from/to `adaptive-tx`. + AdaptiveTx *bool `json:"adaptive-tx,omitempty"` + // PktRateHigh Deserialize and serialize from/to `pkt-rate-high`. + PktRateHigh *intstr.IntOrString `json:"pkt-rate-high,omitempty"` + // PktRateLow Deserialize and serialize from/to `pkt-rate-low`. + PktRateLow *intstr.IntOrString `json:"pkt-rate-low,omitempty"` + // RxFrames Deserialize and serialize from/to `rx-frames`. + RxFrames *intstr.IntOrString `json:"rx-frames,omitempty"` + // RxFramesHigh Deserialize and serialize from/to `rx-frames-high`. + RxFramesHigh *intstr.IntOrString `json:"rx-frames-high,omitempty"` + // RxFramesIrq Deserialize and serialize from/to `rx-frames-irq`. + RxFramesIrq *intstr.IntOrString `json:"rx-frames-irq,omitempty"` + // RxFramesLow Deserialize and serialize from/to `rx-frames-low`. + RxFramesLow *intstr.IntOrString `json:"rx-frames-low,omitempty"` + // RxUsecs Deserialize and serialize from/to `rx-usecs`. + RxUsecs *intstr.IntOrString `json:"rx-usecs,omitempty"` + // RxUsecsHigh Deserialize and serialize from/to `rx-usecs-high`. + RxUsecsHigh *intstr.IntOrString `json:"rx-usecs-high,omitempty"` + // RxUsecsIrq Deserialize and serialize from/to `rx-usecs-irq`. + RxUsecsIrq *intstr.IntOrString `json:"rx-usecs-irq,omitempty"` + // RxUsecsLow Deserialize and serialize from/to `rx-usecs-low`. + RxUsecsLow *intstr.IntOrString `json:"rx-usecs-low,omitempty"` + // SampleInterval Deserialize and serialize from/to `sample-interval`. + SampleInterval *intstr.IntOrString `json:"sample-interval,omitempty"` + // StatsBlockUsecs Deserialize and serialize from/to `stats-block-usecs`. + StatsBlockUsecs *intstr.IntOrString `json:"stats-block-usecs,omitempty"` + // TxFrames Deserialize and serialize from/to `tx-frames`. + TxFrames *intstr.IntOrString `json:"tx-frames,omitempty"` + // TxFramesHigh Deserialize and serialize from/to `tx-frames-high`. + TxFramesHigh *intstr.IntOrString `json:"tx-frames-high,omitempty"` + // TxFramesIrq Deserialize and serialize from/to `tx-frames-irq`. + TxFramesIrq *intstr.IntOrString `json:"tx-frames-irq,omitempty"` + // TxFramesLow Deserialize and serialize from/to `tx-frames-low`. + TxFramesLow *intstr.IntOrString `json:"tx-frames-low,omitempty"` + // TxUsecs Deserialize and serialize from/to `tx-usecs`. + TxUsecs *intstr.IntOrString `json:"tx-usecs,omitempty"` + // TxUsecsHigh Deserialize and serialize from/to `tx-usecs-high`. + TxUsecsHigh *intstr.IntOrString `json:"tx-usecs-high,omitempty"` + // TxUsecsIrq Deserialize and serialize from/to `tx-usecs-irq`. + TxUsecsIrq *intstr.IntOrString `json:"tx-usecs-irq,omitempty"` + // TxUsecsLow Deserialize and serialize from/to `tx-usecs-low`. + TxUsecsLow *intstr.IntOrString `json:"tx-usecs-low,omitempty"` +} + +// +k8s:deepcopy-gen=true +type EthtoolRingConfig struct { + Rx *intstr.IntOrString `json:"rx,omitempty"` + // RxMax Deserialize and serialize from/to `rx-max`. + RxMax *intstr.IntOrString `json:"rx-max,omitempty"` + // RxJumbo Deserialize and serialize from/to `rx-jumbo`. + RxJumbo *intstr.IntOrString `json:"rx-jumbo,omitempty"` + // RxJumboMax Deserialize and serialize from/to `rx-jumbo-max`. + RxJumboMax *intstr.IntOrString `json:"rx-jumbo-max,omitempty"` + // RxMini Deserialize and serialize from/to `rx-mini`. + RxMini *intstr.IntOrString `json:"rx-mini,omitempty"` + // RxMiniMax Deserialize and serialize from/to `rx-mini-max`. + RxMiniMax *intstr.IntOrString `json:"rx-mini-max,omitempty"` + Tx *intstr.IntOrString `json:"tx,omitempty"` + // TxMax Deserialize and serialize from/to `tx-max`. + TxMax *intstr.IntOrString `json:"tx-max,omitempty"` +} + +// BaseInterface Information shared among all interface types +// +k8s:deepcopy-gen=true +type BaseInterface struct { + // Name Interface name, when applying with `InterfaceIdentifier::MacAddress`, + // if `profile_name` not defined, this will be used as profile name. + Name string `json:"name"` + ProfileName *string `json:"profile-name,omitempty"` + // Description Interface description stored in network backend. Not available for + // kernel only mode. + Description *string `json:"description,omitempty"` + // Type Interface type. Serialize and deserialize to/from `type` + Type InterfaceType `json:"type,omitempty"` + // Driver The driver of the specified network device. + Driver *string `json:"driver,omitempty"` + // State Interface state. Default to [InterfaceState::Up] when applying. + State InterfaceState `json:"state,omitempty"` + // Identifier Define network backend matching method on choosing network interface. + // Default to [InterfaceIdentifier::Name]. + Identifier *InterfaceIdentifier `json:"identifier,omitempty"` + // MacAddress When applying with `[InterfaceIdentifier::MacAddress]`, + // nmstate will store original desired interface name as `profile_name` + // here and store the real interface name as `name` property. + // For [InterfaceIdentifier::Name] (default), this property will change + // the interface MAC address to desired one when applying. + // For [InterfaceIdentifier::MacAddress], this property will be used + // for searching interface on desired MAC address when applying. + // MAC address in the format: upper case hex string separated by `:` on + // every two characters. Case insensitive when applying. + // Serialize and deserialize to/from `mac-address`. + MacAddress *string `json:"mac-address,omitempty"` + // Mtu Maximum transmission unit. + Mtu *intstr.IntOrString `json:"mtu,omitempty"` + // MinMtu Minimum MTU allowed. Ignored during apply. + // Serialize and deserialize to/from `min-mtu`. + MinMtu *uint64 `json:"min-mtu,omitempty"` + // MaxMtu Maximum MTU allowed. Ignored during apply. + // Serialize and deserialize to/from `max-mtu`. + MaxMtu *uint64 `json:"max-mtu,omitempty"` + // WaitIP Whether system should wait certain IP stack before considering + // network interface activated. + // Serialize and deserialize to/from `wait-ip`. + WaitIP *WaitIP `json:"wait-ip,omitempty"` + // Ipv4 IPv4 information. + // Hided if interface is not allowed to hold IP information(e.g. port of + // bond is not allowed to hold IP information). + Ipv4 *InterfaceIP `json:"ipv4,omitempty"` + // Ipv6 IPv4 information. + // Hided if interface is not allowed to hold IP information(e.g. port of + // bond is not allowed to hold IP information). + Ipv6 *InterfaceIP `json:"ipv6,omitempty"` + // Mptcp Interface wide MPTCP flags. + // Nmstate will apply these flags to all valid IP addresses(both static + // and dynamic). + Mptcp *MptcpConfig `json:"mptcp,omitempty"` + // Controller Controller of the specified interface. + // Only valid for applying, `None` means no change, empty string means + // detach from current controller, please be advise, an error will trigger + // if this property conflict with ports list of bridge/bond/etc. + // Been always set to `None` by [crate::NetworkState::retrieve()]. + Controller *string `json:"controller,omitempty"` + // AcceptAllMacAddresses Whether kernel should skip check on package targeting MAC address and + // accept all packages, also known as promiscuous mode. + // Serialize and deserialize to/from `accpet-all-mac-addresses`. + AcceptAllMacAddresses *bool `json:"accept-all-mac-addresses,omitempty"` + // CopyMacFrom Copy the MAC address from specified interface. + // Ignored during serializing. + // Deserialize from `copy-mac-from`. + CopyMacFrom *string `json:"copy-mac-from,omitempty"` + // Ovsdb Interface specific OpenvSwitch database configurations. + Ovsdb *OVSDBIfaceConfig `json:"ovs-db,omitempty"` + // Ieee8021X IEEE 802.1X authentication configurations. + // Serialize and deserialize to/from `802.1x`. + Ieee8021X *Ieee8021XConfig `json:"802.1x,omitempty"` + // Lldp Link Layer Discovery Protocol configurations. + Lldp *LldpConfig `json:"lldp,omitempty"` + // Ethtool Ethtool configurations + Ethtool *EthtoolConfig `json:"ethtool,omitempty"` + // Dispatch Dispatch script configurations + Dispatch *DispatchConfig `json:"dispatch,omitempty"` +} + +// EthernetInterface Ethernet(IEEE 802.3) interface. +// Besides [BaseInterface], optionally could hold [EthernetConfig] and/or +// [VethConfig]. +// The yaml output of [crate::NetworkState] containing ethernet interface would +// be: +// ```yml +// interfaces: +// - name: ens3 +// type: ethernet +// state: up +// mac-address: 00:11:22:33:44:FF +// mtu: 1500 +// min-mtu: 68 +// max-mtu: 65535 +// wait-ip: ipv4 +// ipv4: +// enabled: true +// dhcp: false +// address: +// - ip: 192.0.2.9 +// prefix-length: 24 +// ipv6: +// enabled: false +// mptcp: +// address-flags: [] +// accept-all-mac-addresses: false +// lldp: +// enabled: false +// ethtool: +// feature: +// tx-tcp-ecn-segmentation: true +// tx-tcp-mangleid-segmentation: false +// tx-tcp6-segmentation: true +// tx-tcp-segmentation: true +// rx-gro-list: false +// rx-udp-gro-forwarding: false +// rx-gro-hw: true +// tx-checksum-ip-generic: true +// tx-generic-segmentation: true +// rx-gro: true +// tx-nocache-copy: false +// coalesce: +// rx-frames: 1 +// tx-frames: 1 +// ring: +// rx: 256 +// rx-max: 256 +// tx: 256 +// tx-max: 256 +// ethernet: +// auto-negotiation: false +// +// ``` +// +k8s:deepcopy-gen=true +type EthernetInterface struct { + Ethernet *EthernetConfig `json:"ethernet,omitempty"` + // Veth When applying, the [VethConfig] is only valid when + // [BaseInterface.iface_type] is set to [InterfaceType::Veth] explicitly. + Veth *VethConfig `json:"veth,omitempty"` +} + +// +kubebuilder:validation:Enum="full";"half"; +type EthernetDuplex string + +// EthernetDuplexFull Deserialize and serialize from/to `full`. +const EthernetDuplexFull = EthernetDuplex("full") + +// EthernetDuplexHalf Deserialize and serialize from/to `half`. +const EthernetDuplexHalf = EthernetDuplex("half") + +// enum EthernetDuplex + +// +k8s:deepcopy-gen=true +type EthernetConfig struct { + // SrIov Single Root I/O Virtualization(SRIOV) configuration. + // Deserialize and serialize from/to `sr-iov`. + SrIov *SrIovConfig `json:"sr-iov,omitempty"` + // AutoNeg Deserialize and serialize from/to `auto-negotiation`. + AutoNeg *bool `json:"auto-negotiation,omitempty"` + Speed *intstr.IntOrString `json:"speed,omitempty"` + Duplex *EthernetDuplex `json:"duplex,omitempty"` +} + +// +k8s:deepcopy-gen=true +type VethConfig struct { + // Peer The name of veth peer. + Peer string `json:"peer,omitempty"` +} + +// MacSecInterface MACsec interface. The example YAML output of a +// [crate::NetworkState] with an MACsec interface would be: +// ```yaml +// --- +// interfaces: +// - name: macsec0 +// type: macsec +// state: up +// macsec: +// encrypt: true +// base-iface: eth1 +// mka-cak: 50b71a8ef0bd5751ea76de6d6c98c03a +// mka-ckn: f2b4297d39da7330910a74abc0449feb45b5c0b9fc23df1430e1898fcf1c4550 +// port: 0 +// validation: strict +// send-sci: true +// +// ``` +// +k8s:deepcopy-gen=true +type MacSecInterface struct { + // Macsec Deserialize and serialize to `macsec`. + Macsec *MacSecConfig `json:"macsec,omitempty"` +} + +// +k8s:deepcopy-gen=true +type MacSecConfig struct { + // Encrypt Wether the transmitted traffic must be encrypted. + Encrypt bool `json:"encrypt"` + // BaseIface The parent interface used by the MACsec interface. + BaseIface string `json:"base-iface"` + // MkaCak The pre-shared CAK (Connectivity Association Key) for MACsec Key + // Agreement. Must be a string of 32 hexadecimal characters. + MkaCak *string `json:"mka-cak,omitempty"` + // MkaCkn The pre-shared CKN (Connectivity-association Key Name) for MACsec Key + // Agreement. Must be a string of hexadecimal characters with a even + // length between 2 and 64. + MkaCkn *string `json:"mka-ckn,omitempty"` + // Port The port component of the SCI (Secure Channel Identifier), between 1 + // and 65534. + Port uint32 `json:"port"` + // Validation Specifies the validation mode for incoming frames. + Validation MacSecValidate `json:"validation"` + // SendSci Specifies whether the SCI (Secure Channel Identifier) is included in + // every packet. + SendSci bool `json:"send-sci"` + Offload *MacSecOffload `json:"offload,omitempty"` +} + +// +kubebuilder:validation:Enum="disabled";"check";"strict"; +type MacSecValidate string + +const MacSecValidateDisabled = MacSecValidate("disabled") +const MacSecValidateCheck = MacSecValidate("check") +const MacSecValidateStrict = MacSecValidate("strict") + +// enum MacSecValidate + +// +kubebuilder:validation:Enum="off";"phy";"mac"; +type MacSecOffload string + +const MacSecOffloadOff = MacSecOffload("off") +const MacSecOffloadPhy = MacSecOffload("phy") +const MacSecOffloadMac = MacSecOffload("mac") + +// enum MacSecOffload + +// IpsecInterface The libreswan Ipsec interface. This interface does not exist in kernel +// space but only exist in user space tools. +// This is the example yaml output of [crate::NetworkState] with a libreswan +// ipsec connection: +// ```yaml +// --- +// interfaces: +// - name: hosta_conn +// type: ipsec +// ipv4: +// enabled: true +// dhcp: true +// libreswan: +// right: 192.0.2.252 +// rightid: '@hostb.example.org' +// left: 192.0.2.251 +// leftid: '%fromcert' +// leftcert: hosta.example.org +// ikev2: insist +// +// ``` +// +k8s:deepcopy-gen=true +type IpsecInterface struct { + Libreswan *LibreswanConfig `json:"libreswan,omitempty"` +} + +// +k8s:deepcopy-gen=true +type LibreswanConfig struct { + Right string `json:"right"` + Rightid *string `json:"rightid,omitempty"` + Rightrsasigkey *string `json:"rightrsasigkey,omitempty"` + Left *string `json:"left,omitempty"` + Leftid *string `json:"leftid,omitempty"` + Leftrsasigkey *string `json:"leftrsasigkey,omitempty"` + Leftcert *string `json:"leftcert,omitempty"` + Ikev2 *string `json:"ikev2,omitempty"` + // Psk PSK authentication, if not defined, will use X.509 PKI authentication + Psk *string `json:"psk,omitempty"` + Ikelifetime *string `json:"ikelifetime,omitempty"` + Salifetime *string `json:"salifetime,omitempty"` + Ike *string `json:"ike,omitempty"` + Esp *string `json:"esp,omitempty"` + Dpddelay *intstr.IntOrString `json:"dpddelay,omitempty"` + Dpdtimeout *intstr.IntOrString `json:"dpdtimeout,omitempty"` + Dpdaction *string `json:"dpdaction,omitempty"` + IpsecInterface *intstr.IntOrString `json:"ipsec-interface,omitempty"` + Authby *string `json:"authby,omitempty"` + Rightsubnet *string `json:"rightsubnet,omitempty"` + Leftmodecfgclient *bool `json:"leftmodecfgclient,omitempty"` + Kind *LibreswanConnectionType `json:"type,omitempty"` + Hostaddrfamily *LibreswanAddressFamily `json:"hostaddrfamily,omitempty"` + Clientaddrfamily *LibreswanAddressFamily `json:"clientaddrfamily,omitempty"` +} + +// +kubebuilder:validation:Enum="tunnel";"transport"; +type LibreswanConnectionType string + +const LibreswanConnectionTypeTunnel = LibreswanConnectionType("tunnel") +const LibreswanConnectionTypeTransport = LibreswanConnectionType("transport") + +// enum LibreswanConnectionType + +// +kubebuilder:validation:Enum="ipv4";"ipv6"; +type LibreswanAddressFamily string + +const LibreswanAddressFamilyIpv4 = LibreswanAddressFamily("ipv4") +const LibreswanAddressFamilyIpv6 = LibreswanAddressFamily("ipv6") + +// enum LibreswanAddressFamily + +// HsrInterface HSR interface. The example YAML output of a +// [crate::NetworkState] with an HSR interface would be: +// ```yaml +// --- +// interfaces: +// - name: hsr0 +// type: hsr +// state: up +// hsr: +// port1: eth1 +// port2: eth2 +// multicast-spec: 40 +// protocol: prp +// +// ``` +// +k8s:deepcopy-gen=true +type HsrInterface struct { + // Hsr Deserialize and serialize to `hsr`. + Hsr *HsrConfig `json:"hsr,omitempty"` +} + +// +k8s:deepcopy-gen=true +type HsrConfig struct { + // Port1 The port1 interface name. + Port1 string `json:"port1"` + // Port2 The port2 interface name. + Port2 string `json:"port2"` + // SupervisionAddress The MAC address used for the supervision frames. This property is + // read-only. + SupervisionAddress *string `json:"supervision-address,omitempty"` + // MulticastSpec The last byte of the supervision address. + MulticastSpec uint8 `json:"multicast-spec"` + // Protocol Protocol to be used. + Protocol HsrProtocol `json:"protocol"` +} + +// +kubebuilder:validation:Enum="hsr";"prp"; +type HsrProtocol string + +const HsrProtocolHsr = HsrProtocol("hsr") +const HsrProtocolPrp = HsrProtocol("prp") + +// enum HsrProtocol + +// NetworkState The [NetworkState] represents the whole network state including both +// kernel status and configurations provides by backends(NetworkManager, +// OpenvSwitch databas, and etc). +// +// Example yaml(many lines omitted) serialized NetworkState would be: +// +// ```yaml +// hostname: +// +// running: host.example.org +// config: host.example.org +// +// dns-resolver: +// +// config: +// server: +// - 2001:db8:1:: +// - 192.0.2.1 +// search: [] +// +// route-rules: +// +// config: +// - ip-from: 2001:db8:b::/64 +// priority: 30000 +// route-table: 200 +// - ip-from: 192.0.2.2/32 +// priority: 30000 +// route-table: 200 +// +// routes: +// +// config: +// - destination: 2001:db8:a::/64 +// next-hop-interface: eth1 +// next-hop-address: 2001:db8:1::2 +// metric: 108 +// table-id: 200 +// - destination: 192.168.2.0/24 +// next-hop-interface: eth1 +// next-hop-address: 192.168.1.3 +// metric: 108 +// table-id: 200 +// +// interfaces: +// - name: eth1 +// type: ethernet +// state: up +// mac-address: 0E:F9:2B:28:42:D9 +// mtu: 1500 +// ipv4: +// enabled: true +// dhcp: false +// address: +// - ip: 192.168.1.3 +// prefix-length: 24 +// ipv6: +// enabled: true +// dhcp: false +// autoconf: false +// address: +// - ip: 2001:db8:1::1 +// prefix-length: 64 +// +// ovs-db: +// +// external_ids: +// hostname: host.example.org +// rundir: /var/run/openvswitch +// system-id: 176866c7-6dc8-400f-98ac-c658509ec09f +// other_config: {} +// +// ``` +// +k8s:deepcopy-gen=true +type NetworkState struct { + // Hostname Hostname of current host. + Hostname *HostNameState `json:"hostname,omitempty"` + // DNS DNS resolver status, deserialize and serialize from/to `dns-resolver`. + DNS *DNSState `json:"dns-resolver,omitempty"` + // Rules Route rule, deserialize and serialize from/to `route-rules`. + Rules *RouteRules `json:"route-rules,omitempty"` + // Routes Route + Routes *Routes `json:"routes,omitempty"` + // Interfaces Network interfaces + Interfaces []Interface `json:"interfaces,omitempty"` + // Ovsdb The global configurations of OpenvSwitach daemon + Ovsdb *OVSDBGlobalConfig `json:"ovs-db,omitempty"` + // OVN The OVN configuration in the system + OVN *OVNConfiguration `json:"ovn,omitempty"` +} + +// OVNConfiguration Global OVN bridge mapping configuration. Example yaml output of +// [crate::NetworkState]: +// ```yml +// --- +// ovn: +// +// bridge-mappings: +// - localnet: tenantblue +// bridge: ovsbr1 +// state: present +// - localnet: tenantred +// bridge: ovsbr1 +// state: absent +// +// ``` +// +k8s:deepcopy-gen=true +type OVNConfiguration struct { + BridgeMappings *[]OVNBridgeMapping `json:"bridge-mappings,omitempty"` +} + +// +k8s:deepcopy-gen=true +type OVNBridgeMapping struct { + Localnet string `json:"localnet"` + // State When set to `state: absent`, will delete the existing + // `localnet` mapping. + State *OVNBridgeMappingState `json:"state,omitempty"` + Bridge *string `json:"bridge,omitempty"` +} + +// +kubebuilder:validation:Enum="present";"absent"; +type OVNBridgeMappingState string + +const OVNBridgeMappingStatePresent = OVNBridgeMappingState("present") +const OVNBridgeMappingStateAbsent = OVNBridgeMappingState("absent") + +// enum OVNBridgeMappingState + +// +k8s:deepcopy-gen=true +type DispatchConfig struct { + // PostActivation Dispatch bash script content to be invoked after interface activation + // finished by network backend. Nmstate will append additional lines + // to make sure this script is only invoked for specified interface when + // backend interface activation finished. + // Setting to empty string will remove the dispatch script + PostActivation *string `json:"post-activation,omitempty"` + // PostDeactivation Dispatch bash script content to be invoked after interface deactivation + // finished by network backend. Nmstate will append additional lines + // to make sure this script is only invoked for specified interface when + // backend interface deactivation finished. + // Setting to empty string will remove the dispatch script + PostDeactivation *string `json:"post-deactivation,omitempty"` +} + +// +k8s:deepcopy-gen=true +type OVSBridgeStpOptions struct { + Enabled *bool `json:"enabled,omitempty"` +} + +// +k8s:deepcopy-gen=true +type BridgePortConfigMetaData struct { + Name string `json:"name"` + Vlan *BridgePortVlanConfig `json:"vlan,omitempty"` +} + +// +k8s:deepcopy-gen=true +type BridgePortConfig struct { + BridgePortConfigMetaData `json:""` + *OVSBridgePortConfig `json:",omitempty"` + *LinuxBridgePortConfig `json:",omitempty"` +} + +// +k8s:deepcopy-gen=true +type BridgeOptions struct { + *LinuxBridgeOptions `json:",omitempty"` + *OVSBridgeOptions `json:",omitempty"` +} + +// BridgeConfig Linux or OVS bridge configuration +// +// Linux bridge: Bridge interface provided by linux kernel. +// When serializing or deserializing, the [BaseInterface] will +// be flatted and [LinuxBridgeConfig] stored as `bridge` section. The yaml +// output [crate::NetworkState] containing an example linux bridge interface: +// ```yml +// interfaces: +// - name: br0 +// type: linux-bridge +// state: up +// mac-address: 9A:91:53:6C:67:DA +// mtu: 1500 +// min-mtu: 68 +// max-mtu: 65535 +// wait-ip: any +// ipv4: +// enabled: false +// ipv6: +// enabled: false +// bridge: +// options: +// gc-timer: 29594 +// group-addr: 01:80:C2:00:00:00 +// group-forward-mask: 0 +// group-fwd-mask: 0 +// hash-max: 4096 +// hello-timer: 46 +// mac-ageing-time: 300 +// multicast-last-member-count: 2 +// multicast-last-member-interval: 100 +// multicast-membership-interval: 26000 +// multicast-querier: false +// multicast-querier-interval: 25500 +// multicast-query-interval: 12500 +// multicast-query-response-interval: 1000 +// multicast-query-use-ifaddr: false +// multicast-router: auto +// multicast-snooping: true +// multicast-startup-query-count: 2 +// multicast-startup-query-interval: 3125 +// stp: +// enabled: true +// forward-delay: 15 +// hello-time: 2 +// max-age: 20 +// priority: 32768 +// vlan-protocol: 802.1q +// port: +// - name: eth1 +// stp-hairpin-mode: false +// stp-path-cost: 100 +// stp-priority: 32 +// - name: eth2 +// stp-hairpin-mode: false +// stp-path-cost: 100 +// stp-priority: 32 +// +// ``` +// +// OVS bridge: OpenvSwitch bridge interface. Example yaml output of [crate::NetworkState] +// with an OVS bridge: +// ```yaml +// --- +// interfaces: +// - name: br0 +// type: ovs-interface +// state: up +// ipv4: +// address: +// - ip: 192.0.2.252 +// prefix-length: 24 +// - ip: 192.0.2.251 +// prefix-length: 24 +// dhcp: false +// enabled: true +// ipv6: +// address: +// - ip: 2001:db8:2::1 +// prefix-length: 64 +// - ip: 2001:db8:1::1 +// prefix-length: 64 +// autoconf: false +// dhcp: false +// enabled: true +// - name: br0 +// type: ovs-bridge +// state: up +// bridge: +// port: +// - name: br0 +// - name: eth1 +// +// ``` +// +k8s:deepcopy-gen=true +type BridgeConfig struct { + *OVSBridgeConfig `json:",omitempty"` + Options *BridgeOptions `json:"options,omitempty"` + Ports *[]BridgePortConfig `json:"port,omitempty"` +} + +// +k8s:deepcopy-gen=true +type BridgeInterface struct { + *BridgeConfig `json:"bridge,omitempty"` +}