...

Source file src/edge-infra.dev/pkg/edge/gcpinfra/types.go

Documentation: edge-infra.dev/pkg/edge/gcpinfra

     1  // Package gcpinfra defines the GCP Resource Manager / Cloud resource structure that
     2  // is used to manage all infrastructure owned by Edge.
     3  // Initial RFC: https://docs.edge-infra.dev/rfc/gcp-infra-structure
     4  package gcpinfra
     5  
     6  import (
     7  	"fmt"
     8  	"strings"
     9  
    10  	"edge-infra.dev/pkg/lib/gcp/project"
    11  )
    12  
    13  // String constants.  These won't change across Instances/Instance Groups,
    14  // so they aren't defaults (see defaults.go)
    15  var (
    16  	// ForemanServiceAccountName is the name used for all Foreman GCP SAs
    17  	ForemanServiceAccountName = "foreman-cnrm-system"
    18  	// ProjectIDPrefix is the string that must begin all GCP Project IDs
    19  	// owned by Edge, per NCR GCP Org requirements.  We think it is as silly
    20  	// as you do.
    21  	ProjectIDPrefix = "ret-edge"
    22  	// InfraFolderName is the folder name that contains the Infra GCP project
    23  	// for an InstanceGroup
    24  	InfraFolderName = "infra"
    25  )
    26  
    27  // RootFolder is The root folder that Edge owns, containing all instances
    28  // (dev, stage, test, prod, etc) and Edge infrastructure
    29  type RootFolder struct {
    30  	FolderID       string
    31  	InstanceGroups []InstanceGroup
    32  }
    33  
    34  // InstanceGroup contains a group of individual Edge instances, each sharing
    35  // common platform infrastructure, defined in InstanceGroup.Infra
    36  type InstanceGroup struct {
    37  	FolderID  string     `yaml:"folderId"`
    38  	Name      string     `yaml:"name"`
    39  	Instances []Instance `yaml:"instances,omitempty"`
    40  	Infra     Infra      `yaml:"infra,omitempty"`
    41  }
    42  
    43  // Infra is the folder + project that owns the billing admin Foreman Service
    44  // Account needed by each Instance to create tenant projects.  Other infrastructure
    45  // shared by instances is also defined here, such as: GCR registries, DNS, etc.
    46  type Infra struct {
    47  	FolderID              string `yaml:"folderId"`
    48  	ProjectID             string `yaml:"projectId,omitempty"`
    49  	ForemanServiceAccount string `yaml:"foremanSvcAct,omitempty"`
    50  }
    51  
    52  // Instance is the GCP infra needed for a single Edge instance.  If a
    53  // Namespace is provided, an additional folder will be created that the instance
    54  // is nested in.
    55  type Instance struct {
    56  	// The instance name.
    57  	Name string `yaml:"name"`
    58  	// Abstract logical grouping of instsances, e.g., dev, test, sandbox
    59  	Namespace string `yaml:"namespace,omitempty"`
    60  	// List of tenant projects registered with this instance of Edge
    61  	Tenants []Tenant `yaml:"tenants,omitempty"`
    62  	// The GCP project where the Edge control plane will be deployed
    63  	ForemanProjectID string `yaml:"foremanProjectId,omitempty"`
    64  	// QLIDs that will be given admin privileges on the instance and permissions
    65  	// to manage the instance K8s resources on the platform infrastructure cluster
    66  	Owners []string `yaml:"owners,omitempty"`
    67  }
    68  
    69  // Tenant represents a tenant's GCP infra.
    70  type Tenant struct {
    71  	ProjectID string
    72  }
    73  
    74  // ForemanProjectID creates + validates a Project ID string for an instance's
    75  // Foreman GCP Project
    76  func ForemanProjectID(name string) (string, error) {
    77  	id := fmt.Sprintf("%s-%s-foreman", ProjectIDPrefix, name)
    78  	err := project.IsValidProjectID(id)
    79  	if err != nil {
    80  		return "", fmt.Errorf("gcpinfra.ForemanProjectID: %w", err)
    81  	}
    82  	return id, nil
    83  }
    84  
    85  var ErrMissingPrefix = fmt.Errorf("project ID is missing required prefix %s", ProjectIDPrefix)
    86  
    87  // IsValidForemanProjectID validates input project ID strings based on org
    88  // naming requirements (constant prefix) and GCP requirements
    89  func IsValidForemanProjectID(id string) error {
    90  	if !strings.HasPrefix(id, ProjectIDPrefix) {
    91  		return fmt.Errorf("gcpinfra: invalid id %s. error: %w", id, ErrMissingPrefix)
    92  	}
    93  	if err := project.IsValidProjectID(id); err != nil {
    94  		return fmt.Errorf("gcpinfra: project id %s invalid: error: %w", id, err)
    95  	}
    96  
    97  	return nil
    98  }
    99  

View as plain text