Completed
Pull Request — master (#27)
by
unknown
02:50
created

Ansible   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 135
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Test Coverage

Coverage 81.58%

Importance

Changes 10
Bugs 1 Features 4
Metric Value
wmc 12
c 10
b 1
f 4
lcom 1
cbo 4
dl 0
loc 135
ccs 31
cts 38
cp 0.8158
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
B checkCommand() 0 20 5
A checkDir() 0 8 2
A __construct() 0 11 1
A playbook() 0 6 1
A galaxy() 0 6 1
A setTimeout() 0 6 1
A createProcess() 0 9 1
1
<?php
2
/*
3
 * This file is part of the php-ansible package.
4
 *
5
 * (c) Marc Aschmann <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Asm\Ansible;
12
13
use Asm\Ansible\Command\AnsibleGalaxy;
14
use Asm\Ansible\Command\AnsibleGalaxyInterface;
15
use Asm\Ansible\Command\AnsiblePlaybook;
16
use Asm\Ansible\Command\AnsiblePlaybookInterface;
17
use Asm\Ansible\Exception\CommandException;
18
use Symfony\Component\Process\Process;
19
use Symfony\Component\Process\ProcessBuilder;
20
21
/**
22
 * Ansible command factory
23
 *
24
 * @package Asm\Ansible
25
 * @author Marc Aschmann <[email protected]>
26
 */
27
final class Ansible
28
{
29
30
    const DEFAULT_TIMEOUT = 300;
31
32
    /**
33
     * @var string
34
     */
35
    private $playbookCommand;
36
37
    /**
38
     * @var string
39
     */
40
    private $galaxyCommand;
41
42
    /**
43
     * @var string
44
     */
45
    private $ansibleBaseDir;
46
47
    /**
48
     * @var integer
49
     */
50
    private $timeout;
51
52
    /**
53
     * @param string $ansibleBaseDir base directory of ansible project structure
54
     * @param string $playbookCommand path to playbook executable, default ansible-playbook
55
     * @param string $galaxyCommand path to galaxy executable, default ansible-galaxy
56
     * @throws CommandException
57
     */
58 7
    public function __construct(
59
        $ansibleBaseDir,
60
        $playbookCommand = '',
61
        $galaxyCommand = ''
62
    ) {
63 7
        $this->ansibleBaseDir = $this->checkDir($ansibleBaseDir);
64 5
        $this->playbookCommand = $this->checkCommand($playbookCommand, 'ansible-playbook');
65 3
        $this->galaxyCommand = $this->checkCommand($galaxyCommand, 'ansible-galaxy');
66
67 3
        $this->timeout = Ansible::DEFAULT_TIMEOUT;
68 3
    }
69
70
    /**
71
     * AnsiblePlaybook instance creator
72
     *
73
     * @return AnsiblePlaybookInterface
74
     */
75 1
    public function playbook()
76
    {
77 1
        return new AnsiblePlaybook(
78 1
            $this->createProcess($this->playbookCommand)
79 1
        );
80
    }
81
82
    /**
83
     * AnsibleGalaxy instance creator
84
     *
85
     * @return AnsibleGalaxyInterface
86
     */
87 1
    public function galaxy()
88
    {
89 1
        return new AnsibleGalaxy(
90 1
            $this->createProcess($this->galaxyCommand)
91 1
        );
92
    }
93
94
    /**
95
     * Set process timeout in seconds.
96
     *
97
     * @param integer $timeout
98
     * @return $this
99
     */
100
    public function setTimeout($timeout)
101
    {
102
        $this->timeout = $timeout;
103
104
        return $this;
105
    }
106
107
    /**
108
     * @param string $prefix command to execute
109
     * @return ProcessBuilder
110
     */
111 2
    private function createProcess($prefix)
112
    {
113 2
        $process = new ProcessBuilder();
114
115
        return $process
116 2
            ->setPrefix($prefix)
117 2
            ->setWorkingDirectory($this->ansibleBaseDir)
118 2
            ->setTimeout($this->timeout);
119
    }
120
121
    /**
122
     * @param string $command
123
     * @param string $default
124
     * @return string
125
     * @throws CommandException
126
     */
127 5
    private function checkCommand($command, $default)
128
    {
129
        // normally ansible is in /usr/local/bin/*
130 5
        if ('' === $command) {
131 1
            if (null !== shell_exec('which ' . $default)) {
132
                $command = $default;
133
            } else { // not testable without ansible installation
134 1
                throw new CommandException('No ' . $default . ' executable present in PATH!');
135
            }
136
        } else {
137 4
            if (!is_file($command)) {
138 1
                throw new CommandException('Command ' . $command . ' does not exist!');
139
            }
140 3
            if (!is_executable($command)) {
141
                throw new CommandException('Command ' . $command . ' is not executable!');
142
            }
143
        }
144
145 3
        return $command;
146
    }
147
148
    /**
149
     * @param string $dir directory to check
150
     * @return string
151
     * @throws CommandException
152
     */
153 7
    private function checkDir($dir)
154
    {
155 7
        if (!is_dir($dir)) {
156 2
            throw new CommandException('Ansible project root ' . $dir . ' not found!');
157
        }
158
159 5
        return $dir;
160
    }
161
}
162