Completed
Pull Request — master (#12)
by Chad
01:58
created

ChefEc2::_awsCredentialParameters()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
1
<?php
2
namespace DominionEnterprises\Chef;
3
4
class ChefEc2
5
{
6
    /**
7
     * @var string The base command for knife.
8
     */
9
    private $baseKnifeCommand;
10
11
    /**
12
     * @var string The url for the chef API.
13
     */
14
    private $chefServerUrl;
15
16
    /**
17
     * @var array The credentials needed to interact with knife-ec2.
18
     */
19
    private $credentials;
20
21
    /**
22
     * Initialize the wrapper around knife-ec2.
23
     *
24
     * @param string $baseKnifeCommand The base command for knife.  could be 'knife' if knife is already in the path.
25
     *                                 If using bundler to install knife-ec2, you could do something
26
     *                                 like 'BUNDLE_GEMFILE=/path/to/Gemfile bundle exec knife'.
27
     * @param string $chefServerUrl    The url for the chef API.
28
     * @param array  $credentials      The credentials needed to interact with knife-ec2.  Includes awsAccessKeyId and
29
     *                                 awsSecretAccessKey.
30
     */
31
    public function __construct($baseKnifeCommand, $chefServerUrl, array $credentials)
32
    {
33
        $this->baseKnifeCommand = $baseKnifeCommand;
34
        $this->chefServerUrl = $chefServerUrl;
35
        $this->credentials = $credentials;
36
    }
37
38
    /**
39
     * Instantiate a new server.
40
     *
41
     * @param string $region The AWS region the server is in.
42
     * @param string $ami The region-specific AMI to use.
43
     * @param string $flavor The flavor of server to create, e.g. t1.micro.
44
     * @param array $runList The roles/recipes for the chef run list.
45
     * @param string $progressFile A file path to store the server output in.
46
     * @param array $options Additional options for knife-ec2.  For example: ['-groups' => 'foo']
47
     * @param array $tags Tags to set for the server.
48
     * @param string $chefVersion The chef version to use to bootstrap the server.
49
     *
50
     * @return void
51
     */
52
    public function createServer(
53
        $region,
54
        $ami,
55
        $flavor,
56
        array $runList,
57
        $progressFile,
58
        array $options = [],
59
        array $tags = [],
60
        $chefVersion = '11.8.0'
61
    ) {
62
63
        $tagList = [];
64
        foreach ($tags as $key => $value) {
65
            $tagList[] = "{$key}={$value}";
66
        }
67
68
        $fullOptions = [
69
            '--region' => $region,
70
            '--image' => $ami,
71
            '--flavor' => $flavor,
72
            '--run-list' => implode(',', $runList),
73
            '--tags' => implode(',', $tagList),
74
            '--bootstrap-version' => $chefVersion,
75
        ];
76
77
        $fullOptions += $options;
78
        $fullOptions += $this->awsCredentialParameters();
79
        $fullOptions += $this->chefClientParameters();
80
        $fullOptions += $this->ec2SshParameters();
81
82
        $command = \Hiatus\addArguments("{$this->baseKnifeCommand} ec2 server create", $fullOptions);
83
        \Hiatus\execX("{$command} >" . escapeshellarg($progressFile) . ' 2>&1 &');
84
    }
85
86
    /**
87
     * Runs chef client on the servers that match the query storing command output in the given file.
88
     *
89
     * @param string $query The chef query to specify what servers to update.
90
     * @param string $progressFile The filename to send the knife output to.
91
     * @param array $options Additional options for knife ssh.  For example: ['-groups' => 'foo']
92
     * @param array $chefOptions Additional options for chef client. For example: ['--override-runlist' => 'role[foo]']
93
     * @return void
94
     */
95
    public function updateServers($query, $progressFile = null, array $options = [], array $chefOptions = [])
96
    {
97
        $instanceIdUrl = 'http://169.254.169.254/latest/meta-data/instance-id';
98
        $chefOptions = array_merge($chefOptions, ['--json-attributes' => '/etc/chef/first-boot.json']);
99
        $chefCommand = \Hiatus\addArguments("sudo chef-client -N `curl {$instanceIdUrl}`", $chefOptions);
100
        $options = array_merge(
101
            $options,
102
            $this->chefClientParameters(),
103
            $this->ec2SshParameters(),
104
            [$query, $chefCommand]
105
        );
106
        $command = \Hiatus\addArguments("{$this->baseKnifeCommand} ssh", $options);
107
        if ($progressFile !== null) {
108
            \Hiatus\execX("{$command} >" . escapeshellarg($progressFile) . ' 2>&1 &');
109
        } else {
110
            passthru($command);
111
        }
112
    }
113
114
    /**
115
     * Get the knife-ec2 parameters for basic AWS API credentials.
116
     *
117
     * @return array The parameters to access AWS via knife-ec2.
118
     */
119
    private function awsCredentialParameters()
120
    {
121
        return [
122
            '--aws-access-key-id' => $this->credentials['awsAccessKeyId'],
123
            '--aws-secret-access-key' => $this->credentials['awsSecretAccessKey'],
124
        ];
125
    }
126
127
    /**
128
     * Get the chef client parameters.
129
     *
130
     * @return array The parameters to access the chef API via knife.
131
     */
132
    private function chefClientParameters()
133
    {
134
        return [
135
            '--server-url' => $this->chefServerUrl,
136
            '--user' => $this->credentials['chefClientName'],
137
            '--key' => $this->credentials['chefClientKey'],
138
        ];
139
    }
140
141
    /**
142
     * Get the EC2 SSH parameters.
143
     *
144
     * @return array The parameters to access the EC2 ssh servers
145
     */
146
    private function ec2SshParameters()
147
    {
148
        return [
149
            '--ssh-user' => $this->credentials['ec2SshUser'],
150
            '--identity-file' => $this->credentials['ec2SshKey'],
151
        ];
152
    }
153
}
154