diff --git a/installer/Makefile b/installer/Makefile index 78c7438bee..cc38b8b692 100644 --- a/installer/Makefile +++ b/installer/Makefile @@ -24,8 +24,8 @@ bin/%/installer: $(GO_FILES) assets/bindata.go backend: assets/bindata.go GOOS=$(OS) go build -o bin/$(OS)/installer -ldflags $(LD_FLAGS) $(REPO)/cmd/installer -assets/bindata.go: frontend bin/go-bindata $(shell find assets -type f) - @./bin/go-bindata -pkg assets -o assets/bindata.go -ignore=bindata.go -ignore=doc.go -ignore=assets.go -prefix assets assets/... +assets/bindata.go: frontend bin/go-bindata $(shell find assets -type f | grep -v .go) + ./bin/go-bindata -pkg assets -o assets/bindata.go -ignore=bindata.go -ignore=doc.go -ignore=assets.go -prefix assets assets/... .PHONY: frontend frontend: diff --git a/installer/frontend/__tests__/examples/aws-vpc.json b/installer/frontend/__tests__/examples/aws-vpc.json new file mode 100644 index 0000000000..6650cc7ab3 --- /dev/null +++ b/installer/frontend/__tests__/examples/aws-vpc.json @@ -0,0 +1,54 @@ +{ + "adminPassword": "UEFTU1dPUkQ=", + "clusterKind": "tectonic-aws-tf", + "credentials": { + "AWSAccessKeyID": "awsAccessKeyId", + "AWSRegion": "us-west-1", + "AWSSecretAccessKey": "awsSecretAccessKey", + "AWSSessionToken": "awsSessionToken" + }, + "dryRun": false, + "license": "", + "platform": "aws", + "pullSecret": "", + "variables": { + "tectonic_admin_email": "admin@example.com", + "tectonic_aws_etcd_ec2_type": "t2.large", + "tectonic_aws_etcd_root_volume_size": 300, + "tectonic_aws_etcd_root_volume_type": "gp2", + "tectonic_aws_external_master_subnet_ids": [ + "subnet-9a7dcafd", + "subnet-43ef260a", + "subnet-1ad7e242" + ], + "tectonic_aws_external_vpc_id": "someVPCID", + "tectonic_aws_external_vpc_public": true, + "tectonic_aws_external_worker_subnet_ids": [ + "subnet-277ccb40", + "subnet-19ef2650", + "subnet-36d7e26e" + ], + "tectonic_aws_region": "us-west-1", + "tectonic_aws_extra_tags": { + "test_tag": "testing" + }, + "tectonic_aws_master_ec2_type": "t2.large", + "tectonic_aws_master_root_volume_size": 33, + "tectonic_aws_master_root_volume_type": "gp2", + "tectonic_aws_ssh_key": "some-ssh-key", + "tectonic_aws_worker_ec2_type": "t2.medium", + "tectonic_aws_worker_root_volume_iops": 1000, + "tectonic_aws_worker_root_volume_size": 1000, + "tectonic_aws_worker_root_volume_type": "io1", + "tectonic_base_domain": "example.com", + "tectonic_cl_channel": "stable", + "tectonic_cluster_cidr": "10.2.0.0/16", + "tectonic_cluster_name": "test", + "tectonic_dns_name": "test", + "tectonic_etcd_count": 3, + "tectonic_experimental": false, + "tectonic_master_count": 1, + "tectonic_service_cidr": "10.3.0.0/16", + "tectonic_worker_count": 3 + } +} diff --git a/installer/frontend/__tests__/examples/aws.json b/installer/frontend/__tests__/examples/aws.json new file mode 100644 index 0000000000..c4bbcbfcef --- /dev/null +++ b/installer/frontend/__tests__/examples/aws.json @@ -0,0 +1,46 @@ +{ + "dryRun": false, + "license": "", + "platform": "aws", + "pullSecret": "", + "adminPassword": "UEFTU1dPUkQ=", + "clusterKind": "tectonic-aws-tf", + "credentials": { + "AWSAccessKeyID": "awsAccessKeyId", + "AWSRegion": "us-west-1", + "AWSSecretAccessKey": "awsSecretAccessKey" + }, + "variables": { + "tectonic_admin_email": "admin@example.com", + "tectonic_aws_extra_tags": { + "test_tag": "testing" + }, + "tectonic_aws_master_custom_subnets": { + "us-west-1a": "10.0.0.0/19", + "us-west-1c": "10.0.32.0/19" + }, + "tectonic_aws_region": "us-west-1", + "tectonic_aws_master_ec2_type": "t2.large", + "tectonic_aws_master_root_volume_size": 33, + "tectonic_aws_master_root_volume_type": "gp2", + "tectonic_aws_ssh_key": "some-ssh-key", + "tectonic_aws_vpc_cidr_block": "10.0.0.0/16", + "tectonic_aws_worker_custom_subnets": { + "us-west-1a": "10.0.64.0/19", + "us-west-1c": "10.0.96.0/19" + }, + "tectonic_aws_worker_ec2_type": "t2.medium", + "tectonic_aws_worker_root_volume_iops": 1000, + "tectonic_aws_worker_root_volume_size": 1000, + "tectonic_aws_worker_root_volume_type": "io1", + "tectonic_base_domain": "example.com", + "tectonic_cl_channel": "stable", + "tectonic_cluster_cidr": "10.2.0.0/16", + "tectonic_cluster_name": "test", + "tectonic_dns_name": "test", + "tectonic_experimental": true, + "tectonic_master_count": 1, + "tectonic_service_cidr": "10.3.0.0/16", + "tectonic_worker_count": 3 + } +} diff --git a/installer/examples/metal.json b/installer/frontend/__tests__/examples/metal.json similarity index 100% rename from installer/examples/metal.json rename to installer/frontend/__tests__/examples/metal.json diff --git a/installer/frontend/__tests__/examples/tectonic-aws-vpc.progress b/installer/frontend/__tests__/examples/tectonic-aws-vpc.progress new file mode 100644 index 0000000000..230ad480f6 --- /dev/null +++ b/installer/frontend/__tests__/examples/tectonic-aws-vpc.progress @@ -0,0 +1,60 @@ +{ + "clusterConfig": { + "platformType": "aws-tf", + "aws_ssh": "some-ssh-key", + "aws_etcds-numberOfInstances": 3, + "aws_etcds-instanceType": "t2.large", + "aws_etcds-storageSizeInGiB": 300, + "aws_controllers-numberOfInstances": 1, + "aws_controllers-instanceType": "t2.large", + "aws_controllers-storageSizeInGiB": 33, + "awsCreateVpc": "VPC_PUBLIC", + "awsVpcId": "someVPCID", + "awsControllerSubnetIds": { + "us-west-1a": "subnet-9a7dcafd", + "us-west-1b": "subnet-43ef260a", + "us-west-1c": "subnet-1ad7e242" + }, + "aws_workers-numberOfInstances": 3, + "aws_workers-instanceType": "t2.medium", + "aws_workers-storageSizeInGiB": 1000, + "aws_workers-storageType": "io1", + "aws_workers-storageIOPS": 1500, + "awsWorkerSubnetIds": { + "us-west-1a": "subnet-277ccb40", + "us-west-1b": "subnet-19ef2650", + "us-west-1c": "subnet-36d7e26e" + }, + "extra": { + "awsHostedZoneId": { + "zoneToName": { + "asfd": "example.com" + } + } + }, + "awsHostedZoneId": "asfd", + "awsRegion": "us-west-1", + "awsAccessKeyId": "awsAccessKeyId", + "awsSecretAccessKey": "awsSecretAccessKey", + "awsSessionToken": "awsSessionToken", + "sts_enabled": true, + "caType": "self-signed", + "clusterName": "test", + "clusterSubdomain": "test", + "channelToUse": "stable", + "externalETCDClient": "", + "externalETCDEnabled": false, + "updater_enabled": false, + "tectonicLicense": "", + "pullSecret": "", + "adminEmail": "admin@example.com", + "adminPassword": "PASSWORD", + "awsTags": [ + { + "key": "test_tag", + "value": "testing" + } + ], + "updater": {} + } +} diff --git a/installer/frontend/__tests__/examples/tectonic-aws.progress b/installer/frontend/__tests__/examples/tectonic-aws.progress new file mode 100644 index 0000000000..b281ea2ae5 --- /dev/null +++ b/installer/frontend/__tests__/examples/tectonic-aws.progress @@ -0,0 +1,57 @@ +{ + "clusterConfig": { + "platformType": "aws-tf", + "aws_ssh": "some-ssh-key", + "aws_etcds-numberOfInstances": 3, + "aws_etcds-instanceType": "t2.large", + "aws_etcds-storageSizeInGiB": 300, + "aws_controllers-numberOfInstances": 1, + "aws_controllers-instanceType": "t2.large", + "aws_controllers-storageSizeInGiB": 33, + "awsControllerSubnets": { + "us-west-1a": "10.0.0.0/19", + "us-west-1c": "10.0.32.0/19" + }, + "awsWorkerSubnets": { + "us-west-1a": "10.0.64.0/19", + "us-west-1c": "10.0.96.0/19" + }, + "aws_workers-numberOfInstances": 3, + "aws_workers-instanceType": "t2.medium", + "aws_workers-storageSizeInGiB": 1000, + "aws_workers-storageType": "io1", + "aws_workers-storageIOPS": 1500, + "podCIDR": "10.2.0.0/16", + "serviceCIDR": "10.3.0.0/16", + "extra": { + "awsHostedZoneId": { + "zoneToName": { + "asfd": "example.com" + } + } + }, + "awsHostedZoneId": "asfd", + "awsRegion": "us-west-1", + "awsAccessKeyId": "awsAccessKeyId", + "awsSecretAccessKey": "awsSecretAccessKey", + "awsSessionToken": "awsSessionToken", + "sts_enabled": false, + "caType": "self-signed", + "clusterName": "test", + "clusterSubdomain": "test", + "channelToUse": "stable", + "externalETCDClient": "", + "externalETCDEnabled": false, + "updater_enabled": true, + "tectonicLicense": "", + "pullSecret": "", + "adminEmail": "admin@example.com", + "adminPassword": "PASSWORD", + "awsTags": [ + { + "key": "test_tag", + "value": "testing" + } + ] + } +} diff --git a/installer/examples/tectonic-baremetal.progress b/installer/frontend/__tests__/examples/tectonic-baremetal.progress similarity index 100% rename from installer/examples/tectonic-baremetal.progress rename to installer/frontend/__tests__/examples/tectonic-baremetal.progress diff --git a/installer/frontend/__tests__/protocols.js b/installer/frontend/__tests__/protocols.js new file mode 100644 index 0000000000..ff88e8c297 --- /dev/null +++ b/installer/frontend/__tests__/protocols.js @@ -0,0 +1,90 @@ +/* eslint-env jest, node */ +/* eslint no-sync: "off" */ + +import fs from 'fs'; +import path from 'path'; + +import { reducer } from '../reducer'; +import { restoreActionTypes } from '../actions'; +import { commitToServer } from '../server'; +import '../components/aws-cluster-info'; +import '../components/aws-define-nodes'; +import '../components/aws-vpc'; +import '../components/etcd'; +import '../components/bm-sshkeys'; + +const structureOnly = (obj) => { + const toString = Object.prototype.toString; + + if (toString.call(obj) === '[object Object]') { + const ret = {}; + Object.keys(obj).forEach(k => { + ret[k] = structureOnly(obj[k]); + }); + return ret; + } + + if (Array.isArray(obj)) { + return []; + } + + return ''; +}; + +const initialState = reducer(undefined, {type: 'Some Initial Action'}); + +const tests = [ + { + description: 'works with baremetal', + jsonPath: 'metal.json', + progressPath: 'tectonic-baremetal.progress', + }, + { + description: 'works with aws', + jsonPath: 'aws.json', + progressPath: 'tectonic-aws.progress', + }, + { + description: 'works with aws (existing subnets)', + jsonPath: 'aws-vpc.json', + progressPath: 'tectonic-aws-vpc.progress', + }, +]; + +let dispatch; + +beforeEach(() => { + dispatch = jest.fn(); +}); + +const readExample = example => JSON.parse(fs.readFileSync(path.resolve(__dirname, `examples/${example}`), 'utf8')); + +/* eslint-disable max-nested-callbacks */ +describe('progress file example', () => { + tests.forEach(t => { + const example = readExample(t.jsonPath); + const payload = readExample(t.progressPath); + + it(t.description, () => { + const restored = reducer(initialState, { + type: restoreActionTypes.RESTORE_STATE, payload, + }); + + global.fetch = jest.fn(() => Promise.resolve({ + ok: true, + blob: () => Promise.resolve('success'), + text: () => Promise.reject('failed'), + json: () => Promise.resolve({}), + })); + + // TODO: wait for this action to finish & then check expected state + commitToServer(false)(dispatch, () => restored); + + expect(fetch.mock.calls.length).toBe(1); + const body = JSON.parse(fetch.mock.calls[0][1].body); + + expect(example).toEqual(body); + }); + }); +}); +/* eslint-enable max-nested-callbacks */