From 2416ab0120bfe15cd3c5ef6cd0bbade288b32e7a Mon Sep 17 00:00:00 2001 From: Kiran Kamineni Date: Wed, 23 Jan 2019 12:54:50 -0800 Subject: Add support for parsing profile yaml files Add code to parse profile configuration yaml The parsing function is global and returns a client which can then be used to get or apply specific parts of the configuration on top of an extracted helm chart. P14: Add unit test that covers both ProcessProfileYaml and CopyConfigurationOverrides P15: Adding mock_charts and mock_profiles We expect to reuse these files for other unit tests Issue-ID: ONAPARC-348 Change-Id: I4504d0b158fdfef476b8c2a461d33306926545d7 Signed-off-by: Kiran Kamineni --- src/k8splugin/internal/rb/profile.go | 8 +- src/k8splugin/internal/rb/profile_yaml.go | 109 +++++++++++++++++++ src/k8splugin/internal/rb/profile_yaml_test.go | 139 +++++++++++++++++++++++++ 3 files changed, 253 insertions(+), 3 deletions(-) create mode 100644 src/k8splugin/internal/rb/profile_yaml.go create mode 100644 src/k8splugin/internal/rb/profile_yaml_test.go (limited to 'src/k8splugin/internal/rb') diff --git a/src/k8splugin/internal/rb/profile.go b/src/k8splugin/internal/rb/profile.go index 2456ad2d..d78e32e4 100644 --- a/src/k8splugin/internal/rb/profile.go +++ b/src/k8splugin/internal/rb/profile.go @@ -51,6 +51,7 @@ type ProfileManager interface { type ProfileClient struct { storeName string tagMeta, tagContent string + manifestName string } // NewProfileClient returns an instance of the ProfileClient @@ -58,9 +59,10 @@ type ProfileClient struct { // Uses rb/def prefix func NewProfileClient() *ProfileClient { return &ProfileClient{ - storeName: "rbprofile", - tagMeta: "metadata", - tagContent: "content", + storeName: "rbprofile", + tagMeta: "metadata", + tagContent: "content", + manifestName: "manifest.yaml", } } diff --git a/src/k8splugin/internal/rb/profile_yaml.go b/src/k8splugin/internal/rb/profile_yaml.go new file mode 100644 index 00000000..ba55fba9 --- /dev/null +++ b/src/k8splugin/internal/rb/profile_yaml.go @@ -0,0 +1,109 @@ +/* + * Copyright 2018 Intel Corporation, 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 rb + +import ( + "io/ioutil" + "log" + "path/filepath" + + "github.com/ghodss/yaml" + pkgerrors "github.com/pkg/errors" +) + +/* +#Sample Yaml format for profile manifest.yaml +--- +version: v1 +type: + values: "values_override.yaml" + configresource: + - filepath: config.yaml + chartpath: chart/config/resources/config.yaml + - filepath: config2.yaml + chartpath: chart/config/resources/config2.yaml +*/ + +type overrideFiles struct { + FilePath string `yaml:"filepath"` + ChartPath string `yaml:"chartpath"` +} + +type supportedOverrides struct { + ConfigResource []overrideFiles `yaml:"configresource"` + Values string `yaml:"values"` +} + +type profileOverride struct { + Version string `yaml:"version"` + Type supportedOverrides `yaml:"type"` +} + +type ProfileYamlClient struct { + path string + override profileOverride +} + +func (p ProfileYamlClient) Print() { + log.Println(p.override) +} + +//GetValues returns a path to the override values.yam +//that was part of the profile +func (p ProfileYamlClient) GetValues() string { + return filepath.Join(p.path, p.override.Type.Values) +} + +//CopyConfigurationOverrides copies the various files that are +//provided as overrides to their corresponding locations within +//the destination chart. +func (p ProfileYamlClient) CopyConfigurationOverrides(chartPath string) error { + + //Iterate over each configresource and copy that file into + //the respective path in the chart. + for _, v := range p.override.Type.ConfigResource { + data, err := ioutil.ReadFile(filepath.Join(p.path, v.FilePath)) + if err != nil { + return pkgerrors.Wrap(err, "Reading configuration file") + } + err = ioutil.WriteFile(filepath.Join(chartPath, v.ChartPath), data, 0644) + if err != nil { + return pkgerrors.Wrap(err, "Writing configuration file into chartpath") + } + } + + return nil +} + +//ProcessProfileYaml parses the manifest.yaml file that is part of the profile +//package and creates the appropriate structures out of it. +func ProcessProfileYaml(fpath string, manifestFileName string) (ProfileYamlClient, error) { + + p := filepath.Join(fpath, manifestFileName) + data, err := ioutil.ReadFile(p) + if err != nil { + return ProfileYamlClient{}, pkgerrors.Wrap(err, "Reading manifest file") + } + + out := profileOverride{} + err = yaml.Unmarshal(data, &out) + if err != nil { + return ProfileYamlClient{}, pkgerrors.Wrap(err, "Marshaling manifest yaml file") + } + + return ProfileYamlClient{path: fpath, override: out}, nil +} diff --git a/src/k8splugin/internal/rb/profile_yaml_test.go b/src/k8splugin/internal/rb/profile_yaml_test.go new file mode 100644 index 00000000..c29bf9ed --- /dev/null +++ b/src/k8splugin/internal/rb/profile_yaml_test.go @@ -0,0 +1,139 @@ +// +build unit + +/* + * Copyright 2018 Intel Corporation, 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 rb + +import ( + "os" + "path/filepath" + "strings" + "testing" +) + +func TestProcessProfileYaml(t *testing.T) { + + profileDir := "../../mock_files/mock_profiles/profile1" + manifestFile := "manifest.yaml" + faultymanifestfile := "faulty-manifest.yaml" + + testCases := []struct { + label string + prDir, manifest string + expectedError string + }{ + { + label: "Process Profile Yaml", + prDir: profileDir, + manifest: manifestFile, + expectedError: "", + }, + { + label: "Non existent manifest file", + prDir: profileDir, + manifest: "non-existant-file.yaml", + expectedError: "Reading manifest file", + }, + { + label: "Faulty manifest file", + prDir: profileDir, + manifest: faultymanifestfile, + expectedError: "Marshaling manifest yaml file", + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + _, err := ProcessProfileYaml(testCase.prDir, testCase.manifest) + if err != nil { + if testCase.expectedError == "" { + t.Fatalf("Got an error %s", err) + } + if strings.Contains(err.Error(), testCase.expectedError) == false { + t.Fatalf("Got unexpected error message %s", err) + } + } + }) + } +} + +func TestCopyConfigurationOverrides(t *testing.T) { + + profileDir := "../../mock_files/mock_profiles/profile1" + profileFileName := "p1.yaml" + manifestFile := "manifest.yaml" + faultySrcManifestFile := "faulty-src-manifest.yaml" + faultyDestManifestFile := "faulty-dest-manifest.yaml" + chartBaseDir := "../../mock_files/mock_charts" + + //Remove the testchart1/templates/p1.yaml file that gets copied over + defer os.Remove(filepath.Join(chartBaseDir, "testchart1", "templates", profileFileName)) + + testCases := []struct { + label string + prDir, chDir, manifest string + expectedError string + }{ + { + label: "Copy Configuration Overrides", + prDir: profileDir, + manifest: manifestFile, + chDir: chartBaseDir, + expectedError: "", + }, + { + label: "Copy Configuration Overrides Faulty Source", + prDir: profileDir, + manifest: faultySrcManifestFile, + chDir: chartBaseDir, + expectedError: "Reading configuration file", + }, + { + label: "Copy Configuration Overrides Faulty Destination", + prDir: profileDir, + manifest: faultyDestManifestFile, + chDir: chartBaseDir, + expectedError: "Writing configuration file", + }, + } + + for _, testCase := range testCases { + t.Run(testCase.label, func(t *testing.T) { + p, err := ProcessProfileYaml(testCase.prDir, testCase.manifest) + if err != nil { + t.Fatalf("Got unexpected error processing yaml %s", err) + } + + err = p.CopyConfigurationOverrides(testCase.chDir) + if err != nil { + if testCase.expectedError == "" { + t.Fatalf("Got error %s", err) + } + if strings.Contains(err.Error(), testCase.expectedError) == false { + t.Fatalf("Got unexpected error message %s", err) + } + + } else { + //Check if the file got copied over + if _, err = os.Stat(filepath.Join(testCase.chDir, "testchart1", + "templates", profileFileName)); os.IsNotExist(err) { + t.Fatalf("Failed to copy override file: %s", profileFileName) + } + } + }) + } +} -- cgit 1.2.3-korg