From 19fab24b9c84115c8c1e85cbf112a2ef7327fa9d Mon Sep 17 00:00:00 2001 From: Guilhem Lettron Date: Fri, 6 Sep 2024 15:35:32 +0200 Subject: [PATCH] feat(akamai): unzip user content --- docs/release-notes.md | 1 + internal/providers/akamai/akamai.go | 9 +++++- internal/providers/util/unzip.go | 43 +++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 internal/providers/util/unzip.go diff --git a/docs/release-notes.md b/docs/release-notes.md index c734609fe..6fc298861 100644 --- a/docs/release-notes.md +++ b/docs/release-notes.md @@ -12,6 +12,7 @@ nav_order: 9 - Support partitioning disk with mounted partitions - Support Proxmox VE +- Support gzipped Akamai user_data ### Changes diff --git a/internal/providers/akamai/akamai.go b/internal/providers/akamai/akamai.go index 648be3bee..9b178a8c8 100644 --- a/internal/providers/akamai/akamai.go +++ b/internal/providers/akamai/akamai.go @@ -91,7 +91,14 @@ func fetchConfig(f *resource.Fetcher) (types.Config, report.Report, error) { return types.Config{}, report.Report{}, fmt.Errorf("decode base64: %w", err) } - return util.ParseConfig(f.Logger, data[:n]) + // The Linode Metadata Service can compress userdata. + // We have to gunzip if needed. + unzipData, err := util.GunzipIfNeeded(data[:n]) + if err != nil { + return types.Config{}, report.Report{}, fmt.Errorf("unzip: %w", err) + } + + return util.ParseConfig(f.Logger, unzipData) } // defaultTokenTTL is the time-to-live (TTL; in seconds) for an authorization diff --git a/internal/providers/util/unzip.go b/internal/providers/util/unzip.go new file mode 100644 index 000000000..03455198f --- /dev/null +++ b/internal/providers/util/unzip.go @@ -0,0 +1,43 @@ +// Copyright 2024 CoreOS, 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 ( + "bytes" + "compress/gzip" + "io" +) + +var ( + gzipMagic = []byte{0x1F, 0x8B, 0x08} +) + +func hasGzipMagicNumber(source []byte) bool { + return bytes.HasPrefix(source, gzipMagic) +} + +func GunzipIfNeeded(raw []byte) ([]byte, error) { + if !hasGzipMagicNumber(raw) { + return raw, nil + } + + reader, err := gzip.NewReader(bytes.NewReader(raw)) + if err != nil { + return nil, err + } + defer reader.Close() + + return io.ReadAll(reader) +}