blob: 145cad7dd7799cb1c0498d0850248bfaa9332e12 [file] [log] [blame]
// Copyright 2020 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package util
import (
"context"
"fmt"
"regexp"
"strings"
"github.com/golang/protobuf/proto"
descriptorpb "github.com/golang/protobuf/protoc-gen-go/descriptor"
"google.golang.org/genproto/googleapis/api/annotations"
"google.golang.org/grpc/metadata"
"google.golang.org/protobuf/reflect/protoreflect"
"go.chromium.org/luci/common/errors"
"go.chromium.org/luci/gae/service/info"
ufspb "infra/unifiedfleet/api/v1/models"
chromeosLab "infra/unifiedfleet/api/v1/models/chromeos/lab"
ufsmfg "infra/unifiedfleet/api/v1/models/chromeos/manufacturing"
)
const (
// AssetCollection refers to the prefix of the corresponding resource.
AssetCollection string = "assets"
// MachineCollection refers to the prefix of the corresponding resource.
MachineCollection string = "machines"
// RackCollection refers to the prefix of the corresponding resource.
RackCollection string = "racks"
// VMCollection refers to the prefix of the corresponding resource.
VMCollection string = "vms"
// ChromePlatformCollection refers to the prefix of the corresponding resource.
ChromePlatformCollection string = "chromeplatforms"
// MachineLSECollection refers to the prefix of the corresponding resource.
MachineLSECollection string = "machineLSEs"
// MachineLSEDeploymentCollection refers to the prefix of the corresponding resource.
MachineLSEDeploymentCollection string = "machineLSEDeployments"
// HostCollection refers to the prefix of the corresponding resource.
HostCollection string = "hosts"
// RackLSECollection refers to the prefix of the corresponding resource.
RackLSECollection string = "rackLSEs"
// NicCollection refers to the prefix of the corresponding resource.
NicCollection string = "nics"
// KVMCollection refers to the prefix of the corresponding resource.
KVMCollection string = "kvms"
// RPMCollection refers to the prefix of the corresponding resource.
RPMCollection string = "rpms"
// DracCollection refers to the prefix of the corresponding resource.
DracCollection string = "dracs"
// SwitchCollection refers to the prefix of the corresponding resource.
SwitchCollection string = "switches"
// VlanCollection refers to the prefix of the corresponding resource.
VlanCollection string = "vlans"
// MachineLSEPrototypeCollection refers to the prefix of the corresponding resource.
MachineLSEPrototypeCollection string = "machineLSEPrototypes"
// RackLSEPrototypeCollection refers to the prefix of the corresponding resource.
RackLSEPrototypeCollection string = "rackLSEPrototypes"
// DHCPCollection refers to the prefix of the dhcp config id in change history
DHCPCollection string = "dhcps"
// IPCollection refers to the prefix of the ip id in change history
IPCollection string = "ips"
// StateCollection refers to the prefix of the states id in change history
StateCollection string = "states"
// CachingServiceCollection refers to the prefix of the CachingService.
CachingServiceCollection string = "cachingservices"
// DutStateCollection refers to the prefix of the DutStates id in change history
DutStateCollection string = "dutstates"
// SchedulingUnitCollection refers to the prefix of the SchedulingUnit.
SchedulingUnitCollection string = "schedulingunits"
// DefaultWifiCollection refers to the prefix of the DefaultWifi.
DefaultWifiCollection string = "defaultwifis"
defaultPageSize int32 = 100
// MaxPageSize maximum page size for list operations
MaxPageSize int32 = 1000
// NoHostPrefix is the prefix string for generating a fake non-existing hostname
NoHostPrefix string = "no-host-yet-"
)
var collectionsRe = regexp.MustCompile(`\/{[a-zA-Z0-9]*}$`)
// Filter names for indexed properties in datastore for different entities
var (
ZoneFilterName string = "zone"
ZonesFilterName string = "zones"
RackFilterName string = "rack"
MachineFilterName string = "machine"
HostFilterName string = "host"
NicFilterName string = "nic"
DracFilterName string = "drac"
KVMFilterName string = "kvm"
KVMPortFilterName string = "kvmport"
MacAddressFilterName string = "mac"
RPMFilterName string = "rpm"
RPMPortFilterName string = "rpmport"
SwitchFilterName string = "switch"
SwitchPortFilterName string = "switchport"
ServoFilterName string = "servo"
ServoTypeFilterName string = "servotype"
TagFilterName string = "tag"
ChromePlatformFilterName string = "platform"
MachinePrototypeFilterName string = "machineprototype"
RackPrototypeFilterName string = "rackprototype"
VlanFilterName string = "vlan"
StateFilterName string = "state"
IPV4FilterName string = "ipv4"
IPV4StringFilterName string = "ipv4str"
OccupiedFilterName string = "occupied"
ManufacturerFilterName string = "man"
FreeVMFilterName string = "free"
ResourceTypeFilterName string = "resourcetype"
OSVersionFilterName string = "osversion"
OSFilterName string = "os"
VirtualDatacenterFilterName string = "vdc"
ModelFilterName string = "model"
BuildTargetFilterName string = "target"
BoardFilterName string = "board"
DeviceTypeFilterName string = "devicetype"
PhaseFilterName string = "phase"
AssetTypeFilterName string = "assettype"
SubnetsFilterName string = "subnets"
PoolsFilterName string = "pools"
DeploymentIdentifierFilterName string = "deploymentidentifier"
DeploymentEnvFilterName string = "deploymentenv"
MachineLSEsFilterName string = "duts"
TypeFilterName string = "type"
SerialNumberFilterName string = "serialnumber"
BbnumFilterName string = "bbnum"
AssetTagFilterName string = "assettag"
CpuCoresFilterName string = "cpucores"
MemoryFilterName string = "memory"
StorageFilterName string = "storage"
LogicalZoneFilterName string = "logicalzone"
GPNFilterName string = "gpn"
AssetType string = "assettype"
CommittishFilterName string = "commitsh"
HiveFilterName string = "hive"
)
const separator string = "/"
// Namespace namespace to be set by clients in context metadata
// This will be used to set the actual datastore namespace in the context
var (
// OSNamespace os namespace to be set in client context metadata. OS data is stored in os namespace in the datastore.
OSNamespace = "os"
// BrowserNamespace browser namespace to be set in client context metadata. Browser data is stored in default namespace in the datastore.
BrowserNamespace = "browser"
// OSPartnerNamespace partner namespace to be set in client context metadata. Partner data is stored in partner namespace in the datastore.
// This is expected to hold and be accessible to non-Google entities (subject to RPC and zone ACLs) working on ChromeOS.
OSPartnerNamespace = "os-partner"
// Namespace key in the incoming context metadata
Namespace = "namespace"
)
// ClientToDatastoreNamespace refers a map between client namespace(set in context metadata) to actual datastore namespace
var ClientToDatastoreNamespace = map[string]string{
BrowserNamespace: "", // browser data is stored in default namespace
OSNamespace: OSNamespace, // os data in os namespace
OSPartnerNamespace: OSPartnerNamespace, // os partner data is in os partner namespace
}
// ValidClientNamespaceStr returns a valid str list for client namespace(set in incoming context metadata) strings.
func ValidClientNamespaceStr() []string {
ks := make([]string, 0, len(ClientToDatastoreNamespace))
for k := range ClientToDatastoreNamespace {
ks = append(ks, k)
}
return ks
}
// IsClientNamespace checks if a string refers to a valid client namespace.
func IsClientNamespace(namespace string) bool {
_, ok := ClientToDatastoreNamespace[namespace]
return ok
}
// SetupDatastoreNamespace sets the datastore namespace in the context to access the correct namespace in the datastore
func SetupDatastoreNamespace(ctx context.Context, namespace string) (context.Context, error) {
return info.Namespace(ctx, namespace)
}
// GetDatastoreNamespace returns the namespace used in context
func GetDatastoreNamespace(ctx context.Context) string {
return info.GetNamespace(ctx)
}
// GetIncomingCtxNamespace parses namespace in incoming context passed to UFS
//
// The user must explicitly specify a recognized namespace string
// for the corresponding namespace to be returned.
// An empty or unrecognized string will cause namespace=BrowserNamespace.
func GetIncomingCtxNamespace(ctx context.Context) string {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return BrowserNamespace
}
namespace, ok := md[Namespace]
if !ok {
return BrowserNamespace
}
return namespace[0]
}
// GetNamespaceFromCtx parses namespace from ctx, either a normal context
// or an incoming context.
func GetNamespaceFromCtx(ctx context.Context) string {
outNs := GetIncomingCtxNamespace(ctx)
datastoreNs := GetDatastoreNamespace(ctx)
switch {
case outNs == OSNamespace || datastoreNs == OSNamespace:
return OSNamespace
case outNs == OSPartnerNamespace || datastoreNs == OSPartnerNamespace:
return OSPartnerNamespace
default:
return BrowserNamespace
}
}
// GetPageSize gets the correct page size for List pagination
func GetPageSize(pageSize int32) int32 {
switch {
case pageSize == 0:
return defaultPageSize
case pageSize > MaxPageSize:
return MaxPageSize
default:
return pageSize
}
}
// GetResourcePrefix gets the resource prefix given to the proto message.
//
// Returns the resource prefix for a given proto message.
// See also: https://blog.golang.org/protobuf-apiv2
func GetResourcePrefix(message proto.Message) (string, error) {
m := proto.MessageReflect(message)
x, ok := m.Descriptor().Options().(*descriptorpb.MessageOptions)
if !ok {
return "", errors.Reason("Unable to read Message Options").Err()
}
y, _ := proto.GetExtension(x, annotations.E_Resource)
z, ok := y.(*annotations.ResourceDescriptor)
if !ok {
return "", errors.Reason("Resource descriptor not found in proto message").Err()
}
prefix := collectionsRe.ReplaceAllString(z.Pattern[0], "")
return prefix, nil
}
// FormatInputNames formats a given array of resource names
func FormatInputNames(names []string) []string {
var res []string
for _, n := range names {
if n != "" {
res = append(res, RemovePrefix(n))
}
}
return res
}
// FormatDHCPHostname formats a name which will be a dhcp host
func FormatDHCPHostname(old string) string {
return strings.ToLower(old)
}
// FormatDHCPHostnames formats a given array of resource names which could be used as dhcp hostnames
func FormatDHCPHostnames(names []string) []string {
for i, n := range names {
names[i] = FormatDHCPHostname(n)
}
return names
}
// FormatDeploymentRecord initialize a MachineLSE deployment record object by hostname and given serial number.
func FormatDeploymentRecord(hostname, serialNumber string) *ufspb.MachineLSEDeployment {
if hostname == "" {
hostname = GetHostnameWithNoHostPrefix(serialNumber)
}
return &ufspb.MachineLSEDeployment{
Hostname: hostname,
SerialNumber: serialNumber,
DeploymentIdentifier: "",
ConfigsToPush: nil,
}
}
// GetHostnameWithNoHostPrefix generates a hostname with NoHostPrefix.
func GetHostnameWithNoHostPrefix(suffix string) string {
return fmt.Sprintf("%s%s", NoHostPrefix, suffix)
}
// RemovePrefix extracts string appearing after a "/"
func RemovePrefix(name string) string {
// Get substring after a string.
name = strings.TrimSpace(name)
pos := strings.Index(name, separator)
if pos == -1 {
return name
}
adjustedPos := pos + len(separator)
if adjustedPos >= len(name) {
return name
}
return name[adjustedPos:]
}
// AddPrefix adds the prefix for a given resource name
func AddPrefix(collection, entity string) string {
return fmt.Sprintf("%s%s%s", collection, separator, entity)
}
// GetPrefix returns the prefix for a resource name
func GetPrefix(resourceName string) string {
s := strings.Split(strings.TrimSpace(resourceName), separator)
if len(s) < 1 {
return ""
}
return s[0]
}
// GetRackHostname returns a rack host name.
func GetRackHostname(rackName string) string {
return fmt.Sprintf("%s-host", rackName)
}
// FormatResourceName formats the resource name
func FormatResourceName(old string) string {
str := strings.Replace(old, " ", "_", -1)
return strings.Replace(str, ",", "_", -1)
}
// StrToUFSState refers a map between a string to a UFS defined state map.
var StrToUFSState = map[string]string{
"registered": "STATE_REGISTERED",
"deployed_pre_serving": "STATE_DEPLOYED_PRE_SERVING",
"deployed_testing": "STATE_DEPLOYED_TESTING",
"serving": "STATE_SERVING",
"needs_reset": "STATE_NEEDS_RESET",
"needs_repair": "STATE_NEEDS_REPAIR",
"repair_failed": "STATE_REPAIR_FAILED",
"disabled": "STATE_DISABLED",
"reserved": "STATE_RESERVED",
"decommissioned": "STATE_DECOMMISSIONED",
"deploying": "STATE_DEPLOYING",
"ready": "STATE_READY",
"build": "STATE_BUILD",
"missing": "STATE_MISSING",
}
// StateToDescription refers a map between a State to its description.
var StateToDescription = map[string]string{
"registered": "Needs deploy",
"deployed_pre_serving": "Deployed but not placed in prod",
"deployed_testing": "Deployed to the prod, but for testing",
"serving": "Deployed to the prod, serving",
"needs_reset": "Deployed to the prod, but required cleanup and verify",
"needs_repair": "Deployed to the prod, needs repair",
"repair_failed": "Deployed to the prod, failed to be repaired in previous step and requires new repair attempt",
"disabled": "Deployed to the prod, but disabled",
"reserved": "Deployed to the prod, but reserved (e.g. locked)",
"decommissioned": "Decommissioned from the prod, but still lives in UFS record",
"deploying": "Deploying the resource with required configs just before it is READY",
"ready": "Resource is ready for use or free to use",
"build": "Resource is in the process of being built out or assembled",
"missing": "Resource is not detected and has gone missing",
}
// IsUFSState checks if a string refers to a valid UFS state.
func IsUFSState(state string) bool {
_, ok := StrToUFSState[state]
return ok
}
// ValidStateStr returns a valid str list for state strings.
func ValidStateStr() []string {
ks := make([]string, 0, len(StrToUFSState))
for k := range StrToUFSState {
ks = append(ks, k)
}
return ks
}
// RemoveStatePrefix removes the "state_" prefix from the string
func RemoveStatePrefix(state string) string {
state = strings.ToLower(state)
if idx := strings.Index(state, "state_"); idx != -1 {
state = state[idx+len("state_"):]
}
return state
}
// ToUFSState converts state string to a UFS state enum.
func ToUFSState(state string) ufspb.State {
state = RemoveStatePrefix(state)
v, ok := StrToUFSState[state]
if !ok {
return ufspb.State_STATE_UNSPECIFIED
}
return ufspb.State(ufspb.State_value[v])
}
// StrToUFSZone refers a map between a string to a UFS defined map.
var StrToUFSZone = genStrToUFSZone()
func genStrToUFSZone() map[string]string {
res := make(map[string]string, len(ufspb.Zone_name))
for _, value := range ufspb.Zone_name {
// Generate the mapping by removing the prefix and converting text to lower case.
res[strings.ToLower(strings.TrimPrefix(value, "ZONE_"))] = value
}
return res
}
// IsUFSZone checks if a string refers to a valid UFS zone.
func IsUFSZone(zone string) bool {
_, ok := StrToUFSZone[zone]
return ok
}
// IsAssetType checks if a strings is a valid asset type
func IsAssetType(assetType string) bool {
for _, x := range ValidAssetTypeStr() {
if x == assetType {
return true
}
}
return false
}
// ToAssetType returns an AssetType object corresponding to string
func ToAssetType(assetType string) ufspb.AssetType {
aType := RemoveGivenPrefix(assetType, "assettype_")
for k, v := range ufspb.AssetType_value {
if strings.EqualFold(k, aType) {
return ufspb.AssetType(v)
}
}
return ufspb.AssetType_UNDEFINED
}
// ValidAssetTypeStr returns a valid str list for AssetTypes
func ValidAssetTypeStr() []string {
keys := make([]string, 0, len(ufspb.AssetType_name))
for k, v := range ufspb.AssetType_name {
// 0 is UNDEFINED
if k != 0 {
keys = append(keys, strings.ToLower(v))
}
}
return keys
}
// StrToLogicalZone refers a map between a string to a LogicalZone map.
var StrToLogicalZone = map[string]string{
"unspecified": "LOGICAL_ZONE_UNSPECIFIED",
"drillzone_sfo36": "LOGICAL_ZONE_DRILLZONE_SFO36",
}
// IsLogicalZone checks if a string is a valid logical zone
func IsLogicalZone(logicalZone string) bool {
_, ok := StrToLogicalZone[logicalZone]
return ok
}
// ToLogicalZone returns an LogicalZone object corresponding to string
func ToLogicalZone(logicalZone string) ufspb.LogicalZone {
logicalZone = RemoveGivenPrefix(logicalZone, "logical_zone_")
v, ok := StrToLogicalZone[logicalZone]
if !ok {
return ufspb.LogicalZone_LOGICAL_ZONE_UNSPECIFIED
}
return ufspb.LogicalZone(ufspb.LogicalZone_value[v])
}
// ValidLogicalZoneStr returns a valid str list for LogicalZone
func ValidLogicalZoneStr() []string {
ks := make([]string, 0, len(StrToLogicalZone))
for k := range StrToLogicalZone {
ks = append(ks, k)
}
return ks
}
// ValidDeploymentEnvStr returns a valid str list for DeploymentEnv
func ValidDeploymentEnvStr() []string {
keys := make([]string, 0, len(ufspb.DeploymentEnv_name))
for k, v := range ufspb.DeploymentEnv_name {
// 0 is UNDEFINED
if k != 0 {
keys = append(keys, strings.ToLower(v))
}
}
return keys
}
// ToUFSDeploymentEnv converts string to a UFS DeploymentEnv enum.
func ToUFSDeploymentEnv(env string) ufspb.DeploymentEnv {
v, ok := ufspb.DeploymentEnv_value[strings.ToUpper(env)]
if !ok {
return ufspb.DeploymentEnv_DEPLOYMENTENV_UNDEFINED
}
return ufspb.DeploymentEnv(v)
}
// ValidZoneStr returns a valid str list for zone strings.
func ValidZoneStr() []string {
ks := make([]string, 0, len(StrToUFSZone))
for k := range StrToUFSZone {
ks = append(ks, k)
}
return ks
}
// RemoveZonePrefix removes the "zone_" prefix from the string
func RemoveZonePrefix(zone string) string {
zone = strings.ToLower(zone)
if idx := strings.Index(zone, "zone_"); idx != -1 {
zone = zone[idx+len("zone_"):]
}
return zone
}
// ToUFSZone converts zone string to a UFS zone enum.
func ToUFSZone(zone string) ufspb.Zone {
zone = RemoveZonePrefix(zone)
v, ok := StrToUFSZone[zone]
if !ok {
return ufspb.Zone_ZONE_UNSPECIFIED
}
return ufspb.Zone(ufspb.Zone_value[v])
}
// StrToUFSDeviceType refers a map between a string to a UFS defined map.
var StrToUFSDeviceType = map[string]string{
"chromebook": "DEVICE_CHROMEBOOK",
"labstation": "DEVICE_LABSTATION",
"servo": "DEVICE_SERVO",
"unspecified": "CHROME_OS_DEVICE_TYPE_UNSPECIFIED",
}
// ValidDeviceTypeStr returns a valid str list for devicetype strings.
func ValidDeviceTypeStr() []string {
ks := make([]string, 0, len(StrToUFSDeviceType))
for k := range StrToUFSDeviceType {
ks = append(ks, k)
}
return ks
}
// RemoveGivenPrefix removes the prefix from the string
func RemoveGivenPrefix(msg, prefix string) string {
msg = strings.ToLower(msg)
if idx := strings.Index(msg, prefix); idx != -1 {
msg = msg[idx+len(prefix):]
}
return msg
}
// ToUFSDeviceType converts devicetype string to a UFS devicetype enum.
func ToUFSDeviceType(devicetype string) ufspb.ChromeOSDeviceType {
devicetype = RemoveGivenPrefix(devicetype, "device_")
v, ok := StrToUFSDeviceType[devicetype]
if !ok {
return ufspb.ChromeOSDeviceType_CHROME_OS_DEVICE_TYPE_UNSPECIFIED
}
return ufspb.ChromeOSDeviceType(ufspb.ChromeOSDeviceType_value[v])
}
// StrToChameleonType refers a map between a string to a ChameleonType map.
var StrToChameleonType = map[string]string{
"invalid": "CHAMELEON_TYPE_INVALID",
"dp": "CHAMELEON_TYPE_DP",
"hdmi": "CHAMELEON_TYPE_HDMI",
}
// IsChameleonType checks if a string refers to a valid ChameleonType.
func IsChameleonType(chameleonType string) bool {
_, ok := StrToChameleonType[chameleonType]
return ok
}
// ValidChameleonTypeStr returns a valid str list for Chameleontype strings.
func ValidChameleonTypeStr() []string {
ks := make([]string, 0, len(StrToChameleonType))
for k := range StrToChameleonType {
ks = append(ks, k)
}
return ks
}
// ToChameleonType converts devicetype string to a Chameleon type enum.
func ToChameleonType(chameleonType string) chromeosLab.ChameleonType {
chameleonType = RemoveGivenPrefix(chameleonType, "chameleon_type_")
v, ok := StrToChameleonType[chameleonType]
if !ok {
return chromeosLab.ChameleonType_CHAMELEON_TYPE_INVALID
}
return chromeosLab.ChameleonType(chromeosLab.ChameleonType_value[v])
}
// StrToCameraType refers a map between a string to a CameraType map.
var StrToCameraType = map[string]string{
"invalid": "CAMERA_INVALID",
"huddly": "CAMERA_HUDDLY",
"ptzpro2": "CAMERA_PTZPRO2",
}
// IsCameraType checks if a string refers to a valid CameraType.
func IsCameraType(cameraType string) bool {
_, ok := StrToCameraType[cameraType]
return ok
}
// ValidCameraTypeStr returns a valid str list for CameraType strings.
func ValidCameraTypeStr() []string {
ks := make([]string, 0, len(StrToCameraType))
for k := range StrToCameraType {
ks = append(ks, k)
}
return ks
}
// ToCameraType converts cameraType string to a Camera type enum.
func ToCameraType(cameraType string) chromeosLab.CameraType {
cameraType = RemoveGivenPrefix(cameraType, "camera_")
v, ok := StrToCameraType[cameraType]
if !ok {
return chromeosLab.CameraType_CAMERA_INVALID
}
return chromeosLab.CameraType(chromeosLab.CameraType_value[v])
}
// StrToAntennaConnection refers a map between a string to a AntennaConnection map.
var StrToAntennaConnection = map[string]string{
"unknown": "CONN_UNKNOWN",
"conductive": "CONN_CONDUCTIVE",
"ota": "CONN_OTA",
}
// IsAntennaConnection checks if a string refers to a valid AntennaConnection.
func IsAntennaConnection(antennaConnection string) bool {
_, ok := StrToAntennaConnection[antennaConnection]
return ok
}
// ValidAntennaConnectionStr returns a valid str list for AntennaConnection strings.
func ValidAntennaConnectionStr() []string {
ks := make([]string, 0, len(StrToAntennaConnection))
for k := range StrToAntennaConnection {
ks = append(ks, k)
}
return ks
}
// ToAntennaConnection converts antennaConnection string to a Wifi_AntennaConnection enum.
func ToAntennaConnection(antennaConnection string) chromeosLab.Wifi_AntennaConnection {
antennaConnection = RemoveGivenPrefix(antennaConnection, "conn_")
v, ok := StrToAntennaConnection[antennaConnection]
if !ok {
return chromeosLab.Wifi_CONN_UNKNOWN
}
return chromeosLab.Wifi_AntennaConnection(chromeosLab.Wifi_AntennaConnection_value[v])
}
// StrToRouter refers a map between a string to a Router map.
var StrToRouter = map[string]string{
"unspecified": "ROUTER_UNSPECIFIED",
"80211ax": "ROUTER_802_11AX",
}
// IsRouter checks if a string refers to a valid Router.
func IsRouter(router string) bool {
_, ok := StrToRouter[router]
return ok
}
// ValidRouterStr returns a valid str list for Router strings.
func ValidRouterStr() []string {
ks := make([]string, 0, len(StrToRouter))
for k := range StrToRouter {
ks = append(ks, k)
}
return ks
}
// ToRouter converts router string to a Wifi_Router enum.
func ToRouter(router string) chromeosLab.Wifi_Router {
router = RemoveGivenPrefix(router, "router_")
v, ok := StrToRouter[router]
if !ok {
return chromeosLab.Wifi_ROUTER_UNSPECIFIED
}
return chromeosLab.Wifi_Router(chromeosLab.Wifi_Router_value[v])
}
// StrToCableType refers a map between a string to a CableType map.
var StrToCableType = map[string]string{
"invalid": "CABLE_INVALID",
"audiojack": "CABLE_AUDIOJACK",
"usbaudio": "CABLE_USBAUDIO",
"usbprinting": "CABLE_USBPRINTING",
"hdmiaudio": "CABLE_HDMIAUDIO",
}
// IsCableType checks if a string refers to a valid CableType.
func IsCableType(cableType string) bool {
_, ok := StrToCableType[cableType]
return ok
}
// ValidCableTypeStr returns a valid str list for CableType strings.
func ValidCableTypeStr() []string {
ks := make([]string, 0, len(StrToCableType))
for k := range StrToCableType {
ks = append(ks, k)
}
return ks
}
// ToCableType converts cableType string to a Cable type enum.
func ToCableType(cableType string) chromeosLab.CableType {
cableType = RemoveGivenPrefix(cableType, "cable_")
v, ok := StrToCableType[cableType]
if !ok {
return chromeosLab.CableType_CABLE_INVALID
}
return chromeosLab.CableType(chromeosLab.CableType_value[v])
}
// StrToFacing refers a map between a string to a Facing map.
var StrToFacing = map[string]string{
"unknown": "FACING_UNKNOWN",
"back": "FACING_BACK",
"front": "FACING_FRONT",
"nocamera": "FACING_NOCAMERA",
}
// IsFacing checks if a string refers to a valid Facing.
func IsFacing(facing string) bool {
_, ok := StrToFacing[facing]
return ok
}
// ValidFacingStr returns a valid str list for Facing strings.
func ValidFacingStr() []string {
ks := make([]string, 0, len(StrToFacing))
for k := range StrToFacing {
ks = append(ks, k)
}
return ks
}
// ToFacing converts facing string to a Camerabox_Facing enum.
func ToFacing(facing string) chromeosLab.Camerabox_Facing {
facing = RemoveGivenPrefix(facing, "facing_")
v, ok := StrToFacing[facing]
if !ok {
return chromeosLab.Camerabox_FACING_UNKNOWN
}
return chromeosLab.Camerabox_Facing(chromeosLab.Camerabox_Facing_value[v])
}
// StrToLight refers a map between a string to a Light map.
var StrToLight = map[string]string{
"unknown": "LIGHT_UNKNOWN",
"led": "LIGHT_LED",
"noled": "LIGHT_NOLED",
}
// IsLight checks if a string refers to a valid Light.
func IsLight(light string) bool {
_, ok := StrToLight[light]
return ok
}
// ValidLightStr returns a valid str list for Light strings.
func ValidLightStr() []string {
ks := make([]string, 0, len(StrToLight))
for k := range StrToLight {
ks = append(ks, k)
}
return ks
}
// ToLight converts light string to a Camerabox_Light enum.
func ToLight(light string) chromeosLab.Camerabox_Light {
light = RemoveGivenPrefix(light, "light_")
v, ok := StrToLight[light]
if !ok {
return chromeosLab.Camerabox_LIGHT_UNKNOWN
}
return chromeosLab.Camerabox_Light(chromeosLab.Camerabox_Light_value[v])
}
// StrToLicenseType refers a map between a string to a LicenseType map.
var StrToLicenseType = map[string]string{
"invalid": "LICENSE_TYPE_UNSPECIFIED",
"windows10pro": "LICENSE_TYPE_WINDOWS_10_PRO",
"msofficestd": "LICENSE_TYPE_MS_OFFICE_STANDARD",
}
// IsLicenseType checks if a string refers to a valid LicenseType.
func IsLicenseType(licenseType string) bool {
_, ok := StrToLicenseType[licenseType]
return ok
}
// ValidLicenseTypeStr returns a valid str list for LicenseType strings.
func ValidLicenseTypeStr() []string {
ks := make([]string, 0, len(StrToLicenseType))
for k := range StrToLicenseType {
ks = append(ks, k)
}
return ks
}
// ToLicenseType converts licenseType string to a License type enum.
func ToLicenseType(licenseType string) chromeosLab.LicenseType {
licenseType = RemoveGivenPrefix(licenseType, "license_")
v, ok := StrToLicenseType[licenseType]
if !ok {
return chromeosLab.LicenseType_LICENSE_TYPE_UNSPECIFIED
}
return chromeosLab.LicenseType(chromeosLab.LicenseType_value[v])
}
// StrToSchedulingUnitType refers a map between a string to a UFS defined map.
var StrToSchedulingUnitType = map[string]string{
"invalid": "SCHEDULING_UNIT_TYPE_INVALID",
"all": "SCHEDULING_UNIT_TYPE_ALL",
"individual": "SCHEDULING_UNIT_TYPE_INDIVIDUAL",
}
// ValidSchedulingUnitTypeStr returns a valid str list for SchedulingUnitType strings.
func ValidSchedulingUnitTypeStr() []string {
ks := make([]string, 0, len(StrToSchedulingUnitType))
for k := range StrToSchedulingUnitType {
ks = append(ks, k)
}
return ks
}
// IsSchedulingUnitType checks if a string refers to a valid SchedulingUnitType.
func IsSchedulingUnitType(schedulingUnitType string) bool {
_, ok := StrToSchedulingUnitType[schedulingUnitType]
return ok
}
// ToSchedulingUnitType converts SchedulingUnitType string to a UFS SchedulingUnitType enum.
func ToSchedulingUnitType(schedulingUnitType string) ufspb.SchedulingUnitType {
schedulingUnitType = RemoveGivenPrefix(schedulingUnitType, "scheduling_unit_type_")
v, ok := StrToSchedulingUnitType[schedulingUnitType]
if !ok {
return ufspb.SchedulingUnitType_SCHEDULING_UNIT_TYPE_INVALID
}
return ufspb.SchedulingUnitType(ufspb.SchedulingUnitType_value[v])
}
// StrToSchedulingUnitExposeType refers a map between a string to a UFS defined map.
var StrToSchedulingUnitExposeType = map[string]string{
"default": "DEFAULT",
"default_plus_primary": "DEFAULT_PLUS_PRIMARY",
"strictly_primary_only": "STRICTLY_PRIMARY_ONLY",
}
// ValidSchedulingUnitExposeTypeStr returns a valid str list for SchedulingUnit_ExposeType strings.
func ValidSchedulingUnitExposeTypeStr() []string {
ks := make([]string, 0, len(StrToSchedulingUnitExposeType))
for k := range StrToSchedulingUnitExposeType {
ks = append(ks, k)
}
return ks
}
// IsSchedulingUnitExposeType checks if a string refers to a valid SchedulingUnit_ExposeType.
func IsSchedulingUnitExposeType(schedulingUnitExposeType string) bool {
_, ok := StrToSchedulingUnitExposeType[schedulingUnitExposeType]
return ok
}
// ToSchedulingUnitExposeType converts SchedulingUnitExposeType string to a UFS SchedulingUnit_ExposeType enum.
func ToSchedulingUnitExposeType(schedulingUnitExposeType string) ufspb.SchedulingUnit_ExposeType {
v, ok := StrToSchedulingUnitExposeType[schedulingUnitExposeType]
if !ok {
return ufspb.SchedulingUnit_UNKNOWN
}
return ufspb.SchedulingUnit_ExposeType(ufspb.SchedulingUnit_ExposeType_value[v])
}
// List of regexps for recognizing assets stored with googlers or out of lab.
var googlers = []*regexp.Regexp{
regexp.MustCompile(`container`),
regexp.MustCompile(`desk`),
regexp.MustCompile(`testbed`),
}
// LabToZone converts deprecated Lab type to Zone
func LabToZone(lab string) ufspb.Zone {
if strings.Contains(lab, "mtv1950-testing") {
return ufspb.Zone_ZONE_MTV1950_TESTING
}
switch oslabRegexp.FindString(lab) {
case "chromeos1":
return ufspb.Zone_ZONE_CHROMEOS1
case "chromeos2":
return ufspb.Zone_ZONE_CHROMEOS2
case "chromeos3":
return ufspb.Zone_ZONE_CHROMEOS3
case "chromeos4":
return ufspb.Zone_ZONE_CHROMEOS4
case "chromeos5":
return ufspb.Zone_ZONE_CHROMEOS5
case "chromeos6":
return ufspb.Zone_ZONE_CHROMEOS6
case "chromeos7":
return ufspb.Zone_ZONE_CHROMEOS7
case "chromeos15":
return ufspb.Zone_ZONE_CHROMEOS15
default:
for _, r := range googlers {
if r.MatchString(lab) {
return ufspb.Zone_ZONE_CROS_GOOGLER_DESK
}
}
return ufspb.Zone_ZONE_UNSPECIFIED
}
}
// ToUFSDept returns the dept name based on zone string.
func ToUFSDept(zone string) string {
ufsZone := ToUFSZone(zone)
if IsInBrowserZone(ufsZone.String()) {
return Browser
}
return CrOS
}
// GetStateDescription returns the description for the state
func GetStateDescription(state string) string {
state = RemoveStatePrefix(state)
v, ok := StateToDescription[state]
if !ok {
return ""
}
return v
}
// GetSuffixAfterSeparator extracts the string appearing after the separator
//
// returns the suffix after the first found separator
func GetSuffixAfterSeparator(name, seprator string) string {
name = strings.TrimSpace(name)
pos := strings.Index(name, seprator)
if pos == -1 {
return ""
}
adjustedPos := pos + len(seprator)
if adjustedPos >= len(name) {
return ""
}
return name[adjustedPos:]
}
// ServoV3HostnameRegex is used to identify servo V3 hosts.
var ServoV3HostnameRegex = regexp.MustCompile(`.*-servo`)
// PoolNameRegex ensures that a pool name is valid.
var PoolNameRegex = regexp.MustCompile(`^[a-zA-Z0-9][a-zA-Z0-9_-]*$`)
// Invalid characters for tags field. Used by Contains/ContainsAny method.
var invalidTagChars string = "="
// ValidateTags checks if the tags contain only valid characters
func ValidateTags(tags []string) bool {
for _, t := range tags {
if strings.ContainsAny(t, invalidTagChars) {
return false
}
}
return true
}
// StrToUFSAttachedDeviceType refers a map between a string to a UFS defined map.
var StrToUFSAttachedDeviceType = map[string]string{
"unspecified": "ATTACHED_DEVICE_TYPE_UNSPECIFIED",
"apple_phone": "ATTACHED_DEVICE_TYPE_APPLE_PHONE",
"android_phone": "ATTACHED_DEVICE_TYPE_ANDROID_PHONE",
"apple_tablet": "ATTACHED_DEVICE_TYPE_APPLE_TABLET",
"android_tablet": "ATTACHED_DEVICE_TYPE_ANDROID_TABLET",
"devboard": "ATTACHED_DEVICE_TYPE_DEVBOARD",
"jetstream": "ATTACHED_DEVICE_TYPE_JETSTREAM",
}
// ValidAttachedDeviceTypeStr returns a valid str list for attached device type strings.
func ValidAttachedDeviceTypeStr() []string {
ks := make([]string, 0, len(StrToUFSAttachedDeviceType))
for k := range StrToUFSAttachedDeviceType {
ks = append(ks, k)
}
return ks
}
// IsAttachedDeviceType checks if a string refers to a valid AttachedDeviceType.
func IsAttachedDeviceType(deviceType string) bool {
_, ok := StrToUFSAttachedDeviceType[deviceType]
return ok
}
// ToUFSAttachedDeviceType converts type string to a UFS attached device type enum.
func ToUFSAttachedDeviceType(deviceType string) ufspb.AttachedDeviceType {
v, ok := StrToUFSAttachedDeviceType[deviceType]
if !ok {
return ufspb.AttachedDeviceType_ATTACHED_DEVICE_TYPE_UNSPECIFIED
}
return ufspb.AttachedDeviceType(ufspb.AttachedDeviceType_value[v])
}
// GetDevboardType returns the board type string for a devboard.
func GetDevboardType(b *ufspb.Devboard) string {
var m protoreflect.ProtoMessage
if b2 := b.GetAndreiboard(); b2 != nil {
m = b2
} else if b2 := b.GetIcetower(); b2 != nil {
m = b2
} else if b2 := b.GetDragonclaw(); b2 != nil {
m = b2
}
if b != nil {
d := m.ProtoReflect().Descriptor()
return string(d.FullName())
}
return ""
}
// StrToUFSDevboardType refers a map between a string to a UFS defined map.
var StrToUFSDevboardType = map[string]string{
"andreiboard": "unifiedfleet.api.v1.models.Andreiboard",
"icetower": "unifiedfleet.api.v1.models.Icetower",
"dragonclaw": "unifiedfleet.api.v1.models.Dragonclaw",
}
// ValidDevboardTypeStr returns a valid str list for attached device type strings.
func ValidDevboardTypeStr() []string {
ks := make([]string, 0, len(StrToUFSDevboardType))
for k := range StrToUFSDevboardType {
ks = append(ks, k)
}
return ks
}
// IsDevboardType checks if a string refers to a valid Devboard type.
func IsDevboardType(deviceType string) bool {
_, ok := StrToUFSDevboardType[deviceType]
return ok
}
// StrToModemType refers a map between modem type and and enum value.
var StrToModemType = map[string]int32{
"MODEM_TYPE_UNSPECIFIED": 0,
"MODEM_TYPE_QUALCOMM_SC7180": 1,
"MODEM_TYPE_FIBOCOMM_L850GL": 2,
"MODEM_TYPE_NL668": 3,
"MODEM_TYPE_FM350": 4,
"MODEM_TYPE_FM101": 5,
"MODEM_TYPE_QUALCOMM_SC7280": 6,
}
// IsModemType checks if a string refers to a valid ModemType.
func IsModemType(modemType string) bool {
_, ok := StrToModemType[modemType]
return ok
}
// ToModemType converts modemType string to a Modem type enum.
func ToModemType(modemType string) chromeosLab.ModemType {
v, ok := StrToModemType[modemType]
if !ok {
return chromeosLab.ModemType_MODEM_TYPE_UNSPECIFIED
}
return chromeosLab.ModemType(v)
}
// StrToSIMType refers a map between sim type and and enum value.
var StrToSIMType = map[string]int32{
"SIM_UNKNOWN": 0,
"SIM_PHYSICAL": 1,
"SIM_DIGITAL": 2,
}
// IsSIMType checks if a string refers to a valid simType.
func IsSIMType(simType string) bool {
_, ok := StrToSIMType[simType]
return ok
}
// ValidSimTypeStr returns a valid str list for SimType strings.
func ValidSimTypeStr() []string {
ks := make([]string, 0, len(StrToSIMType))
for k := range StrToSIMType {
ks = append(ks, k)
}
return ks
}
// ToSIMType converts simType string to a Sim type enum.
func ToSIMType(simType string) chromeosLab.SIMType {
v, ok := StrToSIMType[simType]
if !ok {
return chromeosLab.SIMType_SIM_UNKNOWN
}
return chromeosLab.SIMType(v)
}
// IsNetworkType checks if a string refers to a valid NetworkProvider.
func IsNetworkType(networkType string) bool {
_, ok := chromeosLab.NetworkProvider_value[networkType]
return ok
}
// ToNetworkType converts Type string to a NetworkProvider type enum.
func ToNetworkType(networkType string) chromeosLab.NetworkProvider {
v, ok := chromeosLab.NetworkProvider_value[networkType]
if !ok {
return chromeosLab.NetworkProvider_NETWORK_OTHER
}
return chromeosLab.NetworkProvider(v)
}
// ValidModemTypeStr returns a valid str list for ModemType strings.
func ValidModemTypeStr() []string {
ks := make([]string, 0, len(StrToModemType))
for k := range StrToModemType {
ks = append(ks, k)
}
return ks
}
// StrToDevicePhase refers to a map between a string and the ManufacturingConfig
// Phase type.
var StrToDevicePhase = map[string]string{
"INVALID": ufsmfg.ManufacturingConfig_PHASE_INVALID.String(),
"EVT": ufsmfg.ManufacturingConfig_PHASE_EVT.String(),
"EVT2": ufsmfg.ManufacturingConfig_PHASE_EVT2.String(),
"DVT": ufsmfg.ManufacturingConfig_PHASE_DVT.String(),
"DVT2": ufsmfg.ManufacturingConfig_PHASE_DVT2.String(),
"PVT": ufsmfg.ManufacturingConfig_PHASE_PVT.String(),
"PVT2": ufsmfg.ManufacturingConfig_PHASE_PVT2.String(),
"PVT3": ufsmfg.ManufacturingConfig_PHASE_PVT3.String(),
"MP": ufsmfg.ManufacturingConfig_PHASE_MP.String(),
}
// getDevicePhaseRegex returns a device phase regex used to match device phases
func getDevicePhaseRegex() *regexp.Regexp {
keys := make([]string, 0, len(StrToDevicePhase))
for k := range StrToDevicePhase {
keys = append(keys, k)
}
p := strings.Join(keys, "|")
regexStr := fmt.Sprintf(`(?:\b|_)(%s)(?:\b|_)`, p)
return regexp.MustCompile(regexStr)
}
// ToUFSDevicePhase converts type string to a UFS attached device type enum.
func ToUFSDevicePhase(devicePhase string) ufsmfg.ManufacturingConfig_Phase {
match := getDevicePhaseRegex().FindString(strings.ToUpper(devicePhase))
phase := strings.Trim(match, "_")
v, ok := StrToDevicePhase[phase]
if !ok {
return ufsmfg.ManufacturingConfig_PHASE_INVALID
}
return ufsmfg.ManufacturingConfig_Phase(ufsmfg.ManufacturingConfig_Phase_value[v])
}
// GetNicNameForHost returns a nic name for a ChromeOS DUT
func GetNicNameForHost(hostname string) string {
return fmt.Sprintf("%s:eth0", hostname)
}