Пример #1
0
 /**
  * Handle an incoming request.
  *
  * @param  \Illuminate\Http\Request  $request
  * @param  \Closure  $next
  * @return mixed
  */
 public function handle($request, Closure $next)
 {
     $setupComplete = SiteConfig::whereParameter('setupComplete')->first();
     if ($setupComplete->data == 'false') {
         return redirect('/admin/setup');
     }
     return $next($request);
 }
Пример #2
0
 /**
  * Create a new user instance after a valid registration.
  *
  * @param  array $data
  * @return User
  */
 public function create(array $data)
 {
     $paymentType = SiteConfig::whereParameter('defaultPaymentType')->first();
     //        system("curl --data \"[StratoSTACK] {$data['email']} registered as a new user.\" -s 'https://1stel.slack.com/services/hooks/slackbot?token=oxHCUBstAR4y9p9dvj8FE5Jr&channel=%23devops'");
     $user = User::create(['name' => $data['name'], 'email' => $data['email'], 'password' => bcrypt($data['password']), 'access' => 'User', 'paymentTypeOverride' => $paymentType->data, 'email_token' => bin2hex(openssl_random_pseudo_bytes(10))]);
     event(new \App\Events\UserHasRegistered($user));
     return $user;
 }
 public function index()
 {
     //
     $acs_id = Auth::User()->email;
     $domain = SiteConfig::whereParameter('domainId')->first();
     $keys = app('Cloudstack\\CloudStackClient')->listSSHKeyPairs(['account' => $acs_id, 'domainid' => $domain->data]);
     //dd($keys);
     return view('settings.security')->with(compact('keys'));
 }
 /**
  * Bootstrap the application services.
  *
  * @return void
  */
 public function boot()
 {
     $mgmtServer = SiteConfig::whereParameter('mgmtServer')->first();
     $apiKey = SiteConfig::whereParameter('apiKey')->first();
     $secretKey = SiteConfig::whereParameter('secretKey')->first();
     // Endpoint, API Key, Secret Key
     try {
         $this->cloudstack = new CloudStackClient($mgmtServer->data, $apiKey->data, $secretKey->data);
     } catch (\Exception $e) {
         $this->cloudstack = ['error' => $e->getMessage()];
     }
 }
 public function getPricing()
 {
     $priceMethod = SiteConfig::whereParameter('priceMethod')->first();
     if ($priceMethod->data == 'fixedRatio') {
         $prices = SiteConfig::where('parameter', 'LIKE', '%Price')->get();
     } else {
         if ($priceMethod->data == 'elementPrice') {
             $prices = ElementPrice::whereActive('1')->get();
         }
     }
     return response()->json(['priceMethod' => $priceMethod->data, 'prices' => $prices->toArray()]);
 }
 public function updateFixed(Request $request)
 {
     foreach ($request->all() as $key => $val) {
         if (strpos($key, 'Price') !== FALSE) {
             $price = SiteConfig::firstOrCreate(['parameter' => $key]);
             $price->data = $val;
             $price->save();
             unset($price);
         }
     }
     return redirect()->back();
 }
 public function run()
 {
     DB::table('site_config')->delete();
     SiteConfig::create(['parameter' => 'priceMethod']);
     SiteConfig::create(['parameter' => 'corePrice']);
     SiteConfig::create(['parameter' => 'ramPrice']);
     SiteConfig::create(['parameter' => 'setupComplete', 'data' => '0']);
     // Management server settings
     SiteConfig::create(['parameter' => 'mgmtServer']);
     SiteConfig::create(['parameter' => 'apiKey']);
     SiteConfig::create(['parameter' => 'secretKey']);
     // Billing settings
     SiteConfig::create(['parameter' => 'hoursInMonth']);
 }
 public function update(Request $request)
 {
     $user = Auth::User();
     $domainId = SiteConfig::whereParameter('domainId')->first();
     $this->validate($request, ['name' => 'required|max:255', 'email' => 'required|email|max:255|unique:users,id,' . $user->id, 'password' => 'required_with:new_password|min:6', 'new_password' => 'confirmed|min:6']);
     if ($user->name != $request['name']) {
         // Change name in DB
         $user->name = $request['name'];
         // Set the name for ACS
         list($userData['firstname'], $userData['lastname']) = explode(' ', $request['name'], 2);
     }
     if ($user->email != $request['email']) {
         // Copy the email for lookup purposes
         $origEmail = $user->email;
         // Update the email data in the DB
         $user->email = $request['email'];
         // Two changes are necessary in ACS: at the User and Account levels
         $userData['email'] = $request['email'];
         $userData['username'] = $request['email'];
         $accountData['newname'] = $request['email'];
     }
     if (isset($request['new_password']) && '' != $request['new_password']) {
         $user->password = bcrypt($request['new_password']);
         $userData['password'] = $request['new_password'];
         Mail::send('emails.password_changed', [], function ($m) use($user) {
             $m->from('*****@*****.**', 'StratoSTACK');
             $m->to($user->email, $user->name)->subject('Password changed');
         });
     }
     if (!isset($userData) && !isset($accountData)) {
         // May do something here later.
     }
     // Check to see if we have changes that need to touch the Cloudstack system.
     if (isset($userData)) {
         $userData['id'] = $user->acs_id;
         $userRequest = $this->acs->updateUser($userData);
     }
     if (isset($accountData)) {
         $accountData['account'] = $origEmail;
         $accountData['domainid'] = $domainId->data;
         $accountRequest = $this->acs->updateAccount($accountData);
     }
     // Update the database
     $user->save();
     flash()->success('Updated user profile.');
     // Add message indicating save.
     return redirect()->route('settings.profile');
 }
 public function updateCloud()
 {
     $recordsServer = SiteConfig::whereParameter('recordsUrl')->first();
     $client = new Client(['base_uri' => $recordsServer->data]);
     $data = $client->get("api/getPricing");
     $pricing = json_decode($data->getBody());
     $data = $client->get("api/getResourceLimits");
     $resourceLimits = json_decode($data->getBody());
     foreach ($resourceLimits as $resource => $limit) {
         $dbEntry = SiteConfig::firstOrCreate(['parameter' => 'RL' . $resource]);
         $dbEntry->data = $limit;
         $dbEntry->save();
     }
     flash()->success('Cloud settings successfully updated.');
     return redirect()->route('admin.settings.index');
 }
Пример #10
0
 public function save(Request $request)
 {
     $this->validate($request, ['recordsUrl' => 'required|url', 'domainId' => 'required']);
     $acsCfg = Config::get('cloud.mgmtServer');
     $acs = new CloudStackClient($acsCfg['url'], $acsCfg['apiKey'], $acsCfg['secretKey']);
     if (is_array($acs)) {
         return back()->withErrors(['message' => $acs['error']]);
     }
     $zones = $acs->listZones();
     if (isset($zones->errorcode)) {
         return back()->withErrors(['message' => 'Unable to verify user credentials.']);
     }
     // We've received some data back now, so its ok to save the credentials.
     $hypervisors = [];
     try {
         $zones = $acs->listZones();
         foreach ($zones as $zone) {
             $hyperQuery = $acs->listHypervisors(['zoneid' => $zone->id]);
             foreach ($hyperQuery as $hypervisor) {
                 if (!in_array($hypervisor->name, $hypervisors)) {
                     $hypervisors[] = $hypervisor->name;
                 }
             }
         }
     } catch (\Exception $e) {
         return back()->withErrors(['message' => $e->getMessage()]);
     }
     if (count($hypervisors) > 1) {
         return back()->withErrors(['message' => 'More than one hypervisor type detected.  Multiple hypervisor types not supported.']);
     } else {
         $hypervisor = $hypervisors[0];
     }
     $recordsUrl = SiteConfig::whereParameter('recordsUrl')->firstOrFail();
     $recordsUrl->data = $request->recordsUrl;
     $recordsUrl->save();
     $dbHypervisor = SiteConfig::whereParameter('hypervisor')->firstOrFail();
     $dbHypervisor->data = $hypervisor;
     $dbHypervisor->save();
     $domainId = SiteConfig::whereParameter('domainId')->firstOrFail();
     $domainId->data = $request->domainId;
     $domainId->save();
     $setup = SiteConfig::whereParameter('setupComplete')->first();
     $setup->data = 'true';
     $setup->save();
     return redirect('/admin/');
 }
Пример #11
0
 /**
  * Show the form for creating a new resource.
  *
  * @return Response
  */
 public function create()
 {
     // Gather resource limits
     $cpuData = SiteConfig::whereParameter('RLcpu_number')->first();
     $ramData = SiteConfig::whereParameter('RLram')->first();
     $diskData = DiskType::all();
     $cpuLimit = $cpuData->data;
     $ramLimit = [];
     $disks = [];
     for ($i = 1; $i <= $ramData->data; $i++) {
         $ramLimit[$i * 1024] = $i;
     }
     foreach ($diskData as $disk) {
         $disks[$disk->id] = $disk->display_text;
     }
     return view('admin.package.create')->with(compact('cpuLimit', 'ramLimit', 'disks'));
 }
 /**
  * Handle the event.
  *
  * @param  UserWasCreated  $event
  * @return void
  */
 public function handle(UserWasCreated $event)
 {
     // $event has user at $user.
     // Extract first and last name.  ACS wants them separate.
     if (str_word_count($event->user->name) > 1) {
         list($fname, $lname) = explode(' ', $event->user->name, 2);
     } else {
         $fname = $event->user->name;
         $lname = ' ';
     }
     // Grab Site Configuration
     $cfg = SiteConfig::all()->makeKVArray();
     $acsData = ['accounttype' => '0', 'email' => $event->user->email, 'firstname' => $fname, 'lastname' => $lname, 'password' => $event->user->password, 'username' => $event->user->email, 'domainid' => $cfg['domainId']];
     $result = app('Cloudstack\\CloudStackClient')->createAccount($acsData);
     // !!NEEDS REVISION!! Error checking
     $event->user->acs_id = $result->account->user[0]->id;
     $event->user->save();
 }
Пример #13
0
 public function run()
 {
     DB::table('site_config')->delete();
     SiteConfig::create(['parameter' => 'setupComplete', 'data' => 'false']);
     SiteConfig::create(['parameter' => 'defaultPaymentType', 'data' => 'PostPay']);
     SiteConfig::create(['parameter' => 'hoursInMonth', 'data' => '672']);
     SiteConfig::create(['parameter' => 'domainId', 'data' => '']);
     SiteConfig::create(['parameter' => 'creditLimit', 'data' => '100']);
     SiteConfig::create(['parameter' => 'rootdiskresize', 'data' => 'FALSE']);
     SiteConfig::create(['parameter' => 'recordsUrl', 'data' => '']);
     SiteConfig::create(['parameter' => 'hypervisor', 'data' => '']);
     SiteConfig::create(['parameter' => 'vouchers', 'data' => '10']);
     SiteConfig::create(['parameter' => 'voucherAmount', 'data' => '25']);
     SiteConfig::create(['parameter' => 'lastBillRecordDate', 'data' => '2015-08-01']);
     SiteConfig::create(['parameter' => 'dnsServer', 'data' => '']);
     SiteConfig::create(['parameter' => 'dnsApiKey', 'data' => '']);
     SiteConfig::create(['parameter' => 'grandfatherPricing', 'data' => 'NO']);
     //        SiteConfig::create(['parameter' => '', 'data' => '']);
 }
Пример #14
0
 /**
  * Handle the event.
  *
  * @param  UserWasCreated  $event
  * @return void
  */
 public function handle(UserWasCreated $event)
 {
     // When we create a user, also create some vouchers for the user if we need to
     // User data is in $event->user
     $numVouchers = SiteConfig::whereParameter('vouchers')->first();
     if ($numVouchers->data > 1) {
         $voucherAmount = SiteConfig::whereParameter('voucherAmount')->first();
         static $randList = 'ABCDEF123456789';
         $randLen = strlen($randList) - 1;
         for ($i = 0; $i < $numVouchers->data; $i++) {
             $voucherNum = '';
             for ($j = 0; $j < 10; $j++) {
                 $num = rand(0, $randLen);
                 $voucherNum .= $randList[$num];
             }
             $vouchers[] = new Voucher(['number' => $voucherNum, 'type' => 'Unknown', 'amount' => $voucherAmount->data]);
         }
         $event->user->vouchers()->saveMany($vouchers);
     }
 }
Пример #15
0
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function fire()
 {
     //
     //        $siteCfg = SiteConfig::all()->makeKVArray();
     $siteCfg = ['domainId' => SiteConfig::whereParameter('domainId')->first()->data, 'apiKey' => Config::get('cloud.mgmtServer.apiKey'), 'secretKey' => Config::get('cloud.mgmtServer.secretKey'), 'lastBillRecordDate' => SiteConfig::whereParameter('lastBillRecordDate')->first()->data];
     // Setup HTTP request for the records
     $url = SiteConfig::whereParameter('recordsUrl')->first()->data;
     $client = new Client(['base_uri' => $url]);
     $data = $client->get("api/getRecords/domainid/{$siteCfg['domainId']}/apiKey/{$siteCfg['apiKey']}/secretKey/{$siteCfg['secretKey']}/lastDate/{$siteCfg['lastBillRecordDate']}");
     $records = json_decode($data->getBody());
     foreach ($records->instances as $instanceRecord) {
         $keys = ['zoneId', 'accountId', 'vm_name', 'usage', 'vmInstanceId', 'serviceOfferingId', 'templateId', 'cpuNumber', 'cpuSpeed', 'memory', 'startDate', 'endDate'];
         $data = [];
         foreach ($keys as $key) {
             $data[$key] = $instanceRecord->{$key};
         }
         UsageInstance::create($data);
         unset($data);
     }
     foreach ($records->general as $generalRecord) {
         $keys = ['zoneId', 'accountId', 'type', 'usage', 'vmInstanceId', 'templateId', 'startDate', 'endDate'];
         $data = [];
         foreach ($keys as $key) {
             $data[$key] = $generalRecord->{$key};
         }
         UsageGeneral::create($data);
         unset($data);
     }
     foreach ($records->disk as $diskRecord) {
         $keys = ['zoneId', 'accountId', 'volumeId', 'size', 'type', 'tags', 'usage', 'vmInstanceId', 'startDate', 'endDate'];
         $data = [];
         foreach ($keys as $key) {
             $data[$key] = $diskRecord->{$key};
         }
         UsageDisk::create($data);
         unset($data);
     }
     // Set last bill record date to today.
     //        SiteConfig::where('parameter', '=', 'lastBillRecordDate')->update(['data' => date('Y-m-d')]);
 }
 /**
  * Handle the event.
  *
  * @param  UserWasCreated $event
  * @return void
  */
 public function handle(UserWasCreated $event, CloudStackClient $acs)
 {
     // $event contains a user object at $event->user
     $groups = $this->repo->all();
     $domainId = SiteConfig::whereParameter('domainId')->first();
     foreach ($groups as $group) {
         // Add each group to the user.
         if (strcasecmp($group->name, 'default') != 0) {
             // Default group doesn't need creating.
             $acs->createSecurityGroup(['name' => $group->name, 'description' => $group->description, 'account' => $event->user->email, 'domainid' => $domainId->data]);
             sleep(5);
             // Make sure the group gets created.
         }
         foreach ($group->ingressRules as $rule) {
             if ($rule->protocol == 'ICMP') {
                 $acs->authorizeSecurityGroupIngress(['account' => $event->user->email, 'domainid' => $domainId->data, 'cidrlist' => $rule->cidr, 'icmpcode' => $rule->icmp_code, 'icmptype' => $rule->icmp_type, 'protocol' => $rule->protocol, 'securitygroupname' => $group->name]);
             } else {
                 $acs->authorizeSecurityGroupIngress(['account' => $event->user->email, 'domainid' => $domainId->data, 'cidrlist' => $rule->cidr, 'startport' => $rule->start_port, 'endport' => $rule->end_port, 'protocol' => $rule->protocol, 'securitygroupname' => $group->name]);
             }
         }
     }
 }
Пример #17
0
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function fire()
 {
     // Setup HTTP request for the records
     $url = SiteConfig::whereParameter('recordsUrl')->first()->data;
     $client = new Client(['base_uri' => $url]);
     $data = $client->get("api/getPricing");
     $priceData = json_decode($data->getBody());
     $priceMethod = SiteConfig::firstOrCreate(['parameter' => 'priceMethod']);
     $priceMethod->data = $priceData->priceMethod;
     $priceMethod->save();
     DB::statement('TRUNCATE element_costs');
     foreach ($priceData->prices as $price) {
         if ($priceData->priceMethod == 'fixedRatio') {
             $frPrice = SiteConfig::firstOrCreate(['parameter' => $price->parameter]);
             $frPrice->data = $price->data;
             $frPrice->save();
         } else {
             if ($priceData->priceMethod == 'elementPrice') {
                 ElementCost::create(['element' => $price->element, 'quantity' => $price->quantity, 'quantity_type' => $price->quantity_type, 'price' => $price->price]);
             }
         }
     }
 }
 public function syncACS()
 {
     $acs = app('cloudstack');
     if (is_array($acs)) {
         return -1;
     }
     $offerings = $acs->listDiskOfferings();
     $tags = [];
     foreach ($offerings as $offering) {
         // Extract a list of tags
         if (!isset($offering->tags)) {
             continue;
         }
         if (!in_array($offering->tags, $tags)) {
             $tags[] = $offering->tags;
         }
     }
     foreach ($tags as $tag) {
         // Create a config price and a storage tag if they don't exist.
         StorageType::firstOrCreate(['tag' => $tag]);
         SiteConfig::firstOrCreate(['parameter' => $tag . 'Price']);
     }
     return 1;
 }
Пример #19
0
 public function create($request)
 {
     /**
      * ACS requires the following for deployVirtualMachine():
      * serviceofferingid
      * templateid
      * zoneid
      * account
      * domainid
      * name
      * keypair (if needed)
      * rootdisksize (if allowed)
      * hypervisor (if specifying rootdisksize)
      */
     $instanceData = [];
     // Get site configuration.  We're looking for hypervisor, rootdiskresize, and domainId.
     $cfg = SiteConfig::all()->makeKVArray();
     // Did we receive a package or a custom configuration?
     if (isset($request['package'])) {
         $pkg = Package::find($request['package']);
         $instanceData['serviceofferingid'] = $this->findServiceOffering(['cpu' => $pkg->cpu_number, 'memory' => $pkg->ram, 'diskType' => $pkg->diskType->tags]);
     } else {
         $instanceData['serviceofferingid'] = $this->findServiceOffering(['cpu' => $request->coreSlider, 'memory' => $request->ramSlider * 1024, 'diskType' => $request->diskType]);
     }
     // If we can't find a service offering, error out.
     if (empty($instanceData['serviceofferingid'])) {
         abort(500);
     }
     if (isset($request->myTemplate)) {
         // Template is one created by the user.
         $instanceData['templateid'] = $request->myTemplate;
     } else {
         // Find the template we need.
         $templateGroup = TemplateGroup::find($request['template']);
         if ('FALSE' == $cfg['rootdiskresize']) {
             // Size can come from a package or a custom size slider.
             $disk_size = isset($request['package']) ? $pkg->disk_size : stristr($request['hdSlider'], ' ', true);
             // Find the specific size of template
             $templateGroup->templates->each(function ($tpl) use($disk_size, &$instanceData) {
                 if ($tpl->size == $disk_size) {
                     $instanceData['templateid'] = $tpl->template_id;
                 }
             });
         } else {
             if ('TRUE' == $cfg['rootdiskresize']) {
                 // We don't care about template size.  We resize whatever we need.
                 // Grab the template ID of the first (only) template in the group.
                 $instanceData['templateid'] = $templateGroup->templates->first()->template_id;
                 // If we have a package get the disk size from there.  If not we have a custom size.
                 $instanceData['rootdisksize'] = isset($request['package']) ? $pkg->disk_size : $request['disk_size'];
                 // We also need to set the hypervisor type.
                 $instanceData['hypervisor'] = $cfg['hypervisor'];
             }
         }
     }
     // Error out if we don't find a template
     if (empty($instanceData['templateid'])) {
         abort(500);
     }
     // Get the user object
     $user = Auth::User();
     // Add a network interface to the system
     $networks = $this->acs->listNetworks(['canusefordeploy' => 'true', 'account' => $user->email, 'domainid' => $cfg['domainId']]);
     // !!REVISE!!
     $instanceData['networkids'] = $networks[0]->id;
     // Select a security group for the instance
     $instanceData['securitygroupids'] = $request->secGroup;
     // Name the new instance
     $instanceData['name'] = $request['name'];
     // Add user data to the request
     $instanceData['account'] = $user->email;
     $instanceData['domainid'] = $cfg['domainId'];
     // What zone is being deployed to?
     $instanceData['zoneid'] = $request['zone'];
     // Do we need to add a keypair to the system?
     if (isset($request['keypair'])) {
         $instanceData['keypair'] = $request['keypair'];
     }
     return $this->acs->deployVirtualMachine($instanceData);
 }
 public function createTemplateFromSnapshot(Request $request, $id)
 {
     // Get metadata for this snapshot.
     $meta = SnapshotMetadata::find($id);
     // Get user's API credentials
     $user = current($this->acs->listUsers(['account' => Auth::User()->email, 'domainid' => SiteConfig::whereParameter('domainId')->first()->data]));
     // If null, generate them.
     if (empty($user->secretkey) || empty($user->apikey)) {
         $keys = $this->acs->registerUserKeys(['id' => $user->id]);
     }
     $apikey = isset($keys->apikey) ? $keys->apikey : $user->apikey;
     $secretkey = isset($keys->secretkey) ? $keys->secretkey : $user->secretkey;
     // Create ACS connector using the API credentials
     $user_acs = app('Cloudstack\\CloudStackClient');
     $user_acs->setKeys($apikey, $secretkey);
     // Call createTemplate as the user
     $resp = $user_acs->createTemplate(['displaytext' => $request->name, 'name' => $request->name, 'ostypeid' => $meta->ostypeid, 'snapshotid' => $id]);
     return redirect()->route('progress', [$resp->jobid]);
 }
Пример #21
0
 /**
  * Remove the specified resource from storage.
  *
  * @param  int $id
  * @return Response
  */
 public function destroy($name)
 {
     $domain = SiteConfig::whereParameter('domainId')->first();
     // Call the ACS API and add the ssh key to the necessary account
     $result = $this->acs->deleteSSHKeyPair(['account' => Auth::User()->email, 'domainid' => $domain->data, 'name' => $name]);
     Activity::create(['subject_type' => 'SSH Key', 'subject_id' => 0, 'event' => 'Deleted', 'user_id' => Auth::User()->id, 'ip' => $request->server('REMOTE_ADDR')]);
     return 1;
 }
Пример #22
0
 /**
  * Execute the console command.
  *
  * @return mixed
  */
 public function fire()
 {
     $grandfatherPricing = SiteConfig::whereParameter('grandfatherPricing')->first()->data;
     $priceMethod = SiteConfig::whereParameter('priceMethod')->first()->data;
     $domainId = SiteConfig::whereParameter('domainId')->first()->data;
     $tcOrigin = Config::get('taxcloud.originAddress');
     $this->taxCloud->setOriginAddress($tcOrigin['address1'], $tcOrigin['address2'], $tcOrigin['city'], $tcOrigin['state'], $tcOrigin['zip']);
     if ($priceMethod == 'fixedRatio') {
         $priceData = SiteConfig::where('parameter', 'LIKE', '%Price')->get();
         foreach ($priceData as $pd) {
             $this->pricing[$pd->parameter] = $pd->data;
         }
     } else {
         if ($priceMethod == 'elementPrice') {
             $priceData = ElementCost::all();
             foreach ($priceData as $pd) {
                 $this->pricing[$pd->element]["{$pd->quantity}-{$pd->quantity_type}"] = $pd->price;
             }
         }
     }
     // Get all of the users with a bill date of today.
     $users = User::billableToday()->chunk(100, function ($users) use($grandfatherPricing, $priceMethod, $domainId) {
         foreach ($users as $user) {
             $acsAccountData = app('Cloudstack\\CloudStackClient')->listUsers(['account' => $user->email, 'domainid' => $domainId])[0];
             $invoiceID = uniqid();
             $this->info("Working on user {$user->email}, account ID {$acsAccountData->accountid}");
             // Get usage records data for VM, disk and general.
             UsageInstance::where('accountId', '=', $acsAccountData->accountid)->chunk(100, function ($instanceUsage) {
                 // Go through the usage and make a nice array that we can invoice from
                 foreach ($instanceUsage as $record) {
                     $this->repo->addRecord($record);
                 }
             });
             UsageDisk::where('accountId', '=', $acsAccountData->accountid)->chunk(100, function ($diskUsage) {
                 foreach ($diskUsage as $record) {
                     $this->repo->addRecord($record);
                 }
             });
             // Begin pricing VMs and setting TIC on each record.
             $usage = $this->repo->all();
             print_r($usage);
             $usage['subtotal'] = 0;
             // Loop through the aggregated records and add pricing and tax information
             foreach ($usage['instance'] as $vmid => &$instance) {
                 foreach ($instance as $so_id => &$so_instance) {
                     $pkg = Package::where('cpu_number', '=', $so_instance['resources']['cpunumber'])->where('ram', '=', $so_instance['resources']['memory'])->where('disk_size', '=', $so_instance['resources']['disk_size'])->where('disk_type', '=', $so_instance['resources']['disk_type'])->first();
                     if ($pkg instanceof Package) {
                         $so_instance['tic'] = $pkg->tic;
                         // Set the price
                         $so_instance['price'] = $pkg->price / 720 * $so_instance['usage'];
                     } else {
                         // Instance has custom parameters and should be priced by its individual elements.
                         if ($priceMethod == 'fixedRatio') {
                             $so_instance['price'] = $so_instance['resources']['cpunumber'] * ($this->pricing['corePrice'] / 720) * $so_instance['usage'];
                             $so_instance['price'] += $so_instance['resources']['memory'] / 1024 * ($this->pricing['ramPrice'] / 720) * $so_instance['usage'];
                             $storageType = DiskType::find($so_instance['resources']['disk_type']);
                             $diskAmount = $so_instance['resources']['disk_size'] / 1024 / 1024 / 1024;
                             $so_instance['price'] += $diskAmount * ($this->pricing["{$storageType->tags}Price"] / 720) * $so_instance['usage'];
                         } else {
                             if ($priceMethod == 'elementPrice') {
                                 $so_instance['price'] = $this->pricing['CPU']["{$so_instance['resources']['cpunumber']}"] * $so_instance['usage'];
                                 $memoryIdentifier = $so_instance['resources']['memory'] / 1024 . "-GB";
                                 $so_instance['price'] += $this->pricing['RAM']["{$memoryIdentifier}"] * $so_instance['usage'];
                                 $storageType = DiskType::find($so_instance['resources']['disk_type']);
                                 $diskAmount = $so_instance['resources']['disk_size'] / 1024 / 1024 / 1024;
                                 $so_instance['price'] += $this->pricing[$storageType->tags][$diskAmount] * $so_instance['usage'];
                             }
                         }
                         $so_instance['tic'] = 30070;
                         // !!REVISE!!
                     }
                     if ($grandfatherPricing == 'YES') {
                         // Check to see if we have this instance on record
                         $gfInstance = VmInstance::where('vm_instance_id', '=', $vmid)->where('cpu_number', '=', $so_instance['resources']['cpunumber'])->where('memory', '=', $so_instance['resources']['memory'])->where('disk_size', '=', $so_instance['resources']['disk_size'])->where('disk_type', '=', $so_instance['resources']['disk_type'])->first();
                         if ($gfInstance instanceof VmInstance) {
                             $so_instance['price'] = $gfInstance->rate;
                         } else {
                             $newVm = new VmInstance(['vm_instance_id' => $vmid, 'cpu_number' => $so_instance['resources']['cpunumber'], 'memory' => $so_instance['resources']['memory'], 'disk_size' => $so_instance['resources']['disk_size'], 'disk_type' => $so_instance['resources']['disk_type'], 'rate' => $so_instance['price']]);
                             $user->instances()->save($newVm);
                         }
                     }
                     $usage['subtotal'] += $so_instance['price'];
                 }
             }
             // Grab a collection of credit cards.  We use billing address off the primary card for tax purposes.
             $cards = CreditCard::where('user_id', '=', $user->id)->orderBy('primary', 'desc')->get();
             $paymentGw = app('\\App\\Repositories\\Contracts\\PaymentRepositoryInterface');
             $primaryCard = $paymentGw->get($cards->first()->id, $user->id);
             // Compute Sales Tax
             $this->taxCloud->setDestAddress($primaryCard['address'], '', $primaryCard['city'], $primaryCard['state'], strpos($primaryCard['zipcode'], '-') === FALSE ? $primaryCard['zipcode'] : substr($primaryCard['zipcode'], 0, 5), '');
             $usage['tax'] = $this->taxCloud->calculateSalesTax($user->id, $invoiceID, $usage);
             $usage['total'] = $usage['subtotal'] + $usage['tax'];
             // Record the uniqueID.
             $usage['invoiceNumber'] = $invoiceID;
             // Record invoice for the total amount.
             $transInvoice = new Transaction(['amount' => $usage['total'], 'note' => 'Invoice', 'invoice_number' => $invoiceID]);
             $user->transactions()->save($transInvoice);
             // Bill the user
             foreach ($cards as $card) {
                 $response = $paymentGw->charge($card->payment_profile_id, $usage['total']);
                 if ($response == false) {
                     // Notify the user their card failed to charge.
                     // Go on to the next one.
                     continue;
                 }
                 // Record payment and set next bill date
                 $transPayment = new Transaction(['amount' => -$usage['total'], 'note' => 'Payment']);
                 $user->transactions()->save($transPayment);
                 $user->bill_date = date('Y-m-d', strtotime("+1 month"));
                 break;
                 // If its successful, proceed.
             }
             // Serialize the cache and save it for the user it was generated for
             $invoice = new \App\Invoice(['invoice_data' => serialize($usage)]);
             $user->invoices()->save($invoice);
             // Reset the cache for the next user
             $this->repo->clearCache();
         }
     });
 }