/**
  * Execute the console command.
  *
  * @return mixed
  */
 public function fire()
 {
     // This process isn't necessary for resellers
     if ('true' == env('RESELLER')) {
         dd('We are a reseller.');
     }
     // Grab all new events concerning virtual machine creation or service offering changes.
     $eventId = Config::firstOrCreate(['parameter' => 'lastEventId']);
     if (null == $eventId->data) {
         $eventId->data = 0;
     }
     // Initialize the parameter with a value.
     $this->info('Last Processed Event ID is: [' . $eventId->data . ']');
     $maxEventId = UsageEvent::max('id');
     $this->info('Max ID in Event table: [' . $maxEventId . ']');
     if ($eventId->data == $maxEventId) {
         // If there are no new events, no processing is required.
         exit;
     }
     $events = UsageEvent::where('id', '>', $eventId->data)->where('id', '<=', $maxEventId)->where(function ($query) {
         $query->where('type', '=', 'VM.CREATE')->orWhere('type', '=', 'VM.UPGRADE');
     })->get();
     // Iterate over each event and process
     $events->each(function ($event) {
         // In this context:
         // resource_id = vm_instance_id
         // type = Event type
         // offering_id = service_offering_id
         // Grab the Service Offering of the VM the event concerns if it is customized.
         $this->info('VM_ID: [' . $event->resource_id . '] Type: [' . $event->type . '] SO_ID: [' . $event->offering_id . ']');
         $so = DB::connection('cloud')->table('service_offering')->whereId($event->offering_id)->whereNull('cpu')->whereNull('speed')->whereNull('ram_size')->first();
         // If we have a result, the Service Offering is custom.
         if (isset($so->id)) {
             $this->info('We have a custom service offering');
             // We need to grab the custom fields for this VM.
             $vmDetails = \App\VmInstance::find($event->resource_id)->details->toArray();
             $resources = array();
             foreach ($vmDetails as $detail) {
                 if ('cpuNumber' == $detail->name || 'cpuSpeed' == $detail->name || 'memory' == $detail->name) {
                     $resources["{$detail->name}"] = $detail->value;
                 }
             }
             $resources['vmInstanceId'] = $event->resource_id;
             VmResources::create($resources);
         }
     });
     // Set the last processed record ID so we don't go over records multiple times.
     $eventId->data = $maxEventId;
     $eventId->save();
 }
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function fire()
 {
     // Setup lists to look up ACS IDs.
     // We need: zones, accounts, domains, instances, service offerings and templates.
     $dataTypes = ['cloud.data_center' => 'zones', 'cloud.domain' => 'domains', 'cloud.account' => 'accounts', 'cloud.vm_instance' => 'instances', 'cloud.service_offering_view' => 'serviceofferings', 'cloud.template_view' => 'templates'];
     $uuidLookup = [];
     foreach ($dataTypes as $table => $type) {
         $dbInfo = DB::table($table)->get();
         $uuidLookup[$type] = [];
         foreach ($dbInfo as $info) {
             $uuidLookup[$type][$info->id] = $info->uuid;
         }
     }
     $diskInfo = DB::table('cloud.disk_offering')->get();
     $diskOfferings = [];
     foreach ($diskInfo as $do) {
         $diskOfferings[$do->id] = $do->tags;
     }
     // Grab yesterday's records
     $yesterday = date('Y-m-d', time() - 84600);
     $records = App\CloudUsage::like('start_date', $yesterday . '%')->billable()->get()->each(function ($record) use($uuidLookup, $diskOfferings) {
         $recordType = '';
         switch ($record->usage_type) {
             case 2:
                 $recordType = 'VM Instance';
                 // Grab the service offering of the VM
                 $serviceOffering = App\ServiceOffering::find($record->offering_id);
                 if (null == $serviceOffering->cpu && null == $serviceOffering->speed && null == $serviceOffering->ram_size) {
                     // Our service offering is Custom.  Grab its resources from our custom table.
                     $resources = App\VmResources::find($record->vm_instance_id);
                     $cpuNumber = $resources->cpuNumber;
                     $cpuSpeed = $resources->cpuSpeed;
                     $memory = $resources->memory;
                 } else {
                     $cpuNumber = $serviceOffering->cpu;
                     $cpuSpeed = $serviceOffering->speed;
                     $memory = $serviceOffering->ram_size;
                 }
                 App\UsageVm::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'vm_name' => $record->vm_name, 'type' => 'VM', 'usage' => $record->raw_usage, 'vmInstanceId' => $uuidLookup['instances'][$record->vm_instance_id], 'serviceOfferingId' => $uuidLookup['serviceofferings'][$record->offering_id], 'templateId' => $uuidLookup['templates'][$record->template_id], 'cpuNumber' => $cpuNumber, 'cpuSpeed' => $cpuSpeed, 'memory' => $memory, 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             case 4:
             case 5:
                 $recordType = 'Network Usage';
                 App\UsageGeneral::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'type' => stripos($record->usage_display, 'Received') === false ? 'Network Sent' : 'Network Received', 'usage' => $record->raw_usage, 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             case 6:
                 $recordType = 'Disk/Volume';
                 // Fetch the VM instance this volume belongs to.
                 $vol = App\Volume::find($record->usage_id);
                 try {
                     $instance = App\VmInstance::find($vol->instance_id);
                 } catch (\Exception $e) {
                     continue;
                     // Ignored bad record.
                 }
                 if (!$instance instanceof App\VmInstance) {
                     continue;
                 }
                 // Ignore this record, its bad for some reason.
                 App\UsageDisk::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'volumeId' => $vol->uuid, 'type' => $vol->volume_type == 'ROOT' ? 'Root Volume' : 'Volume', 'tags' => $diskOfferings[$vol->disk_offering_id], 'usage' => $record->raw_usage, 'size' => $record->size, 'vmInstanceId' => $uuidLookup['instances'][$instance->id], 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             case 9:
                 $recordType = 'Snapshot';
                 App\UsageDisk::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'type' => 'Snapshot', 'usage' => $record->raw_usage, 'size' => $record->size, 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             case 11:
                 $recordType = 'Load Balancer';
                 App\UsageGeneral::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'type' => 'LB', 'usage' => $record->raw_usage, 'vmInstanceId' => $uuidLookup['instances'][$record->vm_instance_id], 'templateId' => $uuidLookup['templates'][$record->template_id], 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             case 12:
                 $recordType = 'Port Forward';
                 App\UsageGeneral::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'type' => 'PF', 'usage' => $record->raw_usage, 'vmInstanceId' => $uuidLookup['instances'][$record->vm_instance_id], 'templateId' => $uuidLookup['templates'][$record->template_id], 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             case 14:
                 $recordType = 'VPN';
                 App\UsageGeneral::create(['zoneId' => $uuidLookup['zones'][$record->zone_id], 'accountId' => $uuidLookup['accounts'][$record->account_id], 'domainId' => $uuidLookup['domains'][$record->domain_id], 'type' => 'VPN', 'usage' => $record->raw_usage, 'vmInstanceId' => $uuidLookup['instances'][$record->vm_instance_id], 'templateId' => $uuidLookup['templates'][$record->template_id], 'startDate' => $record->start_date, 'endDate' => $record->end_date]);
                 break;
             default:
                 $recordType = 'Unknown (' . $record->usage_type . ')';
                 break;
         }
         $this->info('Found a record of type ' . $recordType);
     });
 }