1use 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#[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}