pkg/bundle/container.go (85 lines of code) (raw):

// Licensed to Elasticsearch B.V. under one or more contributor // license agreements. See the NOTICE file distributed with // this work for additional information regarding copyright // ownership. Elasticsearch B.V. licenses this file to you 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 bundle import ( "bytes" "compress/gzip" "fmt" "io" bundlev1 "github.com/elastic/harp/api/gen/go/harp/bundle/v1" containerv1 "github.com/elastic/harp/api/gen/go/harp/container/v1" "github.com/elastic/harp/pkg/container" "github.com/elastic/harp/pkg/sdk/types" ) // Statistic hold bundle statistic information type Statistic struct { PackageCount uint32 CSOCompliantPackageNameCount uint32 SecretCount uint32 } const ( bundleContentType = "application/vnd.harp.v1.Bundle" gzipCompressionLevel = 9 ) // FromContainerReader returns a Bundle extracted from a secret container. func FromContainerReader(r io.Reader) (*bundlev1.Bundle, error) { // Check parameters if types.IsNil(r) { return nil, fmt.Errorf("unable to process nil reader") } // Load secret container c, err := container.Load(r) if err != nil { return nil, fmt.Errorf("unable to load Bundle: %w", err) } // Delegate to bundle loader return FromContainer(c) } // ToContainerWriter returns a Bundle packaged as a secret container. func ToContainerWriter(w io.Writer, b *bundlev1.Bundle) error { // Check parameters if types.IsNil(w) { return fmt.Errorf("unable to process nil writer") } if b == nil { return fmt.Errorf("unable to process nil bundle") } // Create a container c, err := ToContainer(b) if err != nil { return fmt.Errorf("unable to wrap bundle as a container: %w", err) } // Prepare secret container return container.Dump(w, c) } // FromContainer unwraps a Bundle from a secret container. func FromContainer(c *containerv1.Container) (*bundlev1.Bundle, error) { // Check parameters if types.IsNil(c) { return nil, fmt.Errorf("unable to process nil container") } // Check headers if types.IsNil(c.Headers) { return nil, fmt.Errorf("unable to process nil container headers") } if c.Headers.ContentType != bundleContentType { return nil, fmt.Errorf("invalid content type for Bundle loader") } if c.Headers.ContentEncoding != "gzip" { return nil, fmt.Errorf("invalid content encoding for Bundle loader") } // Decompress bundle zr, err := gzip.NewReader(bytes.NewReader(c.Raw)) if err != nil { return nil, fmt.Errorf("unable to initialize compression reader") } // Delegate to bundle loader return Load(zr) } // ToContainer wrpas a Bundle as a container object. func ToContainer(b *bundlev1.Bundle) (*containerv1.Container, error) { if b == nil { return nil, fmt.Errorf("unable to process nil bundle") } // Dump bundle payload := &bytes.Buffer{} // Compress with gzip zw, errGz := gzip.NewWriterLevel(payload, gzipCompressionLevel) if errGz != nil { return nil, fmt.Errorf("unable to compress bundle content: %w", errGz) } // Delegate to Bundle Writer if errDump := Dump(zw, b); errDump != nil { return nil, fmt.Errorf("unable to dump container: %w", errDump) } // Close gzip writer if errGz = zw.Close(); errGz != nil { return nil, fmt.Errorf("unable to close compression writer: %w", errGz) } // Return container return &containerv1.Container{ Headers: &containerv1.Header{ ContentEncoding: "gzip", ContentType: bundleContentType, }, Raw: payload.Bytes(), }, nil }