Add depot, attendant, jetfire, optimus, ota services with kustomize overlays
This commit is contained in:
46
services/ota_update_go/utils/constants.go
Normal file
46
services/ota_update_go/utils/constants.go
Normal 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
|
||||
}
|
||||
104
services/ota_update_go/utils/fileencryptor.go
Normal file
104
services/ota_update_go/utils/fileencryptor.go
Normal 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
|
||||
}
|
||||
73
services/ota_update_go/utils/formparser.go
Normal file
73
services/ota_update_go/utils/formparser.go
Normal 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
|
||||
}
|
||||
62
services/ota_update_go/utils/reader.go
Normal file
62
services/ota_update_go/utils/reader.go
Normal 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
|
||||
}
|
||||
Reference in New Issue
Block a user