Example #1
0
 public function start(Request $request, $repo = false)
 {
     try {
         $repo = new Repo($repo);
     } catch (\Exception $e) {
         $request->session()->flash(str_random(4), ['type' => 'danger', 'message' => $e->getMessage()]);
         return redirect('/?ohno');
     }
     $request->session()->set('intendedRepo', $repo);
     if ($request->session()->has('digitalocean') === false) {
         return redirect(url('/do/start'));
     }
     $request->session()->forget('intendedRepo');
     $provision = new Provision();
     $provision->repo = $repo->getName();
     // Before it gets contaminated
     $github = new Github($this->getGithubClient(), $repo);
     $json = $github->getFodorJson();
     if (empty($json)) {
         $request->session()->flash(str_random(4), ['type' => 'warning', 'message' => 'This repo or repo\'s fodor.json is non-existent']);
         return redirect(url('/'));
     }
     $fodorJson = new Config($json);
     try {
         $fodorJson->valid();
     } catch (\Exception $e) {
         $request->session()->flash(str_random(4), ['type' => 'danger', 'message' => $e->getMessage()]);
         return redirect('/?ohno');
     }
     $fodorJsonUndecoded = $fodorJson->getJson();
     // string of json
     // Has to be less than 1mb
     $provisioner = $github->getFileContents($fodorJson->provisioner);
     if (empty($provisioner)) {
         $request->session()->flash(str_random(4), ['type' => 'warning', 'message' => 'This repo\'s provisioner was invalid or empty']);
         return redirect(url('/?ohno'));
     }
     // We have a valid provisioner
     $size = '512mb';
     // TODO: Config variable for default size
     $suggestedSize = false;
     $requiredSize = false;
     if (array_key_exists('required', $fodorJson->size) === true) {
         $size = $fodorJson->size['required'];
         $requiredSize = $size;
     }
     // Suggested size overrides the default and required size
     if (array_key_exists('suggested', $fodorJson->size) === true) {
         $size = $fodorJson->size['suggested'];
         $suggestedSize = $size;
     }
     if (array_key_exists($size, config('digitalocean.sizes')) === false) {
         // Invalid size
         $size = '512mb';
         // TODO: Config variable for default size
     }
     $isDistroInvalid = !in_array($fodorJson->distro, config('digitalocean.distros'));
     if (empty($fodorJson->distro) || $isDistroInvalid) {
         $fodorJson->distro = 'ubuntu-14-04-x64';
     }
     $adapter = new GuzzleHttpAdapter($request->session()->get('digitalocean')['token']);
     $digitalocean = new DigitalOceanV2($adapter);
     $keysCached = false;
     $cacheKey = sha1($request->session()->get('digitalocean')['token'] . '-sshkeys');
     $keys = Cache::get($cacheKey, []);
     if (empty($keys)) {
         $keysFromDo = $digitalocean->key()->getAll();
         if (empty($keysFromDo)) {
             $request->session()->flash(str_random(4), ['type' => 'danger', 'message' => 'You must have SSH keys attached to your DigitalOcean account to continue - https://cloud.digitalocean.com/settings/security']);
             return redirect(url('/provision/' . $provision->repo));
         }
         foreach ($keysFromDo as $key) {
             if (strpos($key->name, 'fodor-') !== 0) {
                 $keys[$key->id] = $key->name;
             }
         }
         if (empty($keys)) {
             $request->session()->flash(str_random(4), ['type' => 'danger', 'message' => 'You must have SSH keys attached to your DigitalOcean account to continue - https://cloud.digitalocean.com/settings/security']);
             return redirect(url('/provision/' . $provision->repo));
         }
         Cache::put($cacheKey, $keys, 5);
         // Cache SSH keys for 5 minutes
     } else {
         $keysCached = true;
     }
     $requiredMemory = 0;
     if (!empty($requiredSize)) {
         $requiredMemory = array_key_exists($requiredSize, config('digitalocean.sizes')) ? config('digitalocean.sizes')[$requiredSize]['memory'] : 0;
     }
     $inputs = is_null($fodorJson->inputs) === false ? $fodorJson->inputs : [];
     array_walk($inputs, function (&$input) {
         $input['value'] = '';
         $input = new Input($input);
     });
     //get account email, and digitalocean_uuid
     //generate our own uuid
     //store in DB
     $provision->uuid = Uuid::uuid4()->toString();
     $provision->email = $request->session()->get('digitalocean')['email'];
     $provision->digitalocean_uuid = $request->session()->get('digitalocean')['uuid'];
     $provision->size = $size;
     // Default, can be overriden in next step
     $provision->distro = $fodorJson->distro;
     $provision->region = 'xxx';
     // Default, can be overriden in next step
     $provision->datestarted = (new \DateTime('now', new \DateTimeZone('UTC')))->format('c');
     $validatingInputs = $request->input('uuid') !== null ? true : false;
     if ($validatingInputs) {
         $provision = \App\Provision::where('id', $request->input('provisionid'))->where('uuid', $request->input('uuid'))->first();
         /**
          * @var Input $input
          */
         $invalidInputs = [];
         foreach ($inputs as $input) {
             $value = $request->input('inputs')[$input->getName()];
             $input->value($value);
             $valid = $input->validate($value);
             if ($valid === false) {
                 $invalidInputs[] = ucwords($input->getName());
             }
         }
         $selectedKeys = $request->input('keys');
         $keysChosen = count($selectedKeys) > 0;
         if ($keysChosen === false) {
             $request->session()->now(str_random(4), ['type' => 'warning', 'message' => 'You must select an SSH key to add to the server']);
         } elseif (count($invalidInputs) === 0 && $keysChosen) {
             return $this->doit($request);
         } else {
             $request->session()->now(str_random(4), ['type' => 'warning', 'message' => 'Input value was invalid for ' . implode(', ', $invalidInputs)]);
         }
     } else {
         try {
             $saved = $provision->save();
         } catch (\Exception $e) {
             $saved = false;
         }
         if (empty($saved)) {
             // Failed to save
             $request->session()->flash(str_random(4), ['type' => 'danger', 'message' => 'Failed to save the provision data to the database, please destroy your droplet']);
             return redirect(url('/provision/' . $provision->repo));
         }
     }
     return view('provision.start', ['repo' => $repo->getRepoName(), 'size' => ['default' => $size, 'suggested' => $suggestedSize, 'required' => $requiredSize], 'requiredMemory' => $requiredMemory, 'description' => $fodorJson->description, 'distro' => $fodorJson->distro, 'keys' => $keys, 'provisionid' => $provision->id, 'provision' => $provision, 'id' => $provision->id, 'uuid' => $provision->uuid, 'inputs' => $inputs, 'keysCached' => $keysCached]);
 }