Skip to content

Commit

Permalink
Merge pull request #1193 from sohankunkerkar/export-functions
Browse files Browse the repository at this point in the history
config/*: add export functions for parsing any config version less than N
  • Loading branch information
sohankunkerkar authored May 4, 2021
2 parents 3885b9f + 500c684 commit 557b3bf
Show file tree
Hide file tree
Showing 10 changed files with 253 additions and 79 deletions.
69 changes: 2 additions & 67 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,79 +15,14 @@
package config

import (
"github.com/coreos/ignition/v2/config/shared/errors"
"github.com/coreos/ignition/v2/config/util"
"github.com/coreos/ignition/v2/config/v3_0"
types_3_0 "github.com/coreos/ignition/v2/config/v3_0/types"
"github.com/coreos/ignition/v2/config/v3_1"
trans_3_1 "github.com/coreos/ignition/v2/config/v3_1/translate"
types_3_1 "github.com/coreos/ignition/v2/config/v3_1/types"
"github.com/coreos/ignition/v2/config/v3_2"
trans_3_2 "github.com/coreos/ignition/v2/config/v3_2/translate"
types_3_2 "github.com/coreos/ignition/v2/config/v3_2/types"
"github.com/coreos/ignition/v2/config/v3_3_experimental"
trans_exp "github.com/coreos/ignition/v2/config/v3_3_experimental/translate"
exp "github.com/coreos/ignition/v2/config/v3_3_experimental"
types_exp "github.com/coreos/ignition/v2/config/v3_3_experimental/types"

"github.com/coreos/go-semver/semver"
"github.com/coreos/vcontext/report"
)

type versionStub struct {
Ignition struct {
Version string
}
}

// Parse parses a config of any supported version and returns the equivalent config at the latest
// supported version.
func Parse(raw []byte) (types_exp.Config, report.Report, error) {
if len(raw) == 0 {
return types_exp.Config{}, report.Report{}, errors.ErrEmpty
}

stub := versionStub{}
rpt, err := util.HandleParseErrors(raw, &stub)
if err != nil {
return types_exp.Config{}, rpt, err
}

version, err := semver.NewVersion(stub.Ignition.Version)
if err != nil {
return types_exp.Config{}, report.Report{}, errors.ErrInvalidVersion
}

switch *version {
case types_exp.MaxVersion:
return v3_3_experimental.Parse(raw)
case types_3_2.MaxVersion:
return exp_from_3_2(v3_2.Parse(raw))
case types_3_1.MaxVersion:
return exp_from_3_2(v3_2_from_3_1(v3_1.Parse(raw)))
case types_3_0.MaxVersion:
return exp_from_3_2(v3_2_from_3_1(v3_1_from_3_0(v3_0.Parse(raw))))
default:
return types_exp.Config{}, report.Report{}, errors.ErrUnknownVersion
}
}

func exp_from_3_2(cfg types_3_2.Config, r report.Report, err error) (types_exp.Config, report.Report, error) {
if err != nil {
return types_exp.Config{}, r, err
}
return trans_exp.Translate(cfg), r, nil
}

func v3_2_from_3_1(cfg types_3_1.Config, r report.Report, err error) (types_3_2.Config, report.Report, error) {
if err != nil {
return types_3_2.Config{}, r, err
}
return trans_3_2.Translate(cfg), r, nil
}

func v3_1_from_3_0(cfg types_3_0.Config, r report.Report, err error) (types_3_1.Config, report.Report, error) {
if err != nil {
return types_3_1.Config{}, r, err
}
return trans_3_1.Translate(cfg), r, nil
return exp.ParseCompatibleVersion(raw)
}
45 changes: 45 additions & 0 deletions config/util/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright 2021 Red Hat, Inc.
//
// 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 util

import (
"github.com/coreos/ignition/v2/config/shared/errors"

"github.com/coreos/go-semver/semver"
"github.com/coreos/vcontext/report"
)

type versionStub struct {
Ignition struct {
Version string
}
}

// GetConfigVersion parses the version from the given raw config
func GetConfigVersion(raw []byte) (semver.Version, report.Report, error) {
if len(raw) == 0 {
return semver.Version{}, report.Report{}, errors.ErrEmpty
}

stub := versionStub{}
if rpt, err := HandleParseErrors(raw, &stub); err != nil {
return semver.Version{}, rpt, err
}

version, err := semver.NewVersion(stub.Ignition.Version)
if err != nil {
return semver.Version{}, report.Report{}, errors.ErrInvalidVersion
}
return *version, report.Report{}, nil
}
18 changes: 15 additions & 3 deletions config/v3_0/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func Merge(parent, child types.Config) types.Config {
// Parse parses the raw config into a types.Config struct and generates a report of any
// errors, warnings, info, and deprecations it encountered
func Parse(rawConfig []byte) (types.Config, report.Report, error) {
if isEmpty(rawConfig) {
if len(rawConfig) == 0 {
return types.Config{}, report.Report{}, errors.ErrEmpty
}

Expand All @@ -56,6 +56,18 @@ func Parse(rawConfig []byte) (types.Config, report.Report, error) {
return config, rpt, nil
}

func isEmpty(userdata []byte) bool {
return len(userdata) == 0
// ParseCompatibleVersion parses the raw config of version 3.0.0 into
// a 3.0 types.Config struct and generates a report of any errors, warnings,
// info, and deprecations it encountered
func ParseCompatibleVersion(raw []byte) (types.Config, report.Report, error) {
version, rpt, err := util.GetConfigVersion(raw)
if err != nil {
return types.Config{}, rpt, err
}

if version == types.MaxVersion {
return Parse(raw)
}

return types.Config{}, report.Report{}, errors.ErrUnknownVersion
}
32 changes: 32 additions & 0 deletions config/v3_0/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,43 @@ func TestParse(t *testing.T) {
},
}

testsCompt := []struct {
in in
out out
}{
{
in: in{config: []byte(`{"ignition": {"version": "3.0.0"}}`)},
out: out{config: types.Config{Ignition: types.Ignition{Version: types.MaxVersion.String()}}},
},
{
in: in{config: []byte(`{"ignition": {"version": "3.1.0"}}`)},
out: out{err: errors.ErrUnknownVersion},
},
{
in: in{config: []byte(`{"ignition": {"version": "3.2.0"}}`)},
out: out{err: errors.ErrUnknownVersion},
},
{
in: in{config: []byte(`{"ignition": {"version": "3.3.0-experimental"}}`)},
out: out{err: errors.ErrUnknownVersion},
},
{
in: in{config: []byte{}},
out: out{err: errors.ErrEmpty},
},
}
for i, test := range tests {
config, report, err := Parse(test.in.config)
if test.out.err != err {
t.Errorf("#%d: bad error: want %v, got %v, report: %+v", i, test.out.err, err, report)
}
assert.Equal(t, test.out.config, config, "#%d: bad config, report: %+v", i, report)
}
for i, test := range testsCompt {
config, report, err := ParseCompatibleVersion(test.in.config)
if test.out.err != err {
t.Errorf("#%d: bad error: want %v, got %v, report: %+v", i, test.out.err, err, report)
}
assert.Equal(t, test.out.config, config, "#%d: bad config, report: %+v", i, report)
}
}
23 changes: 20 additions & 3 deletions config/v3_1/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"github.com/coreos/ignition/v2/config/merge"
"github.com/coreos/ignition/v2/config/shared/errors"
"github.com/coreos/ignition/v2/config/util"
prev "github.com/coreos/ignition/v2/config/v3_0"
"github.com/coreos/ignition/v2/config/v3_1/translate"
"github.com/coreos/ignition/v2/config/v3_1/types"
"github.com/coreos/ignition/v2/config/validate"

Expand All @@ -33,7 +35,7 @@ func Merge(parent, child types.Config) types.Config {
// Parse parses the raw config into a types.Config struct and generates a report of any
// errors, warnings, info, and deprecations it encountered
func Parse(rawConfig []byte) (types.Config, report.Report, error) {
if isEmpty(rawConfig) {
if len(rawConfig) == 0 {
return types.Config{}, report.Report{}, errors.ErrEmpty
}

Expand All @@ -56,6 +58,21 @@ func Parse(rawConfig []byte) (types.Config, report.Report, error) {
return config, rpt, nil
}

func isEmpty(userdata []byte) bool {
return len(userdata) == 0
// ParseCompatibleVersion parses the raw config of version 3.1.0 or lesser
// into a 3.1 types.Config struct and generates a report of any errors, warnings,
// info, and deprecations it encountered
func ParseCompatibleVersion(raw []byte) (types.Config, report.Report, error) {
version, rpt, err := util.GetConfigVersion(raw)
if err != nil {
return types.Config{}, rpt, err
}

if version == types.MaxVersion {
return Parse(raw)
}
prevCfg, r, err := prev.ParseCompatibleVersion(raw)
if err != nil {
return types.Config{}, r, err
}
return translate.Translate(prevCfg), r, nil
}
29 changes: 29 additions & 0 deletions config/v3_1/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,11 +121,40 @@ func TestParse(t *testing.T) {
},
}

testsCompt := []struct {
in in
out out
}{
{
in: in{config: []byte(`{"ignition": {"version": "3.2.0"}}`)},
out: out{err: errors.ErrUnknownVersion},
},
{
in: in{config: []byte(`{"ignition": {"version": "3.0.0"}}`)},
out: out{config: types.Config{Ignition: types.Ignition{Version: types.MaxVersion.String()}}},
},
{
in: in{config: []byte(`{"ignition": {"version": "3.1.0"}}`)},
out: out{config: types.Config{Ignition: types.Ignition{Version: types.MaxVersion.String()}}},
},
{
in: in{config: []byte{}},
out: out{err: errors.ErrEmpty},
},
}

for i, test := range tests {
config, report, err := Parse(test.in.config)
if test.out.err != err {
t.Errorf("#%d: bad error: want %v, got %v, report: %+v", i, test.out.err, err, report)
}
assert.Equal(t, test.out.config, config, "#%d: bad config, report: %+v", i, report)
}
for i, test := range testsCompt {
config, report, err := ParseCompatibleVersion(test.in.config)
if test.out.err != err {
t.Errorf("#%d: bad error: want %v, got %v, report: %+v", i, test.out.err, err, report)
}
assert.Equal(t, test.out.config, config, "#%d: bad config, report: %+v", i, report)
}
}
23 changes: 20 additions & 3 deletions config/v3_2/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import (
"github.com/coreos/ignition/v2/config/merge"
"github.com/coreos/ignition/v2/config/shared/errors"
"github.com/coreos/ignition/v2/config/util"
prev "github.com/coreos/ignition/v2/config/v3_1"
"github.com/coreos/ignition/v2/config/v3_2/translate"
"github.com/coreos/ignition/v2/config/v3_2/types"
"github.com/coreos/ignition/v2/config/validate"

Expand All @@ -33,7 +35,7 @@ func Merge(parent, child types.Config) types.Config {
// Parse parses the raw config into a types.Config struct and generates a report of any
// errors, warnings, info, and deprecations it encountered
func Parse(rawConfig []byte) (types.Config, report.Report, error) {
if isEmpty(rawConfig) {
if len(rawConfig) == 0 {
return types.Config{}, report.Report{}, errors.ErrEmpty
}

Expand All @@ -56,6 +58,21 @@ func Parse(rawConfig []byte) (types.Config, report.Report, error) {
return config, rpt, nil
}

func isEmpty(userdata []byte) bool {
return len(userdata) == 0
// ParseCompatibleVersion parses the raw config of version 3.2.0 or lesser
// into a 3.2 types.Config struct and generates a report of any errors, warnings,
// info, and deprecations it encountered
func ParseCompatibleVersion(raw []byte) (types.Config, report.Report, error) {
version, rpt, err := util.GetConfigVersion(raw)
if err != nil {
return types.Config{}, rpt, err
}

if version == types.MaxVersion {
return Parse(raw)
}
prevCfg, r, err := prev.ParseCompatibleVersion(raw)
if err != nil {
return types.Config{}, report.Report{}, err
}
return translate.Translate(prevCfg), r, nil
}
33 changes: 33 additions & 0 deletions config/v3_2/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -129,11 +129,44 @@ func TestParse(t *testing.T) {
},
}

testsCompt := []struct {
in in
out out
}{
{
in: in{config: []byte(`{"ignition": {"version": "3.2.0"}}`)},
out: out{config: types.Config{Ignition: types.Ignition{Version: types.MaxVersion.String()}}},
},
{
in: in{config: []byte(`{"ignition": {"version": "3.0.0"}}`)},
out: out{config: types.Config{Ignition: types.Ignition{Version: types.MaxVersion.String()}}},
},
{
in: in{config: []byte(`{"ignition": {"version": "3.1.0"}}`)},
out: out{config: types.Config{Ignition: types.Ignition{Version: types.MaxVersion.String()}}},
},
{
in: in{config: []byte(`{"ignition": {"version": "3.3.0-experimental"}}`)},
out: out{err: errors.ErrUnknownVersion},
},
{
in: in{config: []byte{}},
out: out{err: errors.ErrEmpty},
},
}

for i, test := range tests {
config, report, err := Parse(test.in.config)
if test.out.err != err {
t.Errorf("#%d: bad error: want %v, got %v, report: %+v", i, test.out.err, err, report)
}
assert.Equal(t, test.out.config, config, "#%d: bad config, report: %+v", i, report)
}
for i, test := range testsCompt {
config, report, err := ParseCompatibleVersion(test.in.config)
if test.out.err != err {
t.Errorf("#%d: bad error: want %v, got %v, report: %+v", i, test.out.err, err, report)
}
assert.Equal(t, test.out.config, config, "#%d: bad config, report: %+v", i, report)
}
}
Loading

0 comments on commit 557b3bf

Please sign in to comment.