import { Factory, trait } from 'ember-cli-mirage'; import faker from 'nomad-ui/mirage/faker'; import { provide } from '../utils'; import { DATACENTERS, HOSTS, generateResources } from '../common'; import moment from 'moment'; const UUIDS = provide(100, faker.random.uuid.bind(faker.random)); const NODE_STATUSES = ['initializing', 'ready', 'down']; const NODE_CLASSES = provide(7, faker.company.bsBuzz.bind(faker.company)); const REF_DATE = new Date(); export default Factory.extend({ id: i => (i / 100 >= 1 ? `${UUIDS[i]}-${i}` : UUIDS[i]), name: i => `nomad@${HOSTS[i % HOSTS.length]}`, datacenter: () => faker.helpers.randomize(DATACENTERS), nodeClass: () => faker.helpers.randomize(NODE_CLASSES), drain: faker.random.boolean, status: () => faker.helpers.randomize(NODE_STATUSES), tls_enabled: faker.random.boolean, schedulingEligibility: () => (faker.random.boolean() ? 'eligible' : 'ineligible'), createIndex: i => i, modifyIndex: () => faker.random.number({ min: 10, max: 2000 }), httpAddr() { return this.name.split('@')[1]; }, forceIPv4: trait({ name: i => { const ipv4Hosts = HOSTS.filter(h => !h.startsWith('[')); return `nomad@${ipv4Hosts[i % ipv4Hosts.length]}`; }, }), draining: trait({ drain: true, schedulingEligibility: 'ineligible', drainStrategy: { Deadline: faker.random.number({ min: 30 * 1000, max: 5 * 60 * 60 * 1000 }) * 1000000, ForceDeadline: moment(REF_DATE).add(faker.random.number({ min: 1, max: 5 }), 'd'), IgnoreSystemJobs: faker.random.boolean(), }, }), forcedDraining: trait({ drain: true, schedulingEligibility: 'ineligible', drainStrategy: { Deadline: -1, ForceDeadline: '0001-01-01T00:00:00Z', IgnoreSystemJobs: faker.random.boolean(), }, }), noDeadlineDraining: trait({ drain: true, schedulingEligibility: 'ineligible', drainStrategy: { Deadline: 0, ForceDeadline: '0001-01-01T00:00:00Z', IgnoreSystemJobs: faker.random.boolean(), }, }), noHostVolumes: trait({ hostVolumes: () => ({}), }), drainStrategy: null, drivers: makeDrivers, hostVolumes: makeHostVolumes, resources: generateResources, attributes() { // TODO add variability to these return { 'os.version': '10.12.5', 'cpu.modelname': 'Intel(R) Core(TM) i7-3615QM CPU @ 2.30GHz', 'nomad.revision': 'f551dcb83e3ac144c9dbb90583b6e82d234662e9', 'driver.docker.volumes.enabled': '1', 'driver.docker': '1', 'cpu.frequency': '2300', 'memory.totalbytes': '17179869184', 'driver.mock_driver': '1', 'kernel.version': '16.6.0', 'unique.network.ip-address': '127.0.0.1', 'nomad.version': '0.5.5dev', 'unique.hostname': 'bacon-mac', 'cpu.arch': 'amd64', 'os.name': 'darwin', 'kernel.name': 'darwin', 'unique.storage.volume': '/dev/disk1', 'driver.docker.version': '17.03.1-ce', 'cpu.totalcompute': '18400', 'unique.storage.bytestotal': '249783500800', 'cpu.numcores': '8', 'os.signals': 'SIGCONT,SIGSTOP,SIGSYS,SIGINT,SIGIOT,SIGXCPU,SIGSEGV,SIGUSR1,SIGTTIN,SIGURG,SIGUSR2,SIGABRT,SIGALRM,SIGCHLD,SIGFPE,SIGTSTP,SIGIO,SIGKILL,SIGQUIT,SIGXFSZ,SIGBUS,SIGHUP,SIGPIPE,SIGPROF,SIGTRAP,SIGTTOU,SIGILL,SIGTERM', 'driver.raw_exec': '1', 'unique.storage.bytesfree': '142954643456', }; }, withMeta: trait({ meta: { just: 'some', prop: 'erties', 'over.here': 100, }, }), afterCreate(node, server) { // Each node has a corresponding client stat resource that's queried via node IP. // Create that record, even though it's not a relationship. server.create('client-stat', { id: node.httpAddr, }); const events = server.createList('node-event', faker.random.number({ min: 1, max: 10 }), { nodeId: node.id, }); node.update({ eventIds: events.mapBy('id'), }); server.create('client-stat', { id: node.id, }); }, }); function makeDrivers() { const generate = name => { const detected = faker.random.number(10) >= 3; const healthy = detected && faker.random.number(10) >= 3; const attributes = { [`driver.${name}.version`]: '1.0.0', [`driver.${name}.status`]: 'awesome', [`driver.${name}.more.details`]: 'yeah', [`driver.${name}.more.again`]: 'we got that', }; return { Detected: detected, Healthy: healthy, HealthDescription: healthy ? 'Driver is healthy' : 'Uh oh', UpdateTime: faker.date.past(5 / 365, REF_DATE), Attributes: faker.random.number(10) >= 3 && detected ? attributes : null, }; }; return { docker: generate('docker'), rkt: generate('rkt'), qemu: generate('qemu'), exec: generate('exec'), raw_exec: generate('raw_exec'), java: generate('java'), }; } function makeHostVolumes() { const generate = () => ({ Name: faker.internet.domainWord(), Path: `/${faker.internet.userName()}/${faker.internet.domainWord()}/${faker.internet.color()}`, ReadOnly: faker.random.boolean(), }); const volumes = provide(faker.random.number({ min: 1, max: 5 }), generate); return volumes.reduce((hash, volume) => { hash[volume.Name] = volume; return hash; }, {}); }