Skip to content

Commit

Permalink
go, api: Create a structure API
Browse files Browse the repository at this point in the history
At some scenarios is useful to have a "structured" version of the
network_state, this change creates a golang api tested toward examples
and stated used at integration tests it also add the kubebuilder tags to
be k8s CRD friendly.

Signed-off-by: Enrique Llorente <ellorent@redhat.com>
  • Loading branch information
qinqon committed Jul 5, 2023
1 parent 0c6baf8 commit 432fca0
Show file tree
Hide file tree
Showing 23 changed files with 3,980 additions and 7 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ doc/nmstate-autoconf.8

nmstate-*.tar.gz
nmstate-*.tar.gz.asc

.states
13 changes: 11 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -216,8 +216,13 @@ clib_check: $(CLIB_SO_DEV_DEBUG) $(CLIB_HEADER)
$(TMPDIR)/nmpolicy_yaml_test 1>/dev/null
rm -rf $(TMPDIR)

.PHONY: go_generate
go_generate:
cd rust/src/go/nmstate; go generate
cd rust/src/go/api; go generate

.PHONY: go_check
go_check: $(CLIB_SO_DEV_DEBUG) $(CLIB_HEADER)
go_check: $(CLIB_SO_DEV_DEBUG) $(CLIB_HEADER) go_generate
$(eval TMPDIR := $(shell mktemp -d))
cp $(CLIB_SO_DEV_DEBUG) $(TMPDIR)/$(CLIB_SO_FULL)
ln -sfv $(CLIB_SO_FULL) $(TMPDIR)/$(CLIB_SO_MAN)
Expand All @@ -226,9 +231,13 @@ go_check: $(CLIB_SO_DEV_DEBUG) $(CLIB_HEADER)
cd rust/src/go/nmstate; LD_LIBRARY_PATH=$(TMPDIR) \
CGO_CFLAGS="-I$(TMPDIR)" \
CGO_LDFLAGS="-L$(TMPDIR)" \
go test $(WHAT)
go test -v $(WHAT)
rm -rf $(TMPDIR)

.PHONY: go_api_check
go_api_check: go_generate
cd rust/src/go/api && go test -v

rust_check:
cd rust; cargo test -- --test-threads=1 --show-output;
if [ "CHK$(CI)" != "CHKtrue" ]; then \
Expand Down
6 changes: 5 additions & 1 deletion automation/run-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ PYTEST_OPTIONS="--verbose --verbose \

NMSTATE_TEMPDIR=$(mktemp -d /tmp/nmstate-test-XXXX)

: ${CONTAINER_CMD:=podman}
: ${CONTAINER_CMD:=docker}
: ${KUBECTL_CMD:=k8s/kubectl.sh}

test -t 1 && USE_TTY="-t"
Expand Down Expand Up @@ -99,6 +99,7 @@ function run_tests {
--junitxml=junit.integ.xml \
tests/integration \
${nmstate_pytest_extra_args}"
exec_cmd "make go_api_check"
fi

if [ $TEST_TYPE == $TEST_TYPE_INTEG_TIER1 ];then
Expand All @@ -110,6 +111,7 @@ function run_tests {
-m tier1 \
tests/integration \
${nmstate_pytest_extra_args}"
exec_cmd "make go_api_check"
fi

if [ $TEST_TYPE == $TEST_TYPE_INTEG_TIER2 ];then
Expand All @@ -121,6 +123,7 @@ function run_tests {
-m tier2 \
tests/integration \
${nmstate_pytest_extra_args}"
exec_cmd "make go_api_check"
fi

if [ $TEST_TYPE == $TEST_TYPE_ALL ] || \
Expand All @@ -133,6 +136,7 @@ function run_tests {
-m slow --runslow \
tests/integration \
${nmstate_pytest_extra_args}"
exec_cmd "make go_api_check"
fi
}

Expand Down
1 change: 0 additions & 1 deletion examples/dns_remove.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
---
dns-resolver:
config: {}
interfaces: []
24 changes: 24 additions & 0 deletions examples/linuxbrige_eth1_up_alt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---
interfaces:
- name: eth1
type: ethernet
state: up
- name: linux-br0
type: linux-bridge
state: up
linux-bridge:
options:
group-forward-mask: 0
mac-ageing-time: 300
multicast-snooping: true
stp:
enabled: true
forward-delay: 15
hello-time: 2
max-age: 20
priority: 32768
port:
- name: eth1
stp-hairpin-mode: false
stp-path-cost: 100
stp-priority: 32
25 changes: 25 additions & 0 deletions examples/ovsbridge_create_alt.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
interfaces:
- name: eth1
type: ethernet
state: up
- name: ovs0
type: ovs-interface
state: up
ipv4:
enabled: true
address:
- ip: 192.0.2.1
prefix-length: 24
- name: ovs-br0
type: ovs-bridge
state: up
ovs-bridge:
options:
fail-mode: ''
mcast-snooping-enable: false
rstp: false
stp: true
port:
- name: eth1
- name: ovs0
1 change: 1 addition & 0 deletions rust/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ members = [
"src/cli",
"src/clib",
"src/lib",
"src/go/apigen",
]
79 changes: 79 additions & 0 deletions rust/src/go/api/api_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package nmstate

import (
"encoding/json"
"fmt"
"io/fs"
"io/ioutil"
"os"
"path/filepath"
"testing"

"sigs.k8s.io/yaml"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestUnmarshallingExamples(t *testing.T) {
examples := map[string][]byte{}
err := filepath.Walk("../../../../examples", func(path string, info fs.FileInfo, err error) error {
if info.IsDir() && info.Name() == "policy" {
return filepath.SkipDir
}
if info.IsDir() || filepath.Ext(info.Name()) != ".yml" {
return nil
}
example, err := ioutil.ReadFile(path)
if err != nil {
return fmt.Errorf("failed reading example '%s': %v", info.Name(), err)
}
examples[info.Name()] = example
return nil
})
require.NoError(t, err, "must succeed reading examples")
for exampleName, expectedExample := range examples {
t.Run(exampleName, func(t *testing.T) {
netState := &NetworkState{}
err := yaml.Unmarshal(expectedExample, netState)
assert.NoError(t, err, "must success unmarshaling example")

obtainedExample, err := yaml.Marshal(netState)
assert.NoError(t, err, "must success marshaling example")

assert.YAMLEq(t, string(expectedExample), string(obtainedExample), "expected: \n%s\nobtained: \n%s\n", expectedExample, obtainedExample)
})
}
}

func TestUnmarshallingIntegrationTests(t *testing.T) {
integrationTestsStatesPath := "../../../../tests/integration/.states/"
testStates := map[string][]byte{}
if _, err := os.Stat(integrationTestsStatesPath); os.IsNotExist(err) {
t.Skipf("Missing integration test states dir %s", integrationTestsStatesPath)
}
err := filepath.Walk(integrationTestsStatesPath, func(path string, info fs.FileInfo, err error) error {
if info.IsDir() || filepath.Ext(info.Name()) != ".json" {
return nil
}
testState, err := ioutil.ReadFile(path)
if err != nil {
return fmt.Errorf("failed reading integration test '%s': %v", info.Name(), err)
}
testStates[info.Name()] = testState
return nil
})
require.NoError(t, err, "must succeed reading examples")
for testStateName, expectedTestState := range testStates {
t.Run(testStateName, func(t *testing.T) {
netState := &NetworkState{}
err := json.Unmarshal(expectedTestState, netState)
assert.NoError(t, err, "must success unmarshaling test state")

obtainedTestState, err := json.Marshal(netState)
assert.NoError(t, err, "must success marshaling test state")

assert.JSONEq(t, string(expectedTestState), string(obtainedTestState), "expected: \n%s\nobtained: \n%s\n", expectedTestState, obtainedTestState)
})
}
}
16 changes: 16 additions & 0 deletions rust/src/go/api/boilerplate.go.txt
Original file line number Diff line number Diff line change
@@ -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.
*/

3 changes: 3 additions & 0 deletions rust/src/go/api/controller-gen.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
#!/bin/bash -e

GOFLAGS=-mod=mod go run sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0 $@

0 comments on commit 432fca0

Please sign in to comment.