2023-01-06 06:04:36 -05:00
|
|
|
/*
|
|
|
|
Copyright (c) Edgeless Systems GmbH
|
|
|
|
|
|
|
|
SPDX-License-Identifier: AGPL-3.0-only
|
|
|
|
*/
|
|
|
|
|
|
|
|
package components
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/sha256"
|
2023-12-15 09:45:52 -05:00
|
|
|
"encoding/json"
|
2023-01-06 06:04:36 -05:00
|
|
|
"errors"
|
|
|
|
"fmt"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Components is a list of Kubernetes components.
|
2023-12-11 02:08:55 -05:00
|
|
|
type Components []*Component
|
2023-01-06 06:04:36 -05:00
|
|
|
|
2023-12-15 09:45:52 -05:00
|
|
|
type legacyComponent struct {
|
|
|
|
URL string `json:"URL,omitempty"`
|
|
|
|
Hash string `json:"Hash,omitempty"`
|
|
|
|
InstallPath string `json:"InstallPath,omitempty"`
|
|
|
|
Extract bool `json:"Extract,omitempty"`
|
|
|
|
}
|
|
|
|
|
|
|
|
// UnmarshalJSON implements a custom JSON unmarshaler to ensure backwards compatibility
|
|
|
|
// with older components lists which had a different format for all keys.
|
|
|
|
func (c *Components) UnmarshalJSON(b []byte) error {
|
|
|
|
var legacyComponents []*legacyComponent
|
|
|
|
if err := json.Unmarshal(b, &legacyComponents); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
var components []*Component
|
|
|
|
if err := json.Unmarshal(b, &components); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
if len(legacyComponents) != len(components) {
|
|
|
|
return errors.New("failed to unmarshal data: inconsistent number of components in list") // just a check, should never happen
|
|
|
|
}
|
|
|
|
|
|
|
|
// If a value is not set in the new format,
|
|
|
|
// it might have been set in the old format.
|
|
|
|
// In this case, we copy the value from the old format.
|
|
|
|
comps := make(Components, len(components))
|
|
|
|
for idx := 0; idx < len(components); idx++ {
|
|
|
|
comps[idx] = components[idx]
|
|
|
|
if comps[idx].Url == "" {
|
|
|
|
comps[idx].Url = legacyComponents[idx].URL
|
|
|
|
}
|
|
|
|
if comps[idx].Hash == "" {
|
|
|
|
comps[idx].Hash = legacyComponents[idx].Hash
|
|
|
|
}
|
|
|
|
if comps[idx].InstallPath == "" {
|
|
|
|
comps[idx].InstallPath = legacyComponents[idx].InstallPath
|
|
|
|
}
|
|
|
|
if !comps[idx].Extract {
|
|
|
|
comps[idx].Extract = legacyComponents[idx].Extract
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
*c = comps
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-01-06 06:04:36 -05:00
|
|
|
// GetHash returns the hash over all component hashes.
|
|
|
|
func (c Components) GetHash() string {
|
|
|
|
sha := sha256.New()
|
|
|
|
for _, component := range c {
|
|
|
|
sha.Write([]byte(component.Hash))
|
|
|
|
}
|
|
|
|
|
|
|
|
return fmt.Sprintf("sha256:%x", sha.Sum(nil))
|
|
|
|
}
|
|
|
|
|
|
|
|
// GetKubeadmComponent returns the kubeadm component.
|
2023-12-11 02:08:55 -05:00
|
|
|
func (c Components) GetKubeadmComponent() (*Component, error) {
|
2023-01-06 06:04:36 -05:00
|
|
|
for _, component := range c {
|
2023-12-11 02:08:55 -05:00
|
|
|
if strings.Contains(component.GetUrl(), "kubeadm") {
|
2023-01-06 06:04:36 -05:00
|
|
|
return component, nil
|
|
|
|
}
|
|
|
|
}
|
2023-12-11 02:08:55 -05:00
|
|
|
return nil, errors.New("kubeadm component not found")
|
2023-01-06 06:04:36 -05:00
|
|
|
}
|
2023-12-14 10:02:59 -05:00
|
|
|
|
|
|
|
// GetUpgradableComponents returns only those Components that should be passed to the upgrade-agent.
|
|
|
|
func (c Components) GetUpgradableComponents() Components {
|
|
|
|
var cs Components
|
|
|
|
for _, c := range c {
|
|
|
|
if strings.HasPrefix(c.Url, "data:") || strings.HasSuffix(c.InstallPath, "kubeadm") {
|
|
|
|
cs = append(cs, c)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return cs
|
|
|
|
}
|