|
| 1 | +import { describe, it } from 'mocha' |
| 2 | +import * as t from './' |
| 3 | + |
| 4 | +type ServiceScalingParameters = { |
| 5 | + DesiredCount?: number | null | undefined |
| 6 | + MaximumPercent?: number | null | undefined |
| 7 | +} |
| 8 | + |
| 9 | +const ServiceScalingParametersType = t.object<ServiceScalingParameters>({ |
| 10 | + DesiredCount: t.nullable(t.number()), |
| 11 | + MaximumPercent: t.nullable(t.number()), |
| 12 | +}) |
| 13 | + |
| 14 | +export type DeployConfig = { |
| 15 | + CloudFormationTemplateBucket?: string | null | undefined |
| 16 | + DeploymentName: string |
| 17 | + AppName?: string | null | undefined |
| 18 | + /** |
| 19 | + * The base domain name of the app, for example: clarity.foo.com |
| 20 | + */ |
| 21 | + BaseDomainName?: string | null | undefined |
| 22 | + /** |
| 23 | + * The domain name of the Route 53 hosted zone, for example: foo.com |
| 24 | + */ |
| 25 | + HostedZoneDomainName: string |
| 26 | + /** |
| 27 | + * The id of the VPC to deploy into |
| 28 | + */ |
| 29 | + VpcId: string |
| 30 | + /** |
| 31 | + * The AWS region to deploy into |
| 32 | + */ |
| 33 | + region: string |
| 34 | + /** |
| 35 | + * The subnet ids for the Vpc. Defaults to all available for VpcId |
| 36 | + */ |
| 37 | + SubnetIds?: string[] | null | undefined |
| 38 | + /** |
| 39 | + * Name of an existing EC2 KeyPair to enable SSH access to the ECS instances |
| 40 | + */ |
| 41 | + EC2KeyName?: string | null | undefined |
| 42 | + VPN?: |
| 43 | + | { |
| 44 | + CidrIp?: string | null | undefined |
| 45 | + SecurityGroupId?: string | null | undefined |
| 46 | + } |
| 47 | + | null |
| 48 | + | undefined |
| 49 | + /** |
| 50 | + * Settings for the user upload/download S3 buckets that Clarity uses. |
| 51 | + * Not applicable to CloudFormationTemplateBucket or CertificateProvider.S3BucketName. |
| 52 | + */ |
| 53 | + S3?: { |
| 54 | + /** |
| 55 | + * The origin URLs that the S3 buckets will allow. |
| 56 | + * For prod, just the public URL of the app. For staging, |
| 57 | + * you probably want a wildcard pattern like https://clarity-staging-*.foo.com |
| 58 | + */ |
| 59 | + AllowedOrigin?: string | null | undefined |
| 60 | + } |
| 61 | + Redis: |
| 62 | + | { |
| 63 | + Type: 'External' |
| 64 | + Host: string |
| 65 | + Port?: number | null | undefined |
| 66 | + DB?: number | null | undefined |
| 67 | + SecurityGroupId?: string | null | undefined |
| 68 | + } |
| 69 | + | { |
| 70 | + Type: 'ElastiCache' |
| 71 | + AvailabilityZone: string |
| 72 | + } |
| 73 | + DB: |
| 74 | + | { |
| 75 | + Type: 'External' |
| 76 | + Host: string |
| 77 | + Port?: number | null | undefined |
| 78 | + User: string |
| 79 | + Name: string |
| 80 | + Password: string |
| 81 | + RootDBName?: string | null | undefined |
| 82 | + SecurityGroupId?: string | null | undefined |
| 83 | + } |
| 84 | + | { |
| 85 | + Type: 'RDS' |
| 86 | + MasterUserPassword: string |
| 87 | + AvailabilityZone: string |
| 88 | + } |
| 89 | + Historian: { |
| 90 | + DB: { |
| 91 | + Host: string |
| 92 | + Port?: number | null | undefined |
| 93 | + User: string |
| 94 | + Password: string |
| 95 | + Name: string |
| 96 | + SecurityGroupId?: string | null | undefined |
| 97 | + } |
| 98 | + Redis?: |
| 99 | + | { |
| 100 | + Host: string |
| 101 | + Port?: number | null | undefined |
| 102 | + SecurityGroupId?: string | null | undefined |
| 103 | + } |
| 104 | + | null |
| 105 | + | undefined |
| 106 | + } |
| 107 | + ECSCluster?: |
| 108 | + | { |
| 109 | + ClusterId?: string | null | undefined |
| 110 | + MinSize?: number | null | undefined |
| 111 | + MaxSize?: number | null | undefined |
| 112 | + DesiredCapacity?: number | null | undefined |
| 113 | + InstanceType?: string | null | undefined |
| 114 | + } |
| 115 | + | null |
| 116 | + | undefined |
| 117 | + CertificateProvider?: |
| 118 | + | { |
| 119 | + StackName?: string | null | undefined |
| 120 | + S3BucketName?: string | null | undefined |
| 121 | + CFNCustomProviderZipFileName?: string | null | undefined |
| 122 | + LambdaFunctionName?: string | null | undefined |
| 123 | + } |
| 124 | + | undefined |
| 125 | + Services: { |
| 126 | + Webapp?: ServiceScalingParameters | null | undefined |
| 127 | + RedirectHttps?: ServiceScalingParameters | null | undefined |
| 128 | + MQTT: { |
| 129 | + DesiredCount?: number | null | undefined |
| 130 | + MaximumPercent?: number | null | undefined |
| 131 | + RateLimit: number |
| 132 | + } |
| 133 | + NotificationSender?: ServiceScalingParameters | null | undefined |
| 134 | + ActivityHistorian?: ServiceScalingParameters | null | undefined |
| 135 | + ZeroMinimumHealthyPercent?: boolean | null | undefined |
| 136 | + } |
| 137 | + ReCaptcha: { |
| 138 | + LoginMinScore: number |
| 139 | + SignupMinScore: number |
| 140 | + SiteKey: string |
| 141 | + SecretKey: string |
| 142 | + } |
| 143 | + Stripe: { |
| 144 | + PublishableKey: string |
| 145 | + SecretKey: string |
| 146 | + } |
| 147 | + LiveChat: { |
| 148 | + License: string |
| 149 | + } |
| 150 | + NotificationsApi: { |
| 151 | + Url: string |
| 152 | + Token: string |
| 153 | + } |
| 154 | + ClarityDockerImageTag: string |
| 155 | + JCoreIOLink?: string | null | undefined |
| 156 | + JWT: { |
| 157 | + SecretKey: string |
| 158 | + } |
| 159 | + Superadmin?: |
| 160 | + | { |
| 161 | + Email?: string | null | undefined |
| 162 | + Password?: string | null | undefined |
| 163 | + } |
| 164 | + | null |
| 165 | + | undefined |
| 166 | +} |
| 167 | + |
| 168 | +const DeployConfigType = t.object<DeployConfig>({ |
| 169 | + CloudFormationTemplateBucket: t.nullable(t.string()), |
| 170 | + DeploymentName: t.string(), |
| 171 | + AppName: t.nullable(t.string()), |
| 172 | + /** |
| 173 | + * The base domain name of the app, for example: clarity.foo.com |
| 174 | + */ |
| 175 | + BaseDomainName: t.nullable(t.string()), |
| 176 | + /** |
| 177 | + * The domain name of the Route 53 hosted zone, for example: foo.com |
| 178 | + */ |
| 179 | + HostedZoneDomainName: t.string(), |
| 180 | + /** |
| 181 | + * The id of the VPC to deploy into |
| 182 | + */ |
| 183 | + VpcId: t.string(), |
| 184 | + /** |
| 185 | + * The AWS region to deploy into |
| 186 | + */ |
| 187 | + region: t.string(), |
| 188 | + /** |
| 189 | + * The subnet ids for the Vpc. Defaults to all available for VpcId |
| 190 | + */ |
| 191 | + SubnetIds: t.nullable(t.array(t.string())), |
| 192 | + /** |
| 193 | + * Name of an existing EC2 KeyPair to enable SSH access to the ECS instances |
| 194 | + */ |
| 195 | + EC2KeyName: t.nullable(t.string()), |
| 196 | + VPN: t.nullable( |
| 197 | + t.object<DeployConfig['VPN']>({ |
| 198 | + CidrIp: t.nullable(t.string()), |
| 199 | + SecurityGroupId: t.nullable(t.string()), |
| 200 | + }) |
| 201 | + ), |
| 202 | + /** |
| 203 | + * Settings for the user upload/download S3 buckets that Clarity uses. |
| 204 | + * Not applicable to CloudFormationTemplateBucket or CertificateProvider.S3BucketName. |
| 205 | + */ |
| 206 | + S3: t.nullable( |
| 207 | + t.object<DeployConfig['S3']>({ |
| 208 | + /** |
| 209 | + * The origin URLs that the S3 buckets will allow. |
| 210 | + * For prod, just the public URL of the app. For staging, |
| 211 | + * you probably want a wildcard pattern like https://clarity-staging-*.foo.com |
| 212 | + */ |
| 213 | + AllowedOrigin: t.nullable(t.string()), |
| 214 | + }) |
| 215 | + ), |
| 216 | + Redis: t.union( |
| 217 | + t.object({ |
| 218 | + Type: t.stringLiteral('External'), |
| 219 | + Host: t.string(), |
| 220 | + Port: t.nullable(t.number()), |
| 221 | + DB: t.nullable(t.number()), |
| 222 | + SecurityGroupId: t.nullable(t.string()), |
| 223 | + }), |
| 224 | + t.object({ |
| 225 | + Type: t.stringLiteral('ElastiCache'), |
| 226 | + AvailabilityZone: t.string(), |
| 227 | + }) |
| 228 | + ), |
| 229 | + DB: t.union( |
| 230 | + t.object({ |
| 231 | + Type: t.stringLiteral('External'), |
| 232 | + Host: t.string(), |
| 233 | + Port: t.nullable(t.number()), |
| 234 | + User: t.string(), |
| 235 | + Name: t.string(), |
| 236 | + Password: t.string(), |
| 237 | + RootDBName: t.nullable(t.string()), |
| 238 | + SecurityGroupId: t.nullable(t.string()), |
| 239 | + }), |
| 240 | + t.object({ |
| 241 | + Type: t.stringLiteral('RDS'), |
| 242 | + MasterUserPassword: t.string(), |
| 243 | + AvailabilityZone: t.string(), |
| 244 | + }) |
| 245 | + ), |
| 246 | + Historian: t.object({ |
| 247 | + DB: t.object({ |
| 248 | + Host: t.string(), |
| 249 | + Port: t.nullable(t.number()), |
| 250 | + User: t.string(), |
| 251 | + Password: t.string(), |
| 252 | + Name: t.string(), |
| 253 | + SecurityGroupId: t.nullable(t.string()), |
| 254 | + }), |
| 255 | + Redis: t.nullable( |
| 256 | + t.object({ |
| 257 | + Host: t.string(), |
| 258 | + Port: t.nullable(t.number()), |
| 259 | + SecurityGroupId: t.nullable(t.string()), |
| 260 | + }) |
| 261 | + ), |
| 262 | + }), |
| 263 | + ECSCluster: t.nullable( |
| 264 | + t.object({ |
| 265 | + ClusterId: t.nullable(t.string()), |
| 266 | + MinSize: t.nullable(t.number()), |
| 267 | + MaxSize: t.nullable(t.number()), |
| 268 | + DesiredCapacity: t.nullable(t.number()), |
| 269 | + InstanceType: t.nullable(t.string()), |
| 270 | + }) |
| 271 | + ), |
| 272 | + CertificateProvider: t.nullable( |
| 273 | + t.object({ |
| 274 | + StackName: t.nullable(t.string()), |
| 275 | + S3BucketName: t.nullable(t.string()), |
| 276 | + CFNCustomProviderZipFileName: t.nullable(t.string()), |
| 277 | + LambdaFunctionName: t.nullable(t.string()), |
| 278 | + }) |
| 279 | + ), |
| 280 | + Services: t.object({ |
| 281 | + Webapp: t.nullable(ServiceScalingParametersType), |
| 282 | + RedirectHttps: t.nullable(ServiceScalingParametersType), |
| 283 | + MQTT: t.object({ |
| 284 | + DesiredCount: t.nullable(t.number()), |
| 285 | + MaximumPercent: t.nullable(t.number()), |
| 286 | + RateLimit: t.number(), |
| 287 | + }), |
| 288 | + NotificationSender: t.nullable(ServiceScalingParametersType), |
| 289 | + ActivityHistorian: t.nullable(ServiceScalingParametersType), |
| 290 | + ZeroMinimumHealthyPercent: t.nullable(t.boolean()), |
| 291 | + }), |
| 292 | + ReCaptcha: t.object({ |
| 293 | + LoginMinScore: t.number(), |
| 294 | + SignupMinScore: t.number(), |
| 295 | + SiteKey: t.string(), |
| 296 | + SecretKey: t.string(), |
| 297 | + }), |
| 298 | + Stripe: t.object({ |
| 299 | + PublishableKey: t.string(), |
| 300 | + SecretKey: t.string(), |
| 301 | + }), |
| 302 | + LiveChat: t.object({ |
| 303 | + License: t.string(), |
| 304 | + }), |
| 305 | + NotificationsApi: t.object({ |
| 306 | + Url: t.string(), |
| 307 | + Token: t.string(), |
| 308 | + }), |
| 309 | + ClarityDockerImageTag: t.string(), |
| 310 | + JCoreIOLink: t.nullable(t.string()), |
| 311 | + JWT: t.object({ |
| 312 | + SecretKey: t.string(), |
| 313 | + }), |
| 314 | + Superadmin: t.nullable( |
| 315 | + t.object({ |
| 316 | + Email: t.nullable(t.string()), |
| 317 | + Password: t.nullable(t.string()), |
| 318 | + }) |
| 319 | + ), |
| 320 | +}) |
| 321 | + |
| 322 | +describe(`smoke test`, function() { |
| 323 | + it(`works`, function() { |
| 324 | + const config: DeployConfig = { |
| 325 | + CloudFormationTemplateBucket: 'templates.clarity.foo.com', |
| 326 | + DeploymentName: 'clarity-new', |
| 327 | + HostedZoneDomainName: 'foo.com', |
| 328 | + VpcId: 'vpc-222222222', |
| 329 | + region: 'us-west-2', |
| 330 | + SubnetIds: ['subnet-222222222'], |
| 331 | + VPN: { |
| 332 | + CidrIp: '172.0.0.0/32', |
| 333 | + }, |
| 334 | + Redis: { |
| 335 | + Type: 'ElastiCache', |
| 336 | + AvailabilityZone: 'us-west-2a', |
| 337 | + }, |
| 338 | + DB: { |
| 339 | + Type: 'RDS', |
| 340 | + AvailabilityZone: 'us-west-2a', |
| 341 | + MasterUserPassword: 'blah', |
| 342 | + }, |
| 343 | + Historian: { |
| 344 | + DB: { |
| 345 | + Host: 'historian-staging-db-01.foo.com', |
| 346 | + Password: '22222222222222222222222', |
| 347 | + User: 'postgres', |
| 348 | + Name: 'historian', |
| 349 | + SecurityGroupId: 'sg-22222222222', |
| 350 | + }, |
| 351 | + }, |
| 352 | + ECSCluster: { |
| 353 | + DesiredCapacity: 2, |
| 354 | + }, |
| 355 | + Services: { |
| 356 | + MQTT: { |
| 357 | + RateLimit: 10000, |
| 358 | + }, |
| 359 | + }, |
| 360 | + ReCaptcha: { |
| 361 | + LoginMinScore: 0.15, |
| 362 | + SignupMinScore: 0.15, |
| 363 | + SiteKey: '22222222222222', |
| 364 | + SecretKey: '22222222222222', |
| 365 | + }, |
| 366 | + Stripe: { |
| 367 | + PublishableKey: '22222222222222', |
| 368 | + SecretKey: '22222222222222', |
| 369 | + }, |
| 370 | + LiveChat: { |
| 371 | + License: '10730772', |
| 372 | + }, |
| 373 | + NotificationsApi: { |
| 374 | + Url: 'https://notifications-api.foo.com', |
| 375 | + Token: '22222222222222', |
| 376 | + }, |
| 377 | + ClarityDockerImageTag: 'master', |
| 378 | + JCoreIOLink: 'http://foo.com', |
| 379 | + JWT: { |
| 380 | + SecretKey: '222222222222222', |
| 381 | + }, |
| 382 | + Superadmin: { |
| 383 | + Email: 'dev@foo.com', |
| 384 | + }, |
| 385 | + } |
| 386 | + |
| 387 | + DeployConfigType.assert(config) |
| 388 | + }) |
| 389 | +}) |
0 commit comments