pkg/wrapper/bundlewrapper.go (145 lines of code) (raw):

// Copyright 2018 Google LLC // // 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 // // https://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 wrapper provides a union type for expressing various different // bundle-types. package wrapper import ( "fmt" bundle "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/apis/bundle/v1alpha1" "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/converter" "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/options" "github.com/GoogleCloudPlatform/k8s-cluster-bundle/pkg/options/multi" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) // BundleWrapper represents one of several possible bundle types -- a union type. type BundleWrapper struct { bundle *bundle.Bundle component *bundle.Component bundleBuilder *bundle.BundleBuilder componentBuilder *bundle.ComponentBuilder } // FromRaw creates a BundleWrapper object from a byte source, by converting // based off of the Kind. func FromRaw(inFmt string, bytes []byte) (*BundleWrapper, error) { if len(bytes) == 0 { return nil, fmt.Errorf("in FromRaw, content was empty") } if inFmt == "" { return nil, fmt.Errorf("in FromRaw, format was empty") } uns, err := converter.FromContentType(inFmt, bytes).ToUnstructured() if err != nil { return nil, err } kind := uns.GetKind() switch kind { case "BundleBuilder": b, err := converter.FromContentType(inFmt, bytes).ToBundleBuilder() if err != nil { return nil, err } return FromBundleBuilder(b), nil case "Bundle": b, err := converter.FromContentType(inFmt, bytes).ToBundle() if err != nil { return nil, err } return FromBundle(b), nil case "ComponentBuilder": c, err := converter.FromContentType(inFmt, bytes).ToComponentBuilder() if err != nil { return nil, err } return FromComponentBuilder(c), nil case "Component": c, err := converter.FromContentType(inFmt, bytes).ToComponent() if err != nil { return nil, err } return FromComponent(c), nil default: return nil, fmt.Errorf("unrecognized bundle-kind %s for content %s", kind, string(bytes)) } } // FromBundle creates a BundleWrapper from a bundle object. func FromBundle(c *bundle.Bundle) *BundleWrapper { return &BundleWrapper{bundle: c} } // FromComponent creates a BundleWrapper from a component object func FromComponent(c *bundle.Component) *BundleWrapper { return &BundleWrapper{component: c} } // FromBundleBuilder creates a BundleWrapper from a bundle builder object. func FromBundleBuilder(c *bundle.BundleBuilder) *BundleWrapper { return &BundleWrapper{bundleBuilder: c} } // FromComponentBuilder creates a BundleWrapper from a component builder object func FromComponentBuilder(c *bundle.ComponentBuilder) *BundleWrapper { return &BundleWrapper{componentBuilder: c} } // Bundle returns the wrapped bundle object. func (bw *BundleWrapper) Bundle() *bundle.Bundle { return bw.bundle } // Component returns the wrapped Component object. func (bw *BundleWrapper) Component() *bundle.Component { return bw.component } // BundleBuilder returns the wrapped BundleBuilder object. func (bw *BundleWrapper) BundleBuilder() *bundle.BundleBuilder { return bw.bundleBuilder } // ComponentBuilder returns the wrapped ComponentBuilder object. func (bw *BundleWrapper) ComponentBuilder() *bundle.ComponentBuilder { return bw.componentBuilder } // Kind gets the type of the underlying object. func (bw *BundleWrapper) Kind() string { if bw.Bundle() != nil { return bw.Bundle().Kind } else if bw.BundleBuilder() != nil { return bw.BundleBuilder().Kind } else if bw.Component() != nil { return bw.Component().Kind } else if bw.ComponentBuilder() != nil { return bw.ComponentBuilder().Kind } return "" } // Object returns the wrapped object. func (bw *BundleWrapper) Object() interface{} { if bw.Bundle() != nil { return bw.Bundle() } else if bw.BundleBuilder() != nil { return bw.BundleBuilder() } else if bw.Component() != nil { return bw.Component() } else if bw.ComponentBuilder() != nil { return bw.ComponentBuilder() } return nil } // AllComponents returns all the components in the BundleWrapper, with the // assumption that only one of Bundle or Component is filled out. func (bw *BundleWrapper) AllComponents() []*bundle.Component { if bw.bundle != nil { return bw.bundle.Components } else if bw.component != nil { return []*bundle.Component{bw.component} } return nil } // ExportAsObjects will export a Bundle as a ComponentSet and Components, // or a Component as unstructured Objects. func (bw *BundleWrapper) ExportAsObjects(opts options.JSONOptions) ([]*unstructured.Unstructured, error) { switch bw.Kind() { case "Component": components := bw.Component() if opts != nil { applier := multi.NewDefaultApplier() comp, err := applier.ApplyOptions(components, opts) if err != nil { return nil, fmt.Errorf("failed to apply options: %v", err) } components = comp } return components.Spec.Objects, nil case "Bundle": bun := bw.Bundle() y, err := converter.FromObject(bun.ComponentSet()).ToYAML() if err != nil { return nil, err } o, err := converter.FromYAML(y).ToUnstructured() if err != nil { return nil, err } var objs []*unstructured.Unstructured objs = append(objs, o) for _, c := range bun.Components { y, err := converter.FromObject(c).ToYAML() if err != nil { return nil, err } o, err := converter.FromYAML(y).ToUnstructured() if err != nil { return nil, err } objs = append(objs, o) } return objs, nil default: return nil, fmt.Errorf("bundle kind %q not supported for exporting", bw.Kind()) } }