Add depot, attendant, jetfire, optimus, ota services with kustomize overlays

This commit is contained in:
Chris Rai
2026-01-31 15:35:07 -05:00
parent a0ec642ca1
commit 9a5cb2f547
404 changed files with 38817 additions and 16 deletions

View File

@@ -0,0 +1,46 @@
package utils
import (
"strings"
"github.com/fiskerinc/cloud-services/pkg/utils/envtool"
az "github.com/Azure/azure-storage-blob-go/azblob"
"github.com/pkg/errors"
)
type Direction int
const (
Up Direction = iota
Down
)
var (
cursorDirection = map[string]Direction{
"up": Up,
"down": Down,
}
)
func ParseCursorDirection(str string) (Direction, bool) {
c, ok := cursorDirection[strings.ToLower(str)]
return c, ok
}
var (
AzureAccount = envtool.GetEnv("AZURE_STORAGE_ACCOUNT", "REPLACE_ME")
AzureAccountKey = envtool.GetEnv("AZURE_STORAGE_ACCESS_KEY", "REPLACE_ME")
AzureTRexLogsContainerName = envtool.GetEnv("AZURE_TREX_LOGS_STORAGE_CONTAINER_NAME", "trex-logs")
ReadFileName = "raw.log"
AzureLogsBlobPath = "https://%s.blob.core.windows.net/%s"
)
func AzureStorageCredential() (*az.SharedKeyCredential, error) {
cred, err := az.NewSharedKeyCredential(AzureAccount, AzureAccountKey)
if err != nil {
return nil, errors.WithStack(err)
}
return cred, nil
}

View File

@@ -0,0 +1,104 @@
package utils
import (
"otaupdate/services"
"github.com/fiskerinc/cloud-services/pkg/common"
"github.com/fiskerinc/cloud-services/pkg/security"
"github.com/fiskerinc/cloud-services/pkg/utils/randomvalues"
)
type FileEncryptor struct {
FileID string
encrypter security.IEncryptor
streamer security.IEncryptedStream
fileKey *common.FileKey
}
func NewEncryptor() (*FileEncryptor, error) {
instance := FileEncryptor{}
err := instance.init()
return &instance, err
}
func (fe *FileEncryptor) SaveFileKey()(err error){
err = fe.saveData(fe.fileKey)
return
}
func (fe *FileEncryptor) init() error {
filekey, err := fe.getKey()
if err != nil {
return err
}
fe.fileKey = filekey
/* err = fe.saveData(filekey)
if err != nil {
return err
} */
encrypter, _, err := security.NewEncryptor(filekey.Key, filekey.Auth, filekey.Nonce)
if err != nil {
return err
}
streamer, err := security.NewEncryptedStream(encrypter, security.WithUniqueId([]byte(filekey.FileID)))
if err != nil {
return err
}
fe.FileID = filekey.FileID
fe.encrypter = encrypter
fe.streamer = streamer
return nil
}
func (fe *FileEncryptor) saveData(filekey *common.FileKey) error {
_, err := services.GetDB().GetFileKeys().Insert(*filekey)
return err
}
func (fe *FileEncryptor) getKey() (*common.FileKey, error) {
var err error
generator := randomvalues.NewGenerator("")
filekey := common.FileKey{}
filekey.FileID, err = generator.GetUniformDistHex()
if err != nil {
return nil, err
}
value, err := generator.GetBytes(32)
if err != nil {
return nil, err
}
filekey.Key = value
value, err = generator.GetBytes(16)
if err != nil {
return nil, err
}
filekey.Auth = value
value, err = generator.GetBytes(12)
if err != nil {
return nil, err
}
filekey.Nonce = value
return &filekey, nil
}
func (fe *FileEncryptor) Encrypt(input []byte) []byte {
return fe.streamer.Write(input)
}
func (fe *FileEncryptor) Close() {
fe.FileID = ""
fe.encrypter.Close()
fe.encrypter = nil
fe.streamer = nil
}

View File

@@ -0,0 +1,73 @@
package utils
import (
"mime/multipart"
"strconv"
"strings"
"github.com/fiskerinc/cloud-services/pkg/common"
"github.com/fiskerinc/cloud-services/pkg/utils"
)
// GetUpdatePackgeFormParser returns form parser function to parse FormData
func GetUpdateManifestFileFormParser() (utils.FormParser, *common.UpdateManifestFile) {
data := common.UpdateManifestFile{
WriteRegion: common.MemoryRegion{
Length: 1, // Set to non-zero to pass init validation, actual value will be set and checked later
},
}
return func(part *multipart.Part) error {
var err error
switch part.FormName() {
case "manifest_ecu_id":
data.UpdateManifestECUID, err = utils.PartReadInt64(part, 2048, 64)
case "url":
data.URL, err = utils.PartReadAll(part, 500)
case "offset":
data.WriteRegion.Offset, err = utils.PartReadUInt64(part, 255, 64)
case "checksum":
data.Checksum, err = utils.PartReadAll(part, 32)
case "order":
data.FileOrder, err = utils.PartReadInt(part, 255)
case "signature":
data.Signature, err = utils.PartReadAll(part, 129)
case "type":
value, err := utils.PartReadAll(part, 255)
if err != nil {
return err
}
data.FileType = convertFileType(value)
case "parsed_file":
stringBool, err := utils.PartReadAll(part, 32)
if err != nil {
return err
}
aBool, err := strconv.ParseBool(stringBool)
if err != nil {
return err
}
data.Parsed = &aBool
}
return err
}, &data
}
func convertFileType(filetype string) common.ManifestFileType {
value := strings.ToLower(filetype)
if strings.Contains(value, string(common.Bootloader)) {
return common.Bootloader
}
if strings.Contains(value, string(common.Software)) || strings.Contains(value, "sw") {
return common.Software
}
if strings.Contains(value, string(common.Calibration)) {
return common.Calibration
}
return common.Other
}

View File

@@ -0,0 +1,62 @@
package utils
import (
"context"
"fmt"
"io"
"net/url"
"github.com/fiskerinc/cloud-services/pkg/remotefileupload"
"github.com/Azure/azure-storage-blob-go/azblob"
"github.com/pkg/errors"
)
func ReadAzureBlob(azureContainer string, vin string, year, month, day int, offset, count int64, readDirection Direction) ([]byte, int64, error) {
creds, err := AzureStorageCredential()
if err != nil {
return nil, -1, err
}
link, err := remotefileupload.AzureFilePathLink(AzureAccount, azureContainer, vin, fmt.Sprintf("%04d", year), fmt.Sprintf("%02d", month), fmt.Sprintf("%02d", day), ReadFileName)
if err != nil {
return nil, 0, err
}
u, err := url.Parse(link)
if err != nil {
return nil, -1, errors.WithStack(err)
}
url := azblob.NewBlobURL(*u, azblob.NewPipeline(creds, azblob.PipelineOptions{Retry: azblob.RetryOptions{MaxTries: 100}}))
prop, err := url.GetProperties(context.Background(), azblob.BlobAccessConditions{}, azblob.ClientProvidedKeyOptions{})
if err != nil {
return nil, -1, err
}
if offset >= prop.ContentLength() {
return nil, -1, errors.New("offset out of range")
}
//count from the end of the blob
readOffset := prop.ContentLength() - offset
begin := readOffset
if readDirection == Up {
begin -= count
}
//just read the rest
if begin <= 0 {
begin = 0
count = readOffset
}
if count == 0 {
count = azblob.CountToEnd
}
reader, err := url.Download(context.Background(), begin, count,
azblob.BlobAccessConditions{}, false, azblob.ClientProvidedKeyOptions{})
if err != nil {
return nil, -1, err
}
buf := make([]byte, reader.ContentLength())
_, err = io.ReadAtLeast(reader.Body(azblob.RetryReaderOptions{}), buf, len(buf))
return buf, prop.ContentLength(), err
}