sn_testnet_deploy/
error.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// Copyright (c) 2023, MaidSafe.
// All rights reserved.
//
// This SAFE Network Software is licensed under the BSD-3-Clause license.
// Please see the LICENSE file for more details.

use crate::{ansible::inventory::AnsibleInventoryType, NodeType};
use evmlib::contract::network_token;
use thiserror::Error;
use tokio::task::JoinError;

pub type Result<T, E = Error> = std::result::Result<T, E>;
/// Internal error.
#[derive(Debug, Error)]
#[allow(missing_docs)]
pub enum Error {
    #[error(transparent)]
    AddrParseError(#[from] std::net::AddrParseError),
    #[error("Could not determine content length for asset")]
    AssetContentLengthUndetermined,
    #[error(transparent)]
    AwsS3Error(#[from] Box<aws_sdk_s3::Error>),
    #[error("The {0} environment variable must be set to use your cloud provider")]
    CloudProviderCredentialsNotSupplied(String),
    #[error("The {0} cloud provider is not supported yet")]
    CloudProviderNotSupported(String),
    #[error("The home data directory could not be retrieved")]
    CouldNotRetrieveDataDirectory,
    #[error("Failed to delete '{0}' from '{1}")]
    DeleteS3ObjectError(String, String),
    #[error("Authorization failed for the Digital Ocean API")]
    DigitalOceanUnauthorized,
    #[error("Unexpected response: {0} -- {1}")]
    DigitalOceanUnexpectedResponse(u16, String),
    #[error("The public IP address was not obtainable from the API response")]
    DigitalOceanPublicIpAddressNotFound,
    #[error("The provided ansible inventory is empty or does not exists {0}")]
    EmptyInventory(AnsibleInventoryType),
    #[error("Could not retrieve environment details for '{0}'")]
    EnvironmentDetailsNotFound(String),
    #[error("The '{0}' environment does not exist")]
    EnvironmentDoesNotExist(String),
    #[error("The environment name is required")]
    EnvironmentNameRequired,
    #[error("Could not convert '{0}' to an EnvironmentType variant")]
    EnvironmentNameFromStringError(String),
    #[error("No EVM node found in the inventory")]
    EvmNodeNotFound,
    #[error("EVM testnet data not found or could not be read")]
    EvmTestnetDataNotFound,
    #[error("Error parsing EVM testnet data: {0}")]
    EvmTestnetDataParsingError(String),
    #[error("Command that executed with {binary} failed. See output for details.")]
    ExternalCommandRunFailed {
        binary: String,
        exit_status: std::process::ExitStatus,
    },
    #[error("Failed to parse key")]
    FailedToParseKey,
    #[error("Failed to retrieve filename")]
    FilenameNotRetrieved,
    #[error(transparent)]
    FsExtraError(#[from] fs_extra::error::Error),
    #[error("Could not obtain Genesis multiaddr")]
    GenesisListenAddress,
    #[error("To provision the remaining nodes the multiaddr of the genesis node must be supplied")]
    GenesisMultiAddrNotSupplied,
    #[error("Failed to retrieve '{0}' from '{1}")]
    GetS3ObjectError(String, String),
    #[error(transparent)]
    InquireError(#[from] inquire::InquireError),
    #[error("The node type '{0:?}' is not supported")]
    InvalidNodeType(NodeType),
    #[error(
        "The '{0}' deployment type for the environment is not supported for upscaling uploaders"
    )]
    InvalidUploaderUpscaleDeploymentType(String),
    #[error("The desired auditor VM count is smaller than the current count. This is invalid for an upscale operation.")]
    InvalidUpscaleDesiredAuditorVmCount,
    #[error("The desired bootstrap VM count is smaller than the current count. This is invalid for an upscale operation.")]
    InvalidUpscaleDesiredBootstrapVmCount,
    #[error("The desired bootstrap node count is smaller than the current count. This is invalid for an upscale operation.")]
    InvalidUpscaleDesiredBootstrapNodeCount,
    #[error("The desired node VM count is smaller than the current count. This is invalid for an upscale operation.")]
    InvalidUpscaleDesiredNodeVmCount,
    #[error("The desired node count is smaller than the current count. This is invalid for an upscale operation.")]
    InvalidUpscaleDesiredNodeCount,
    #[error("The desired private node VM count is smaller than the current count. This is invalid for an upscale operation.")]
    InvalidUpscaleDesiredPrivateNodeVmCount,
    #[error("The desired private node count is smaller than the current count. This is invalid for an upscale operation.")]
    InvalidUpscaleDesiredPrivateNodeCount,
    #[error("The desired uploader count is smaller than the current count. This is invalid for an upscale operation.")]
    InvalidUpscaleDesiredUploaderCount,
    #[error("The desired uploader VM count is smaller than the current count. This is invalid for an upscale operation.")]
    InvalidUpscaleDesiredUploaderVmCount,
    #[error("Options were used that are not applicable to a bootstrap deployment")]
    InvalidUpscaleOptionsForBootstrapDeployment,
    #[error(transparent)]
    Io(#[from] std::io::Error),
    #[error("Could not obtain IpDetails")]
    IpDetailsNotObtained,
    #[error(transparent)]
    JoinError(#[from] JoinError),
    #[error("Failed to list objects in S3 bucket with prefix '{prefix}': {error}")]
    ListS3ObjectsError { prefix: String, error: String },
    #[error("Could not configure logging: {0}")]
    LoggingConfiguration(String),
    #[error("Logs for a '{0}' testnet already exist")]
    LogsForPreviousTestnetExist(String),
    #[error("Logs have not been retrieved for the '{0}' environment.")]
    LogsNotRetrievedError(String),
    #[error("The API response did not contain the expected '{0}' value")]
    MalformedDigitalOceanApiRespose(String),
    #[error("Could not convert from DeployOptions to ProvisionOptions: bootstrap node count must have a value")]
    MissingBootstrapNodeCount,
    #[error(
        "Could not convert from DeployOptions to ProvisionOptions: node count must have a value"
    )]
    MissingNodeCount,
    #[error("The NAT gateway VM was not supplied")]
    NatGatewayNotSupplied,
    #[error(transparent)]
    NetworkTokenError(#[from] network_token::Error),
    #[error("This deployment does not have an auditor. It may be a bootstrap deployment.")]
    NoAuditorError,
    #[error("This deployment does not have a faucet. It may be a bootstrap deployment.")]
    NoFaucetError,
    #[error("This deployment does not have any uploaders. It may be a bootstrap deployment.")]
    NoUploadersError,
    #[error("The node count for the provided custom vms are not equal")]
    NodeCountMismatch,
    #[error("Could not obtain a multiaddr from the node inventory")]
    NodeAddressNotFound,
    #[error("Failed to upload {0} to S3 bucket {1}")]
    PutS3ObjectError(String, String),
    #[error(transparent)]
    RegexError(#[from] regex::Error),
    #[error(transparent)]
    ReqwestError(#[from] reqwest::Error),
    #[error("Safe client command failed: {0}")]
    SafeCmdError(String),
    #[error("Failed to download the safe or safenode binary")]
    SafeBinaryDownloadError,
    #[error("Error in byte stream when attempting to retrieve S3 object")]
    S3ByteStreamError,
    #[error("The secret key was not found in the environment")]
    SecretKeyNotFound,
    #[error(transparent)]
    SerdeJson(#[from] serde_json::Error),
    #[error("An unexpected error occurred during the setup process")]
    SetupError,
    #[error("The SLACK_WEBHOOK_URL variable was not set")]
    SlackWebhookUrlNotSupplied,
    #[error("SSH command failed: {0}")]
    SshCommandFailed(String),
    #[error("Failed to obtain lock to update SSH settings")]
    SshSettingsRwLockError,
    #[error("After several retry attempts an SSH connection could not be established")]
    SshUnavailable,
    #[error(transparent)]
    StripPrefixError(#[from] std::path::StripPrefixError),
    #[error(transparent)]
    TemplateError(#[from] indicatif::style::TemplateError),
    #[error("The '{0}' binary was not found. It is required for the deploy process. Make sure it is installed.")]
    ToolBinaryNotFound(String),
    #[error("The {0} type is not yet supported for an upscaling provision")]
    UpscaleInventoryTypeNotSupported(String),
    #[error(transparent)]
    VarError(#[from] std::env::VarError),
}