Documentation
¶
Index ¶
- Constants
- Variables
- func BuildContainerImages(ctx context.Context, log *slog.Logger, workspaceDir string, verbose bool) error
- func DeviceExecAristaCliJSON[T any](ctx context.Context, device *Device, command string) (T, error)
- func LoadContainerImagesEnvFile(log *slog.Logger, workspaceDir string) error
- func WorkspaceDir() (string, error)
- type Activator
- type ActivatorSpec
- type BuildConfig
- type CYOANetwork
- type CYOANetworkSpec
- type Client
- func (c *Client) Exec(ctx context.Context, command []string, options ...docker.ExecOption) ([]byte, error)
- func (c *Client) ExecReturnJSONList(ctx context.Context, command []string, options ...docker.ExecOption) ([]map[string]any, error)
- func (c *Client) Exists(ctx context.Context) (bool, error)
- func (c *Client) GetTunnelStatus(ctx context.Context) ([]ClientStatusResponse, error)
- func (c *Client) Start(ctx context.Context) error
- func (c *Client) StartIfNotRunning(ctx context.Context) (bool, error)
- func (c *Client) WaitForLatencyResults(ctx context.Context, wantDevicePK string, timeout time.Duration) error
- func (c *Client) WaitForTunnelDisconnected(ctx context.Context, timeout time.Duration) error
- func (c *Client) WaitForTunnelStatus(ctx context.Context, wantStatus ClientSessionStatus, timeout time.Duration) error
- func (c *Client) WaitForTunnelUp(ctx context.Context, timeout time.Duration) error
- type ClientSession
- type ClientSessionStatus
- type ClientSpec
- type ClientStatusResponse
- type ClientUserType
- type Controller
- func (c *Controller) Exists(ctx context.Context) (bool, error)
- func (c *Controller) GetAgentConfig(ctx context.Context, deviceAgentPubkey string) (*pb.ConfigResponse, error)
- func (c *Controller) Start(ctx context.Context) error
- func (c *Controller) StartIfNotRunning(ctx context.Context) (bool, error)
- type ControllerSpec
- type DefaultNetwork
- type Device
- func (d *Device) Exec(ctx context.Context, command []string) ([]byte, error)
- func (d *Device) Exists(ctx context.Context) (bool, error)
- func (d *Device) GetEAPIHTTPClient() (*goeapi.Node, error)
- func (d *Device) GetTelemetryMetricsClient() *prometheus.MetricsClient
- func (d *Device) InternalTelemetryMetricsPort() (int, error)
- func (d *Device) Start(ctx context.Context) error
- func (d *Device) StartIfNotRunning(ctx context.Context) (bool, error)
- type DeviceSpec
- type DeviceTelemetrySpec
- type Devnet
- func (d *Devnet) AddClient(ctx context.Context, spec ClientSpec) (*Client, error)
- func (d *Devnet) AddDevice(ctx context.Context, spec DeviceSpec) (*Device, error)
- func (d *Devnet) Close()
- func (d *Devnet) CreateDeviceLoopbackInterface(ctx context.Context, deviceCode string, interfaceName string, ...) error
- func (d *Devnet) CreateDeviceOnchain(ctx context.Context, deviceCode string, location string, exchange string, ...) error
- func (d *Devnet) DeleteDeviceLoopbackInterface(ctx context.Context, deviceCode string, interfaceName string) error
- func (dn *Devnet) DeployServiceabilityProgram(ctx context.Context) error
- func (dn *Devnet) DeployServiceabilityProgramIfNotDeployed(ctx context.Context) (bool, error)
- func (dn *Devnet) DeployTelemetryProgram(ctx context.Context) error
- func (dn *Devnet) DeployTelemetryProgramIfNotDeployed(ctx context.Context) (bool, error)
- func (d *Devnet) Destroy(ctx context.Context, all bool) error
- func (d *Devnet) GetDevicePubkeyOnchain(ctx context.Context, deviceCode string) (string, error)
- func (d *Devnet) GetOrCreateDeviceOnchain(ctx context.Context, deviceCode string, location string, exchange string, ...) (string, error)
- func (dn *Devnet) InitSmartContract(ctx context.Context) error
- func (dn *Devnet) InitSmartContractIfNotInitialized(ctx context.Context) (bool, error)
- func (dn *Devnet) IsServiceabilityProgramDeployed(ctx context.Context) (bool, error)
- func (dn *Devnet) IsSmartContractInitialized(ctx context.Context) (bool, error)
- func (dn *Devnet) IsTelemetryProgramDeployed(ctx context.Context) (bool, error)
- func (d *Devnet) Start(ctx context.Context, buildConfig *BuildConfig) error
- func (d *Devnet) Stop(ctx context.Context) error
- type DevnetSpec
- type Funder
- type FunderSpec
- type Ledger
- func (l *Ledger) Exists(ctx context.Context) (bool, error)
- func (l *Ledger) GetRPCClient() *rpc.Client
- func (l *Ledger) GetServiceabilityClient() (*serviceability.Client, error)
- func (l *Ledger) GetTelemetryClient(signer *solana.PrivateKey) (*telemetry.Client, error)
- func (l *Ledger) Start(ctx context.Context) error
- func (l *Ledger) StartIfNotRunning(ctx context.Context) (bool, error)
- type LedgerSpec
- type Manager
- type ManagerSpec
- type MiscNetwork
Constants ¶
const ( LabelsKeyDomain = "dz.malbeclabs.com" LabelsKeyType = "type" LabelsKeyTypeValueDevnet = "devnet" LabelsKeyDeployID = "deploy-id" LabelsFilterTypeDevnet = LabelsKeyDomain + "/" + LabelsKeyType + "=" + LabelsKeyTypeValueDevnet )
Variables ¶
var ( ErrDevicePubkeyNotFoundOnchain = errors.New("device pubkey not found onchain") ErrDeviceNotFoundOnchain = errors.New("device not found onchain") )
Functions ¶
func BuildContainerImages ¶
func DeviceExecAristaCliJSON ¶
ExecCliReturnJSONObject executes a command on the device using the Cli tool and returns the JSON-encoded response as a map.
func WorkspaceDir ¶
Types ¶
type Activator ¶
type Activator struct {
ContainerID string
// contains filtered or unexported fields
}
type ActivatorSpec ¶
type ActivatorSpec struct {
ContainerImage string
}
func (*ActivatorSpec) Validate ¶
func (s *ActivatorSpec) Validate() error
type BuildConfig ¶
type BuildConfig struct {
Verbose bool
}
type CYOANetwork ¶
func (*CYOANetwork) CreateIfNotExists ¶
func (n *CYOANetwork) CreateIfNotExists(ctx context.Context) (bool, error)
type CYOANetworkSpec ¶
type CYOANetworkSpec struct {
CIDRPrefix int
}
func (*CYOANetworkSpec) Validate ¶
func (s *CYOANetworkSpec) Validate() error
type Client ¶
type Client struct {
Spec *ClientSpec
ContainerID string
Pubkey string
CYOANetworkIP string
// contains filtered or unexported fields
}
func (*Client) ExecReturnJSONList ¶
func (*Client) GetTunnelStatus ¶
func (c *Client) GetTunnelStatus(ctx context.Context) ([]ClientStatusResponse, error)
func (*Client) StartIfNotRunning ¶
StartIfNotRunning creates and starts the client container if it's not already running.
func (*Client) WaitForLatencyResults ¶
func (*Client) WaitForTunnelDisconnected ¶
func (*Client) WaitForTunnelStatus ¶
type ClientSession ¶
type ClientSession struct {
SessionStatus ClientSessionStatus `json:"session_status"`
LastSessionUpdate int64 `json:"last_session_update"`
}
type ClientSessionStatus ¶
type ClientSessionStatus string
const ( ClientSessionStatusUp ClientSessionStatus = "up" ClientSessionStatusDown ClientSessionStatus = "down" ClientSessionStatusDisconnected ClientSessionStatus = "disconnected" )
type ClientSpec ¶
type ClientSpec struct {
ContainerImage string
KeypairPath string
// Route liveness passive/active mode flags.
// TODO(snormore): These flags are temporary for initial rollout testing.
// They will be superceded by a single `route-liveness-enable` flag, where false means passive-mode
// and true means active-mode.
RouteLivenessEnablePassive bool
RouteLivenessEnableActive bool
// RouteLivenessPeerMetrics is a flag to enable or disable per per-peer metrics for route
// liveness (high cardinality).
RouteLivenessPeerMetrics bool
// RouteLivenessDebug is a flag to enable or disable debug logging for route liveness.
RouteLivenessDebug bool
// CYOANetworkIPHostID is the offset into the host portion of the subnet (must be < 2^(32 - prefixLen)).
CYOANetworkIPHostID uint32
}
func (*ClientSpec) Validate ¶
func (s *ClientSpec) Validate(cyoaNetworkSpec CYOANetworkSpec) error
type ClientStatusResponse ¶
type ClientStatusResponse struct {
TunnelName string `json:"tunnel_name"`
TunnelSrc net.IP `json:"tunnel_src"`
TunnelDst net.IP `json:"tunnel_dst"`
DoubleZeroIP net.IP `json:"doublezero_ip"`
DoubleZeroStatus ClientSession `json:"doublezero_status"`
UserType ClientUserType `json:"user_type"`
}
type ClientUserType ¶
type ClientUserType string
type Controller ¶
type Controller struct {
ContainerID string
ExternalPort int
DefaultNetworkIP string
// contains filtered or unexported fields
}
func (*Controller) Exists ¶
func (c *Controller) Exists(ctx context.Context) (bool, error)
Exists checks if the controller container exists.
func (*Controller) GetAgentConfig ¶
func (c *Controller) GetAgentConfig(ctx context.Context, deviceAgentPubkey string) (*pb.ConfigResponse, error)
func (*Controller) StartIfNotRunning ¶
func (c *Controller) StartIfNotRunning(ctx context.Context) (bool, error)
StartIfNotRunning creates and starts the controller container if it's not already running.
type ControllerSpec ¶
type ControllerSpec struct {
ContainerImage string
}
func (*ControllerSpec) Validate ¶
func (s *ControllerSpec) Validate(cyoaNetworkSpec CYOANetworkSpec) error
type DefaultNetwork ¶
type DefaultNetwork struct {
Name string
SubnetCIDR string
// contains filtered or unexported fields
}
func (*DefaultNetwork) CreateIfNotExists ¶
func (n *DefaultNetwork) CreateIfNotExists(ctx context.Context) (bool, error)
type Device ¶
type Device struct {
Spec *DeviceSpec
// ID is the PDA derived address/pubkey of the device onchain.
// It's the primary key of the devices dataset in the ledger.
ID string
ContainerID string
CYOANetworkIP string
// ExternalEAPIHTTPPort is the port on which the device's EAPI HTTP server is exposed.
ExternalEAPIHTTPPort int
// ExternalTelemetryMetricsPort is the port on which the device's telemetry metrics server is exposed.
ExternalTelemetryMetricsPort int
// contains filtered or unexported fields
}
func (*Device) GetTelemetryMetricsClient ¶
func (d *Device) GetTelemetryMetricsClient() *prometheus.MetricsClient
func (*Device) InternalTelemetryMetricsPort ¶
func (*Device) Start ¶
StartDevice starts a device container and attaches it to the management network.
Interface ordering very much matters with containerized EOS. The first network attached is the management interface, then subsequent networks correspond to ethernet interfaces.
Docker attaches interfaces in seemingly random order if the container is not yet started. If the networks end up attached in the wrong order, this test will fail as the CYOA network will not be attached to Ethernet1. To avoid this, we start the container with the default bridge network attached, then attach the CYOA network to the container.
type DeviceSpec ¶
type DeviceSpec struct {
ContainerImage string
Code string
Location string
Exchange string
MetricsPublisherPK string
// CYOANetworkIPHostID is the offset into the host portion of the subnet (must be < 2^(32 - prefixLen)).
CYOANetworkIPHostID uint32
// CYOANetworkAllocatablePrefix is the prefix length of the allocatable portion of the CYOA network.
// This is used to derive the allocatable IP addresses for the device.
CYOANetworkAllocatablePrefix uint32
// Agent telemetry config.
Telemetry DeviceTelemetrySpec
// Additional docker networks to attach the device to.
AdditionalNetworks []string
// Interfaces is a map of interface names to types.
Interfaces map[string]string
// LoopbackInterfaces is a map of interface names to loopback types.
LoopbackInterfaces map[string]string
}
func (*DeviceSpec) Validate ¶
func (s *DeviceSpec) Validate(cyoaNetworkSpec CYOANetworkSpec) error
type DeviceTelemetrySpec ¶
type DeviceTelemetrySpec struct {
Enabled bool
// KeypairPath is the path to the telemetry keypair.
KeypairPath string
// TWAMPListenPort is the port on which the device will listen for TWAMP probes.
TWAMPListenPort uint16
// ProbeInterval is the interval at which to probe peers.
ProbeInterval time.Duration
// SubmissionInterval is the interval at which to submit samples.
SubmissionInterval time.Duration
// PeersRefreshInterval is the interval at which to refresh peers.
PeersRefreshInterval time.Duration
// ManagementNS is the name of the management namespace to use for ledger communication.
// If not provided, the default namespace will be used.
ManagementNS string
// Verbose is whether to enable verbose logging.
Verbose bool
// MetricsEnable is whether to enable prometheus metrics.
MetricsEnable bool
// MetricsAddr is the listen address for the prometheus metrics server.
MetricsAddr string
}
func (*DeviceTelemetrySpec) Validate ¶
func (s *DeviceTelemetrySpec) Validate() error
type Devnet ¶
type Devnet struct {
Spec DevnetSpec
ExternalHost string
DefaultNetwork *DefaultNetwork
CYOANetwork *CYOANetwork
Ledger *Ledger
Manager *Manager
Funder *Funder
Controller *Controller
Activator *Activator
Devices map[string]*Device
Clients map[string]*Client
// contains filtered or unexported fields
}
func New ¶
func New(spec DevnetSpec, log *slog.Logger, dockerClient *client.Client, subnetAllocator *docker.SubnetAllocator) (*Devnet, error)
func (*Devnet) CreateDeviceLoopbackInterface ¶ added in v0.5.3
func (*Devnet) CreateDeviceOnchain ¶
func (*Devnet) DeleteDeviceLoopbackInterface ¶ added in v0.5.3
func (*Devnet) DeployServiceabilityProgram ¶
func (*Devnet) DeployServiceabilityProgramIfNotDeployed ¶
func (*Devnet) DeployTelemetryProgram ¶
func (*Devnet) DeployTelemetryProgramIfNotDeployed ¶
func (*Devnet) GetDevicePubkeyOnchain ¶
func (*Devnet) GetOrCreateDeviceOnchain ¶
func (*Devnet) InitSmartContract ¶
InitSmartContract initializes the smart contract using the manager container.
Perform the global state initialization via `doublezero init`, and then populate global config, location, and exchange information onchain.
func (*Devnet) InitSmartContractIfNotInitialized ¶
InitSmartContractIfNotInitialized initializes the smart contract if it's not already initialized.
func (*Devnet) IsServiceabilityProgramDeployed ¶
func (*Devnet) IsSmartContractInitialized ¶
IsSmartContractInitialized checks if the smart contract is initialized by checking for the presence of the default global configuration of any value.
func (*Devnet) IsTelemetryProgramDeployed ¶
type DevnetSpec ¶
type DevnetSpec struct {
DeployID string
DeployDir string
// ExtraLabels are used to identify the resources created by the devnet.
// These are added to the resources created by the devnet, in addition to default labels based
// on the deployID.
ExtraLabels map[string]string
CYOANetwork CYOANetworkSpec
// Override the default device tunnel network onchain.
DeviceTunnelNet string
Ledger LedgerSpec
Manager ManagerSpec
Funder FunderSpec
Controller ControllerSpec
Activator ActivatorSpec
Devices map[string]DeviceSpec
Clients map[string]ClientSpec
}
func (*DevnetSpec) Validate ¶
func (s *DevnetSpec) Validate() error
type Funder ¶
type Funder struct {
ContainerID string
ExternalMetricsPort int
// contains filtered or unexported fields
}
func (*Funder) GetMetricsClient ¶
func (c *Funder) GetMetricsClient() *prometheus.MetricsClient
func (*Funder) PrivateKey ¶
func (c *Funder) PrivateKey() (solana.PrivateKey, error)
type FunderSpec ¶
type FunderSpec struct {
ContainerImage string
KeypairPath string
Interval time.Duration
MinBalanceSOL float64
TopUpSOL float64
Verbose bool
ExtraRecipients map[string]string
}
func (*FunderSpec) Validate ¶
func (s *FunderSpec) Validate() error
type Ledger ¶
type Ledger struct {
ContainerID string
InternalRPCURL string
InternalRPCWSURL string
ExternalRPCPort int
// InternalIPRPCURL is the RPC URL of the ledger container using the internal IP instead of
// hostname. This is needed by the device/agent which isn't able to use docker DNS.
InternalIPRPCURL string
// contains filtered or unexported fields
}
func (*Ledger) GetRPCClient ¶
func (*Ledger) GetServiceabilityClient ¶
func (l *Ledger) GetServiceabilityClient() (*serviceability.Client, error)
func (*Ledger) GetTelemetryClient ¶
type LedgerSpec ¶
type LedgerSpec struct {
ContainerImage string
}
func (*LedgerSpec) Validate ¶
func (s *LedgerSpec) Validate() error
type Manager ¶
type Manager struct {
ContainerID string
Pubkey string
ServiceabilityProgramID string
TelemetryProgramID string
// contains filtered or unexported fields
}
type ManagerSpec ¶
type ManagerSpec struct {
ContainerImage string
ManagerKeypairPath string
ServiceabilityProgramKeypairPath string
TelemetryProgramKeypairPath string
}
func (*ManagerSpec) Validate ¶
func (s *ManagerSpec) Validate() error
type MiscNetwork ¶ added in v0.5.3
type MiscNetwork struct {
Name string
// contains filtered or unexported fields
}
func NewMiscNetwork ¶ added in v0.5.3
func NewMiscNetwork(dn *Devnet, log *slog.Logger, suffix string) *MiscNetwork
func (*MiscNetwork) Create ¶ added in v0.5.3
func (n *MiscNetwork) Create(ctx context.Context) error
func (*MiscNetwork) CreateIfNotExists ¶ added in v0.5.3
func (n *MiscNetwork) CreateIfNotExists(ctx context.Context) (bool, error)