feat: initial copy of v0.1.0
This commit is contained in:
parent
4cc801a7f3
commit
7d4cbb6b08
538 changed files with 63361 additions and 55213 deletions
169
generator/cmd/publish/versions.go
Normal file
169
generator/cmd/publish/versions.go
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
package publish
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
)
|
||||
|
||||
type Version struct {
|
||||
Version string `json:"version"`
|
||||
Protocols []string `json:"protocols"`
|
||||
Platforms []Platform `json:"platforms"`
|
||||
}
|
||||
|
||||
type Platform struct {
|
||||
OS string `json:"os" yaml:"os"`
|
||||
Arch string `json:"arch" yaml:"arch"`
|
||||
}
|
||||
|
||||
type Data struct {
|
||||
Id string `json:"id,omitempty"`
|
||||
Versions []Version `json:"versions"`
|
||||
}
|
||||
|
||||
func (d *Data) WriteToFile(filePath string) error {
|
||||
// TODO: make it variable
|
||||
d.Id = "tfregistry.sysops.stackit.rocks/mhenselin/stackitprivatepreview"
|
||||
|
||||
jsonString, err := json.Marshal(d)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error encoding data: %w", err)
|
||||
}
|
||||
|
||||
//nolint:gosec // this file is not sensitive, so we can use os.ModePerm
|
||||
err = os.WriteFile(
|
||||
filePath,
|
||||
jsonString,
|
||||
os.ModePerm,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error writing data: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Data) AddVersion(v Version) error {
|
||||
var newVersions []Version
|
||||
for _, ver := range d.Versions {
|
||||
if ver.Version != v.Version {
|
||||
newVersions = append(newVersions, ver)
|
||||
}
|
||||
}
|
||||
newVersions = append(newVersions, v)
|
||||
d.Versions = newVersions
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Data) Validate() error {
|
||||
for _, v := range d.Versions {
|
||||
err := v.Validate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Data) LoadFromFile(filePath string) error {
|
||||
plan, err := os.ReadFile(filePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = json.Unmarshal(plan, &d)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *Data) LoadFromUrl(uri string) error {
|
||||
u, err := url.ParseRequestURI(uri)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
file, err := os.CreateTemp("", "versions.*.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(name string) {
|
||||
//nolint:gosec // The file path is generated by os.CreateTemp and is not user-controllable
|
||||
err := os.Remove(name)
|
||||
if err != nil {
|
||||
slog.Error("failed to remove temporary file", slog.Any("err", err))
|
||||
}
|
||||
}(file.Name()) // Clean up
|
||||
|
||||
err = DownloadFile(
|
||||
u.String(),
|
||||
file.Name(),
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return d.LoadFromFile(file.Name())
|
||||
}
|
||||
|
||||
func (v *Version) Validate() error {
|
||||
slog.Warn("validation needs to be implemented")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Version) AddPlatform(p Platform) error {
|
||||
if p.OS == "" || p.Arch == "" {
|
||||
return fmt.Errorf("OS and Arch MUST NOT be empty")
|
||||
}
|
||||
v.Platforms = append(v.Platforms, p)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (v *Version) AddProtocol(p string) error {
|
||||
if p == "" {
|
||||
return fmt.Errorf("protocol MUST NOT be empty")
|
||||
}
|
||||
v.Protocols = append(v.Protocols, p)
|
||||
return nil
|
||||
}
|
||||
|
||||
// DownloadFile will download a url and store it in local filepath.
|
||||
// It writes to the destination file as it downloads it, without
|
||||
// loading the entire file into memory.
|
||||
func DownloadFile(urlValue, filepath string) error {
|
||||
// Create the file
|
||||
//nolint:gosec // path traversal is not a concern here, as the filepath is generated by us and not user input
|
||||
out, err := os.Create(filepath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(out *os.File) {
|
||||
err := out.Close()
|
||||
if err != nil {
|
||||
slog.Error("failed to close file", slog.Any("err", err))
|
||||
}
|
||||
}(out)
|
||||
|
||||
// Get the data
|
||||
|
||||
//nolint:gosec,bodyclose // this is a controlled URL, not user input
|
||||
resp, err := http.Get(urlValue)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func(Body io.ReadCloser) {
|
||||
_ = Body.Close()
|
||||
}(resp.Body)
|
||||
|
||||
// Write the body to file
|
||||
_, err = io.Copy(out, resp.Body)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue