sn_testnet_deploy/
error.rs

1// Copyright (c) 2023, MaidSafe.
2// All rights reserved.
3//
4// This SAFE Network Software is licensed under the BSD-3-Clause license.
5// Please see the LICENSE file for more details.
6
7use std::net::IpAddr;
8
9use crate::{ansible::inventory::AnsibleInventoryType, NodeType};
10use evmlib::contract::network_token;
11use thiserror::Error;
12use tokio::task::JoinError;
13
14pub type Result<T, E = Error> = std::result::Result<T, E>;
15/// Internal error.
16#[derive(Debug, Error)]
17#[allow(missing_docs)]
18pub enum Error {
19    #[error(transparent)]
20    AddrParseError(#[from] std::net::AddrParseError),
21    #[error("Could not determine content length for asset")]
22    AssetContentLengthUndetermined,
23    #[error(transparent)]
24    AwsS3Error(#[from] Box<aws_sdk_s3::Error>),
25    #[error("The {0} environment variable must be set to use your cloud provider")]
26    CloudProviderCredentialsNotSupplied(String),
27    #[error("The {0} cloud provider is not supported yet")]
28    CloudProviderNotSupported(String),
29    #[error("The home data directory could not be retrieved")]
30    CouldNotRetrieveDataDirectory,
31    #[error("Failed to delete '{0}' from '{1}")]
32    DeleteS3ObjectError(String, String),
33    #[error("Authorization failed for the Digital Ocean API")]
34    DigitalOceanUnauthorized,
35    #[error("Unexpected response: {0} -- {1}")]
36    DigitalOceanUnexpectedResponse(u16, String),
37    #[error("The public IP address was not obtainable from the API response")]
38    DigitalOceanPublicIpAddressNotFound,
39    #[error("The provided ansible inventory is empty or does not exists {0}")]
40    EmptyInventory(AnsibleInventoryType),
41    #[error("Could not retrieve environment details for '{0}'")]
42    EnvironmentDetailsNotFound(String),
43    #[error("The '{0}' environment does not exist")]
44    EnvironmentDoesNotExist(String),
45    #[error("The environment name is required")]
46    EnvironmentNameRequired,
47    #[error("Could not convert '{0}' to an EnvironmentType variant")]
48    EnvironmentNameFromStringError(String),
49    #[error("No EVM node found in the inventory")]
50    EvmNodeNotFound,
51    #[error("EVM testnet data not found or could not be read")]
52    EvmTestnetDataNotFound,
53    #[error("Error parsing EVM testnet data: {0}")]
54    EvmTestnetDataParsingError(String),
55    #[error("Command that executed with {binary} failed. See output for details.")]
56    ExternalCommandRunFailed {
57        binary: String,
58        exit_status: std::process::ExitStatus,
59    },
60    #[error("Failed to parse key")]
61    FailedToParseKey,
62    #[error("Failed to retrieve filename")]
63    FilenameNotRetrieved,
64    #[error(transparent)]
65    FsExtraError(#[from] fs_extra::error::Error),
66    #[error("Could not obtain Genesis multiaddr")]
67    GenesisListenAddress,
68    #[error("To provision the remaining nodes the multiaddr of the genesis node must be supplied")]
69    GenesisMultiAddrNotSupplied,
70    #[error("Failed to retrieve '{0}' from '{1}")]
71    GetS3ObjectError(String, String),
72    #[error(transparent)]
73    InquireError(#[from] inquire::InquireError),
74    #[error("'{0}' is not a valid binary to build")]
75    InvalidBinaryName(String),
76    #[error("The node type '{0:?}' is not supported")]
77    InvalidNodeType(NodeType),
78    #[error("The number of wallet secret keys ({0}) does not match the number of uploaders ({1})")]
79    InvalidWalletCount(usize, usize),
80    #[error(
81        "The '{0}' deployment type for the environment is not supported for upscaling Clients"
82    )]
83    InvalidClientUpscaleDeploymentType(String),
84    #[error("The desired auditor VM count is smaller than the current count. This is invalid for an upscale operation.")]
85    InvalidUpscaleDesiredAuditorVmCount,
86    #[error("The desired Client count is smaller than the current count. This is invalid for an upscale operation.")]
87    InvalidUpscaleDesiredClientCount,
88    #[error("The desired Client VM count is smaller than the current count. This is invalid for an upscale operation.")]
89    InvalidUpscaleDesiredClientVmCount,
90    #[error("The desired Peer Cache VM count is smaller than the current count. This is invalid for an upscale operation.")]
91    InvalidUpscaleDesiredPeerCacheVmCount,
92    #[error("The desired Peer Cache node count is smaller than the current count. This is invalid for an upscale operation.")]
93    InvalidUpscaleDesiredPeerCacheNodeCount,
94    #[error("The desired node VM count is smaller than the current count. This is invalid for an upscale operation.")]
95    InvalidUpscaleDesiredNodeVmCount,
96    #[error("The desired node count is smaller than the current count. This is invalid for an upscale operation.")]
97    InvalidUpscaleDesiredNodeCount,
98    #[error("The desired full cone private node VM count is smaller than the current count. This is invalid for an upscale operation.")]
99    InvalidUpscaleDesiredFullConePrivateNodeVmCount,
100    #[error("The desired symmetric private node VM count is smaller than the current count. This is invalid for an upscale operation.")]
101    InvalidUpscaleDesiredSymmetricPrivateNodeVmCount,
102    #[error("The desired full cone private node count is smaller than the current count. This is invalid for an upscale operation.")]
103    InvalidUpscaleDesiredFullConePrivateNodeCount,
104    #[error("The desired symmetric private node count is smaller than the current count. This is invalid for an upscale operation.")]
105    InvalidUpscaleDesiredSymmetricPrivateNodeCount,
106    #[error("Options were used that are not applicable to a bootstrap deployment")]
107    InvalidUpscaleOptionsForBootstrapDeployment,
108    #[error("No {0} inventory found for {1} at {2}")]
109    InventoryNotFound(String, String, String),
110    #[error("The vm count for the provided custom vms are not equal: {0:?} != {1:?}")]
111    VmCountMismatch(Option<AnsibleInventoryType>, Option<AnsibleInventoryType>),
112    #[error(transparent)]
113    Io(#[from] std::io::Error),
114    #[error("Could not obtain IpDetails")]
115    IpDetailsNotObtained,
116    #[error(transparent)]
117    JoinError(#[from] JoinError),
118    #[error("Failed to list objects in S3 bucket with prefix '{prefix}': {error}")]
119    ListS3ObjectsError { prefix: String, error: String },
120    #[error("Could not configure logging: {0}")]
121    LoggingConfiguration(String),
122    #[error("Logs for a '{0}' testnet already exist")]
123    LogsForPreviousTestnetExist(String),
124    #[error("Logs have not been retrieved for the '{0}' environment.")]
125    LogsNotRetrievedError(String),
126    #[error("The API response did not contain the expected '{0}' value")]
127    MalformedDigitalOceanApiRespose(String),
128    #[error("Could not convert from DeployOptions to ProvisionOptions: peer cache node count must have a value")]
129    MissingPeerCacheNodeCount,
130    #[error(
131        "Could not convert from DeployOptions to ProvisionOptions: node count must have a value"
132    )]
133    MissingNodeCount,
134    #[error("The NAT gateway VM was not supplied")]
135    NatGatewayNotSupplied,
136    #[error(transparent)]
137    NetworkTokenError(#[from] network_token::Error),
138    #[error("This deployment does not have an auditor. It may be a bootstrap deployment.")]
139    NoAuditorError,
140    #[error("This deployment does not have any Client. It may be a bootstrap deployment.")]
141    NoClientError,
142    #[error("This deployment does not have a faucet. It may be a bootstrap deployment.")]
143    NoFaucetError,
144    #[error("The node count for the provided custom vms are not equal")]
145    NodeCountMismatch,
146    #[error("Could not obtain a multiaddr from the node inventory")]
147    NodeAddressNotFound,
148    #[error("Failed to upload {0} to S3 bucket {1}")]
149    PutS3ObjectError(String, String),
150    #[error(transparent)]
151    RegexError(#[from] regex::Error),
152    #[error(transparent)]
153    ReqwestError(#[from] reqwest::Error),
154    #[error("The rewards address must be supplied")]
155    RewardsAddressNotSet,
156    #[error("A wallet secret key must be provided for the repair run")]
157    RepairWalletAddressNotProvided,
158    #[error("Routed VM for IP {0} not found")]
159    RoutedVmNotFound(IpAddr),
160    #[error("Safe client command failed: {0}")]
161    SafeCmdError(String),
162    #[error("Failed to download the safe or safenode binary")]
163    SafeBinaryDownloadError,
164    #[error("Error in byte stream when attempting to retrieve S3 object")]
165    S3ByteStreamError,
166    #[error("The secret key was not found in the environment")]
167    SecretKeyNotFound,
168    #[error(transparent)]
169    SerdeJson(#[from] serde_json::Error),
170    #[error("An unexpected error occurred during the setup process")]
171    SetupError,
172    #[error("The SLACK_WEBHOOK_URL variable was not set")]
173    SlackWebhookUrlNotSupplied,
174    #[error("SSH command failed: {0}")]
175    SshCommandFailed(String),
176    #[error("Failed to obtain lock to update SSH settings")]
177    SshSettingsRwLockError,
178    #[error("After several retry attempts an SSH connection could not be established")]
179    SshUnavailable,
180    #[error(transparent)]
181    StripPrefixError(#[from] std::path::StripPrefixError),
182    #[error(transparent)]
183    TemplateError(#[from] indicatif::style::TemplateError),
184    #[error("Terraform show failed")]
185    TerraformShowFailed,
186    #[error("Terraform resource not found {0}")]
187    TerraformResourceNotFound(String),
188    #[error("Mismatch of a terraform resource value {expected} != {actual}")]
189    TerraformResourceValueMismatch { expected: String, actual: String },
190    #[error("The '{0}' binary was not found. It is required for the deploy process. Make sure it is installed.")]
191    ToolBinaryNotFound(String),
192    #[error("The {0} type is not yet supported for an upscaling provision")]
193    UpscaleInventoryTypeNotSupported(String),
194    #[error(transparent)]
195    VarError(#[from] std::env::VarError),
196}