/ Tools / CodexNetDeployer / Configuration.cs
Configuration.cs
  1  using ArgsUniform;
  2  using CodexClient;
  3  using DistTestCore;
  4  
  5  namespace CodexNetDeployer
  6  {
  7      public class Configuration
  8      {
  9          public const int SecondsIn1Day = 24 * 60 * 60;
 10          public const int TenMinutes = 10 * 60;
 11  
 12          [Uniform("deploy-name", "nm", "DEPLOYNAME", false, "Name of the deployment. (optional)")]
 13          public string DeploymentName { get; set; } = "unnamed";
 14  
 15          [Uniform("kube-config", "kc", "KUBECONFIG", false, "Path to Kubeconfig file. Use 'null' (default) to use local cluster.")]
 16          public string KubeConfigFile { get; set; } = "null";
 17  
 18          [Uniform("kube-namespace", "kn", "KUBENAMESPACE", true, "Kubernetes namespace to be used for deployment.")]
 19          public string KubeNamespace { get; set; } = string.Empty;
 20          
 21          [Uniform("deploy-id", "di", "DEPLOYID", false, "ID of the deployment. (default) to current time)")]
 22          public string DeployId { get; set; } = NameUtils.MakeDeployId();
 23  
 24          [Uniform("deploy-file", "df", "DEPLOYFILE", false, "Output deployment JSON file that will be written. Defaults to 'codex-deployment.json'.")]
 25          public string DeployFile { get; set; } = "codex-deployment.json";
 26  
 27          [Uniform("codex-local-repo", "cr", "CODEXLOCALREPOPATH", false, "If set, instead of using the default Codex docker image, the local repository will be used to build an image. " +
 28              "This requires the 'DOCKERUSERNAME' and 'DOCKERPASSWORD' environment variables to be set. (You can omit the password to use your system default, or use a docker access token as DOCKERPASSWORD.) You can set " +
 29              "'DOCKERTAG' to define the image tag. If not set, one will be generated.")]
 30          public string CodexLocalRepoPath { get; set; } = string.Empty;
 31  
 32          [Uniform("nodes", "n", "NODES", true, "Number of Codex nodes to be created.")]
 33          public int? NumberOfCodexNodes { get; set; }
 34  
 35          [Uniform("validators", "v", "VALIDATORS", true, "Number of Codex nodes that will be validating.")]
 36          public int? NumberOfValidators { get; set; }
 37  
 38          [Uniform("storage-quota", "sq", "STORAGEQUOTA", true, "Storage quota in megabytes used by each Codex node.")]
 39          public int? StorageQuota { get; set; }
 40  
 41          [Uniform("log-level", "l", "LOGLEVEL", true, "Log level used by each Codex node. [Trace, Debug*, Info, Warn, Error]")]
 42          public CodexLogLevel CodexLogLevel { get; set; } = CodexLogLevel.Debug;
 43          
 44          [Uniform("log-level-libp2p", "lp2p", "LOGLEVELLIBP2P", true, "Log level for all libp2p topics. [Trace, Debug, Info, Warn*, Error]")]
 45          public CodexLogLevel Libp2pLogLevel { get; set; } = CodexLogLevel.Warn;
 46  
 47          [Uniform("log-level-discv5", "ldv5", "LOGLEVELDISCV5", true, "Log level for all discv5 topics. [Trace, Debug, Info, Warn*, Error]")]
 48          public CodexLogLevel Discv5LogLevel { get; set; } = CodexLogLevel.Warn;
 49  
 50          [Uniform("make-storage-available", "msa", "MAKESTORAGEAVAILABLE", true, "Is true, storage will be made available using the next configuration parameters.")]
 51          public bool ShouldMakeStorageAvailable { get; set; } = false;
 52  
 53          [Uniform("storage-sell", "ss", "STORAGESELL", false, "Number of megabytes of storage quota to make available for selling.")]
 54          public int? StorageSell { get; set; }
 55  
 56          [Uniform("test-tokens", "tt", "TESTTOKENS", false, "Initial amount of test-tokens minted for each Codex node.")]
 57          public int InitialTestTokens { get; set; }
 58  
 59          [Uniform("min-price", "mp", "MINPRICE", false, "Minimum price per byte per second in TSTWEI for the storage space for which contracts will be accepted.")]
 60          public int MinPricePerBytePerSecond { get; set; }
 61  
 62          [Uniform("max-collateral", "mc", "MAXCOLLATERAL", false, "Maximum collateral that will be placed for the total storage space.")]
 63          public int MaxCollateral { get; set; }
 64  
 65          [Uniform("max-duration", "md", "MAXDURATION", false, "Maximum duration in seconds for contracts which will be accepted.")]
 66          public int MaxDuration { get; set; }
 67  
 68          [Uniform("block-ttl", "bt", "BLOCKTTL", false, "Block timeout in seconds. Default is 24 hours.")]
 69          public int BlockTTL { get; set; } = SecondsIn1Day;
 70  
 71          [Uniform("block-mi", "bmi", "BLOCKMI", false, "Block maintenance interval in seconds. Default is 10 minutes.")]
 72          public int BlockMI { get; set; } = TenMinutes;
 73  
 74          [Uniform("block-mn", "bmn", "BLOCKMN", false, "Number of blocks maintained per interval. Default is 1000 blocks.")]
 75          public int BlockMN { get; set; } = 1000;
 76  
 77          [Uniform("metrics-endpoints", "me", "METRICSENDPOINTS", false, "[true, false]. Determines if metric endpoints will be enabled. Default is false.")]
 78          public bool MetricsEndpoints { get; set; } = false;
 79  
 80          [Uniform("metrics-scraper", "ms", "METRICSSCRAPER", false, "[true, false]. Determines if metrics scraper service will be deployed. (Required for certain tests.) Default is false.")]
 81          public bool MetricsScraper { get; set; } = false;
 82  
 83          [Uniform("teststype-podlabel", "ttpl", "TESTSTYPE-PODLABEL", false, "Each kubernetes pod will be created with a label 'teststype' with value 'continuous'. " +
 84              "set this option to override the label value.")]
 85          public string TestsTypePodLabel { get; set; } = "continuous-tests";
 86  
 87          [Uniform("check-connect", "cc", "CHECKCONNECT", false, "If true, deployer check ensure peer-connectivity between all deployed nodes after deployment. Default is false.")]
 88          public bool CheckPeerConnection { get; set; } = false;
 89  
 90          [Uniform("public-testnet", "ptn", "PUBLICTESTNET", false, "If true, deployment is created for public exposure. Default is false.")]
 91          public bool IsPublicTestNet { get; set; } = false;
 92  
 93          [Uniform("public-discports", "pdps", "PUBLICDISCPORTS", false, "Required if public-testnet is true. Comma-separated port numbers used for discovery. Number must match number of nodes.")]
 94          public string PublicDiscPorts { get; set; } = string.Empty;
 95  
 96          [Uniform("public-listenports", "plps", "PUBLICLISTENPORTS", false, "Required if public-testnet is true. Comma-separated port numbers used for listening. Number must match number of nodes.")]
 97          public string PublicListenPorts { get; set; } = string.Empty;
 98  
 99          [Uniform("public-gethdiscport", "pgdp", "PUBLICGETHDISCPORT", false, "Required if public-testnet is true. Single port number used for Geth's public discovery port.")]
100          public int PublicGethDiscPort { get; set; }
101  
102          [Uniform("public-gethlistenport", "pglp", "PUBLICGETHLISTENPORT", false, "Required if public-testnet is true. Single port number used for Geth's public listen port.")]
103          public int PublicGethListenPort { get; set; }
104  
105          [Uniform("discord-bot", "dbot", "DISCORDBOT", false, "If true, will deploy discord bot. Default is false.")]
106          public bool DeployDiscordBot { get; set; } = false;
107  
108          [Uniform("dbot-token", "dbott", "DBOTTOKEN", false, "Required if discord-bot is true. Discord token used by bot.")]
109          public string DiscordBotToken { get; set; } = string.Empty;
110  
111          [Uniform("dbot-servername", "dbotsn", "DBOTSERVERNAME", false, "Required if discord-bot is true. Name of the Discord server.")]
112          public string DiscordBotServerName { get; set; } = string.Empty;
113  
114          [Uniform("dbot-adminrolename", "dbotarn", "DBOTADMINROLENAME", false, "Required if discord-bot is true. Name of the Discord role which will have access to admin features.")]
115          public string DiscordBotAdminRoleName { get; set; } = string.Empty;
116  
117          [Uniform("dbot-adminchannelname", "dbotacn", "DBOTADMINCHANNELNAME", false, "Required if discord-bot is true. Name of the Discord channel in which admin commands are allowed.")]
118          public string DiscordBotAdminChannelName { get; set; } = string.Empty;
119          
120          [Uniform("dbot-rewardchannelname", "dbotrcn", "DBOTREWARDCHANNELNAME", false, "Required if discord-bot is true. Name of the Discord channel in which reward updates are posted.")]
121          public string DiscordBotRewardChannelName { get; set; } = string.Empty;
122  
123          [Uniform("dbot-datapath", "dbotdp", "DBOTDATAPATH", false, "Optional. Path in container where bot will save all data.")]
124          public string DiscordBotDataPath { get; set; } = string.Empty;
125  
126          public List<string> Validate()
127          {
128              var errors = new List<string>();
129  
130              StringIsSet(nameof(KubeNamespace), KubeNamespace, errors);
131              StringIsSet(nameof(KubeConfigFile), KubeConfigFile, errors);
132              StringIsSet(nameof(TestsTypePodLabel), TestsTypePodLabel, errors);
133  
134              if (NumberOfValidators > NumberOfCodexNodes)
135              {
136                  errors.Add($"{nameof(NumberOfValidators)} ({NumberOfValidators}) may not be greater than {nameof(NumberOfCodexNodes)} ({NumberOfCodexNodes}).");
137              }
138              if (StorageSell.HasValue && StorageQuota.HasValue && StorageSell.Value >= StorageQuota.Value)
139              {
140                  errors.Add("StorageSell cannot be greater than or equal to StorageQuota.");
141              }
142  
143              if (ShouldMakeStorageAvailable)
144              {
145                  IntIsOverZero(nameof(StorageSell), StorageSell, errors);
146                  IntIsOverZero(nameof(InitialTestTokens), InitialTestTokens, errors);
147                  IntIsOverZero(nameof(MinPricePerBytePerSecond), MinPricePerBytePerSecond, errors);
148                  IntIsOverZero(nameof(MaxCollateral), MaxCollateral, errors);
149                  IntIsOverZero(nameof(MaxDuration), MaxDuration, errors);
150              }
151  
152              if (IsPublicTestNet)
153              {
154                  if (NumberOfCodexNodes > 0)
155                  {
156                      if (PublicDiscPorts.Split(",").Length != NumberOfCodexNodes) errors.Add("Number of public discovery-ports provided does not match number of codex nodes.");
157                      if (PublicListenPorts.Split(",").Length != NumberOfCodexNodes) errors.Add("Number of public listen-ports provided does not match number of codex nodes.");
158                  }
159                  if (PublicGethDiscPort == 0) errors.Add("Geth public discovery port is not set.");
160                  if (PublicGethListenPort == 0) errors.Add("Geth public listen port is not set.");
161              }
162  
163              if (DeployDiscordBot)
164              {
165                  StringIsSet(nameof(DiscordBotToken), DiscordBotToken, errors);
166                  StringIsSet(nameof(DiscordBotServerName), DiscordBotServerName, errors);
167                  StringIsSet(nameof(DiscordBotAdminRoleName), DiscordBotAdminRoleName, errors);
168                  StringIsSet(nameof(DiscordBotAdminChannelName), DiscordBotAdminChannelName, errors);
169                  StringIsSet(nameof(DiscordBotRewardChannelName), DiscordBotRewardChannelName, errors);
170              }
171  
172              return errors;
173          }
174  
175          private static void IntIsOverZero(string variable, int? value, List<string> errors)
176          {
177              if (value == null || value.Value < 1)
178              {
179                  errors.Add($"{variable} must be set and must be greater than 0.");
180              }
181          }
182  
183          private static void StringIsSet(string variable, string value, List<string> errors)
184          {
185              if (string.IsNullOrWhiteSpace(value))
186              {
187                  errors.Add($"{variable} must be set.");
188              }
189          }
190      }
191  }