-
-
Save roderik/1ff8d4df9c76f13f7441f7e5c34cc7dd to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as pulumi from '@pulumi/pulumi'; | |
import { ClusterProvider } from '../../enums/clusterprovider.enum'; | |
import { ClusterRegion } from '../../enums/clusterregion.enum'; | |
import { ClusterSize } from '../../enums/clustersize.enum'; | |
process.env.TEST_SUITE = 'ClusterResource'; | |
pulumi.runtime.setMocks({ | |
newResource: function (type: string, name: string, inputs: any): { id: string; state: any } { | |
return { | |
id: `${inputs.name}_id`, | |
state: inputs, | |
}; | |
}, | |
call: function (token: string, args: any, provider?: string) { | |
return args; | |
}, | |
}); | |
describe('ClusterResource', () => { | |
let bpaas: typeof import('./cluster.resource'); | |
beforeAll(async function () { | |
// It's important to import the program _after_ the mocks are defined. | |
bpaas = await import('./cluster.resource'); | |
}); | |
it('should be able to create a GKE cluster', async () => { | |
return await new Promise((resolve) => { | |
const cluster = new bpaas.ClusterResource('test1', ClusterProvider.GKE, ClusterRegion.EUROPE, ClusterSize.LARGE); | |
pulumi.all([cluster.kubeconfig]).apply(([kubeconfig]) => { | |
expect(kubeconfig).toContain('cmd-path: gcloud'); | |
resolve(true); | |
}); | |
}); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as gcp from '@pulumi/gcp'; | |
import { all, ComponentResource, ComponentResourceOptions, Output } from '@pulumi/pulumi'; | |
import { ClusterProvider } from '../../enums/clusterprovider.enum'; | |
import { ClusterRegion } from '../../enums/clusterregion.enum'; | |
import { ClusterSize } from '../../enums/clustersize.enum'; | |
// enum EKSLocation { | |
// EUROPE = 'eu-west-3', | |
// UNITED_STATES = 'us-east-2', | |
// INDIA = 'ap-south-1', | |
// SINGAPORE = 'ap-southeast-1', | |
// } | |
// | |
// enum AKSLocation { | |
// UNITED_STATES = 'westus2', | |
// EUROPE = 'westeurope', | |
// INDIA = 'centralindia', | |
// SINGAPORE = 'southeastasia', | |
// } | |
enum GKELocation { | |
UNITED_STATES = 'us-west1-b', | |
EUROPE = 'europe-west1-b', | |
INDIA = 'asia-south1-b', | |
SINGAPORE = 'asia-southeast1-b', | |
} | |
enum GKEMachineType { | |
SMALL = 'e2-standard-2', // 2cpu / 8gb / 4gbps | |
MEDIUM = 'e2-standard-4', // 4cpu / 16gb / 8gbps | |
LARGE = 'e2-standard-8', // 8cpu / 32gb / 16gbps | |
} | |
export class ClusterResource extends ComponentResource { | |
public kubeconfig: Output<string>; | |
constructor( | |
name: string, | |
provider: ClusterProvider, | |
region: ClusterRegion, | |
size: ClusterSize, | |
opts: ComponentResourceOptions = {} | |
) { | |
super('bpaas:cluster', name, {}, { ...opts }); | |
switch (provider) { | |
case ClusterProvider.GKE: { | |
// Find the latest GKE Version | |
const engineVersion = gcp.container.getEngineVersions().then((v) => v.latestMasterVersion); | |
// Build the GKE cluster | |
const cluster = new gcp.container.Cluster( | |
name, | |
{ | |
name: `v4-${name}`, | |
location: GKELocation[region], | |
minMasterVersion: engineVersion, | |
nodeVersion: engineVersion, | |
nodePools: [ | |
{ | |
name: `v4-${name}-np`, | |
nodeConfig: { | |
machineType: GKEMachineType[size], | |
diskType: 'pd-ssd', | |
diskSizeGb: 20, | |
shieldedInstanceConfig: { | |
enableIntegrityMonitoring: true, | |
}, | |
oauthScopes: [ | |
'https://www.googleapis.com/auth/compute', | |
'https://www.googleapis.com/auth/devstorage.read_only', | |
'https://www.googleapis.com/auth/logging.write', | |
'https://www.googleapis.com/auth/monitoring', | |
], | |
}, | |
autoscaling: { | |
minNodeCount: 1, | |
maxNodeCount: 2, | |
}, | |
initialNodeCount: 1, | |
management: { | |
autoUpgrade: true, | |
autoRepair: true, | |
}, | |
upgradeSettings: { | |
maxSurge: 2, | |
maxUnavailable: 1, | |
}, | |
}, | |
], | |
addonsConfig: { | |
httpLoadBalancing: { | |
disabled: false, | |
}, | |
horizontalPodAutoscaling: { | |
disabled: true, | |
}, | |
dnsCacheConfig: { | |
enabled: false, | |
}, | |
}, | |
clusterAutoscaling: { | |
enabled: false, | |
autoscalingProfile: 'OPTIMIZE_UTILIZATION', | |
}, | |
verticalPodAutoscaling: { | |
enabled: true, | |
}, | |
enableShieldedNodes: true, | |
clusterTelemetry: { | |
type: 'ENABLED', | |
}, | |
masterAuth: { | |
clientCertificateConfig: { | |
issueClientCertificate: true, | |
}, | |
}, | |
}, | |
{ | |
ignoreChanges: ['initialNodeCount'], | |
parent: this, | |
} | |
); | |
// Manufacture a GKE-style kubeconfig. Note that this is slightly "different" | |
// because of the way GKE requires gcloud to be in the picture for cluster | |
// authentication (rather than using the client cert/key directly). | |
this.kubeconfig = all([cluster.name, cluster.endpoint, cluster.masterAuth]).apply( | |
([name, endpoint, masterAuth]) => { | |
const context = `v4-${name}_${region}`; | |
return `apiVersion: v1 | |
clusters: | |
- cluster: | |
certificate-authority-data: ${masterAuth.clusterCaCertificate} | |
server: https://${endpoint} | |
name: ${context} | |
contexts: | |
- context: | |
cluster: ${context} | |
user: ${context} | |
name: ${context} | |
current-context: ${context} | |
kind: Config | |
preferences: {} | |
users: | |
- name: ${context} | |
user: | |
auth-provider: | |
config: | |
cmd-args: config config-helper --format=json | |
cmd-path: gcloud | |
expiry-key: '{.credential.token_expiry}' | |
token-key: '{.credential.access_token}' | |
name: gcp | |
`; | |
} | |
); | |
break; | |
} | |
case ClusterProvider.EKS: { | |
break; | |
} | |
case ClusterProvider.AKS: { | |
break; | |
} | |
default: { | |
throw new Error(`Unknown cluster provider! ${provider}`); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
● Cannot log after tests are done. Did you forget to wait for something async in your test? | |
Attempted to log "unhandled rejection: CONTEXT(221): monitor.registerResourceOutputs(...)-initial | |
STACK_TRACE: | |
Error | |
at Object.debuggablePromise (/Users/roderik/Development/bpaas-launchpad/packages/launchpad-api/node_modules/@pulumi/pulumi/runtime/debuggable.js:69:75) | |
at runAsyncResourceOp (/Users/roderik/Development/bpaas-launchpad/packages/launchpad-api/node_modules/@pulumi/pulumi/runtime/resource.js:634:75) | |
at Object.registerResourceOutputs (/Users/roderik/Development/bpaas-launchpad/packages/launchpad-api/node_modules/@pulumi/pulumi/runtime/resource.js:553:5) | |
at ClusterResource.registerOutputs (/Users/roderik/Development/bpaas-launchpad/packages/launchpad-api/node_modules/@pulumi/pulumi/resource.js:444:20) | |
at ClusterResource.<anonymous> (/Users/roderik/Development/bpaas-launchpad/packages/launchpad-api/node_modules/@pulumi/pulumi/resource.js:410:18) | |
at Generator.next (<anonymous>) | |
at fulfilled (/Users/roderik/Development/bpaas-launchpad/packages/launchpad-api/node_modules/@pulumi/pulumi/resource.js:18:58) | |
at processTicksAndRejections (node:internal/process/task_queues:93:5)". | |
at Object.debuggablePromise (node_modules/@pulumi/pulumi/runtime/debuggable.js:69:75) | |
at runAsyncResourceOp (node_modules/@pulumi/pulumi/runtime/resource.js:634:75) | |
at Object.registerResourceOutputs (node_modules/@pulumi/pulumi/runtime/resource.js:553:5) | |
at ClusterResource.registerOutputs (node_modules/@pulumi/pulumi/resource.js:444:20) | |
at ClusterResource.<anonymous> (node_modules/@pulumi/pulumi/resource.js:410:18) | |
at fulfilled (node_modules/@pulumi/pulumi/resource.js:18:58) | |
at console.log (../../node_modules/@jest/console/build/BufferedConsole.js:197:10) | |
at process.<anonymous> (node_modules/@pulumi/pulumi/runtime/debuggable.js:108:17) | |
● Cannot log after tests are done. Did you forget to wait for something async in your test? | |
Attempted to log "unhandled rejection: CONTEXT(221): monitor.registerResourceOutputs(...)-initial | |
STACK_TRACE: | |
Error | |
at Object.debuggablePromise (/Users/roderik/Development/bpaas-launchpad/packages/launchpad-api/node_modules/@pulumi/pulumi/runtime/debuggable.js:69:75) | |
at runAsyncResourceOp (/Users/roderik/Development/bpaas-launchpad/packages/launchpad-api/node_modules/@pulumi/pulumi/runtime/resource.js:634:75) | |
at Object.registerResourceOutputs (/Users/roderik/Development/bpaas-launchpad/packages/launchpad-api/node_modules/@pulumi/pulumi/runtime/resource.js:553:5) | |
at ClusterResource.registerOutputs (/Users/roderik/Development/bpaas-launchpad/packages/launchpad-api/node_modules/@pulumi/pulumi/resource.js:444:20) | |
at ClusterResource.<anonymous> (/Users/roderik/Development/bpaas-launchpad/packages/launchpad-api/node_modules/@pulumi/pulumi/resource.js:410:18) | |
at Generator.next (<anonymous>) | |
at fulfilled (/Users/roderik/Development/bpaas-launchpad/packages/launchpad-api/node_modules/@pulumi/pulumi/resource.js:18:58) | |
at processTicksAndRejections (node:internal/process/task_queues:93:5)". | |
at Object.debuggablePromise (node_modules/@pulumi/pulumi/runtime/debuggable.js:69:75) | |
at runAsyncResourceOp (node_modules/@pulumi/pulumi/runtime/resource.js:634:75) | |
at Object.registerResourceOutputs (node_modules/@pulumi/pulumi/runtime/resource.js:553:5) | |
at ClusterResource.registerOutputs (node_modules/@pulumi/pulumi/resource.js:444:20) | |
at ClusterResource.<anonymous> (node_modules/@pulumi/pulumi/resource.js:410:18) | |
at fulfilled (node_modules/@pulumi/pulumi/resource.js:18:58) | |
at console.log (../../node_modules/@jest/console/build/BufferedConsole.js:197:10) | |
at process.<anonymous> (node_modules/@pulumi/pulumi/runtime/debuggable.js:108:17) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment