Skip to content

Commit bfde389

Browse files
committed
initial commit
0 parents  commit bfde389

28 files changed

+2911
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
vendor/

README.md

+200
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
# PHP OVH CLI
2+
3+
A simple [OVH API](https://api.ovh.com/console/) client for managing OVH infrastructure, written with PHP.
4+
5+
## Features
6+
**General**
7+
- Configuration wizard
8+
- Cache support
9+
- PHAR package
10+
- Easy to extend with new commands!
11+
- Safe mode (dry-run)
12+
13+
**API**
14+
- Application management
15+
16+
**Dedicated Servers**
17+
- Search by name/reverse (using RegExps)
18+
- Retrieve information
19+
- Configure boot mode
20+
- Enable/disable OVH monitoring
21+
- Access KVM console (requires Java-WS)
22+
- Perform IPMI reset
23+
- Request hardware reboot
24+
25+
**vRack**
26+
- List associated servers
27+
- Assign servers to vRack
28+
29+
**DNS**
30+
- Reverse DNS management
31+
- Automatically resolve reverse hostname to OVH `nsXXX` hostname
32+
33+
34+
## Requirements
35+
36+
* PHP >= 7.0
37+
* PHP gmp extension (used by [rlanvin/php-ip](https://github.com/rlanvin/php-ip))
38+
* [Composer](https://getcomposer.org)
39+
40+
## Install
41+
42+
```text
43+
$ git clone https://github.com/miklinux/php-ovh-cli.git
44+
$ cd php-ovh-cli
45+
$ composer update
46+
```
47+
48+
## Configuration
49+
To interact with OVH API you must already have an account at OVH.
50+
The script will take care of requesting an API token for you.
51+
52+
```text
53+
$ ./ovh-cli api:setup
54+
Would you like me to open the browser and create a new OVH API token? [N]:
55+
```
56+
If you answer *YES*, the script will attempt to open the browser to a page where you can generate an OVH API token, pre-populating some fields.
57+
In case you would like to do that manually here's the link: https://api.ovh.com/createToken
58+
59+
```text
60+
Application key [xxx]:
61+
Application secret [xxx]:
62+
Consumer key [xxx]:
63+
Endpoint [ovh-eu]:
64+
JavaWS binary [/usr/bin/javaws]:
65+
Cache TTL in seconds [3600]:
66+
67+
Configuration file written: /home/user/.ovh-cli.config.json
68+
```
69+
70+
Once the script is configured you can test if it's working properly:
71+
```text
72+
$ ./ovh-cli api:test
73+
Hi John Doe, OVH API are working properly ;)
74+
```
75+
76+
## Usage
77+
Once the script is correctly configured, you can interact with OVH API using this script.
78+
Please refer to its help for all the information you need.
79+
80+
```text
81+
$ ./ovh-cli --help
82+
```
83+
84+
**NOTE:** If you're concerned about damaging your systems by improper use of this tool, use the `--dry-run` or `-t` command line switch.
85+
This will prevent the execution of potentially harmful **PUT/POST/DELETE** requests, so only **GET**s will be executed.
86+
87+
## Development
88+
This script has been developed to be easily extended, so if you want to contribute and/or add your own commands,
89+
you can do it without particular efforts. This project has been structured in this way:
90+
91+
| Path | Description |
92+
|-----------------|----------------------------------------------------------------------|
93+
| ovh-cli | Simple executable |
94+
| cli.php | Main script (to be used with PHAR) |
95+
| create-phar.php | Package the script into an executable: `ovh-cli` |
96+
| src/ | Project directory |
97+
| src/Cli.php | Contains all the CLI decorators (colors, prompts, formatting, ...) |
98+
| src/Command.php | Class `OvhCli\Command`: contains all common command logic |
99+
| src/Config.php | Class `OvhCli\Config`: manages configuration file |
100+
| src/Ovh.php | Class `OvhCli\Ovh`: contains wrappers to OVH API calls |
101+
| src/Command/ | Directory containing all the available commands |
102+
103+
### Creating new command
104+
See: http://getopt-php.github.io/getopt-php/
105+
106+
In this example we will create a new `hello:world` command.
107+
```
108+
$ cd src/Command
109+
$ mkdir Hello
110+
$ touch Hello/World.php
111+
```
112+
113+
**World.php**
114+
```php
115+
<?php
116+
117+
// The namespace should match the directory structure
118+
namespace OvhCli\Command\Hello;
119+
120+
use GetOpt\GetOpt;
121+
use GetOpt\Operand;
122+
use GetOpt\Option;
123+
use GetOpt\Argument;
124+
use OvhCli\Cli;
125+
126+
class World extends \OvhCli\Command
127+
{
128+
// Command description, used for help
129+
public $shortDescription = "This is my hello world command";
130+
// Optional. Add some usage examples.
131+
public $usageExamples = [
132+
'-a' => 'Do action A',
133+
'-b' => 'Do action B',
134+
];
135+
136+
// Here you will define command options/operands
137+
public function __construct() {
138+
parent::__construct($this->getName(), [$this, 'handle']);
139+
$this->addOptions([
140+
Option::create('a', 'action-a', GetOpt::NO_ARGUMENT)
141+
->setDescription('Perform action A'),
142+
Option::create('b', 'action-b', GetOpt::NO_ARGUMENT)
143+
->setDescription('Perform action B'),
144+
]);
145+
}
146+
147+
// This function will contain the main logic of your command
148+
public function handle(GetOpt $getopt) {
149+
$a = $getopt->getOption('action-a');
150+
$b = $getopt->getOption('action-b');
151+
152+
if ($a) {
153+
print "This is action A\n";
154+
} elseif($b) {
155+
print "This is action A\n";
156+
} else {
157+
print "No action specified. Use --help!\n";
158+
}
159+
}
160+
}
161+
```
162+
163+
You can then find your new command in the help (output omitted for brevity):
164+
```
165+
$ ./ovh-cli --help
166+
Usage: ./ovh-cli <command> [options] [operands]
167+
168+
Options:
169+
-?, --help Show this help and quit
170+
171+
Commands:
172+
hello:world This is my hello world command
173+
```
174+
175+
Get your new command help:
176+
```
177+
$ ./ovh-cli hello:world --help
178+
Usage: ./ovh-cli hello:world [options] [operands]
179+
180+
This is my hello world command
181+
182+
Examples:
183+
hello:world -a Do action A
184+
hello:world -b Do action B
185+
186+
Options:
187+
-?, --help Show this help and quit
188+
-a, --action-a Perform action A
189+
-b, --action-b Perform action B
190+
```
191+
192+
And then, simply execute it!
193+
```text
194+
$ ./ovh-cli hello:world
195+
No action specified. Use --help!
196+
$ ./ovh-cli hello:world -a
197+
This is action A
198+
$ ./ovh-cli hello:world -b
199+
This is action A
200+
```

cli.php

+94
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
use GetOpt\GetOpt;
4+
use GetOpt\Option;
5+
use GetOpt\Command;
6+
use GetOpt\ArgumentException;
7+
use GetOpt\ArgumentException\Missing;
8+
use Phpfastcache\CacheManager;
9+
use Phpfastcache\Config\Config as CacheConfig;
10+
use Phpfastcache\Core\phpFastCache;
11+
use OvhCli\Ovh;
12+
use OvhCli\Cli;
13+
14+
require_once __DIR__ . '/vendor/autoload.php';
15+
16+
error_reporting(E_ALL ^ E_NOTICE);
17+
define('CONFIG_FILE', getenv("HOME").'/.ovh-cli.config.json');
18+
define('COMMAND_PATH', __DIR__ . '/src/Command');
19+
20+
// set cache
21+
CacheManager::setDefaultConfig(new CacheConfig([
22+
"path" => sys_get_temp_dir(),
23+
"itemDetailedDate" => false
24+
]));
25+
26+
$cacheManager = CacheManager::getInstance('files');
27+
Ovh::setCacheManager($cacheManager);
28+
29+
$getOpt = new GetOpt();
30+
$getOpt->addOptions([
31+
Option::create('?', 'help', GetOpt::NO_ARGUMENT)
32+
->setDescription('Show this help and quit'),
33+
Option::create('t', 'dry-run', GetOpt::NO_ARGUMENT)
34+
->setDescription('Will fake PUT/POST/DELETE requests'),
35+
Option::create('g', 'grep', GetOpt::NO_ARGUMENT)
36+
->setDescription('Greppable output'),
37+
Option::create('n', 'no-cache', GetOpt::NO_ARGUMENT)
38+
->setDescription('Disable cache')
39+
]);
40+
41+
$commands = [];
42+
// glob() doesn't work with PHAR, so use iterators
43+
$directory = new \RecursiveIteratorIterator(
44+
new \RecursiveDirectoryIterator(COMMAND_PATH)
45+
);
46+
// commands autoloading
47+
foreach($directory as $file) {
48+
if (!preg_match('/\.php$/', $file)) {
49+
continue;
50+
}
51+
$relativePath = substr($file, strlen(COMMAND_PATH) + 1);
52+
$classSuffix = str_replace(['.php',DIRECTORY_SEPARATOR], ['','\\'], $relativePath);
53+
$class = '\\OvhCli\\Command\\' . $classSuffix;
54+
$command = new $class;
55+
$name = $command->getName();
56+
$commands[$name] = $command;
57+
}
58+
// I like commands to be in alphabetical order :)
59+
ksort($commands);
60+
$getOpt->addCommands($commands);
61+
62+
try {
63+
try {
64+
$getOpt->process();
65+
} catch (Missing $exception) {
66+
if (!$getOpt->getOption('help')) {
67+
throw $exception;
68+
}
69+
}
70+
} catch (ArgumentException $exception) {
71+
file_put_contents('php://stderr', $exception->getMessage() . PHP_EOL);
72+
echo PHP_EOL . $getOpt->getHelpText();
73+
exit;
74+
}
75+
76+
// show help and quit
77+
$command = $getOpt->getCommand();
78+
if (!$command || $getOpt->getOption('help')) {
79+
echo $getOpt->getHelpText();
80+
exit;
81+
}
82+
83+
if ($getOpt->getOption('dry-run')) {
84+
Ovh::setDryRun(true);
85+
Cli::warning("running in DRY-RUN mode");
86+
}
87+
88+
if ($getOpt->getOption('no-cache')) {
89+
Ovh::disableCache();
90+
Cli::warning("cache is disabled");
91+
}
92+
93+
// call the requested command
94+
call_user_func($command->getHandler(), $getOpt);

composer.json

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"require": {
3+
"ovh/ovh": "^2.0",
4+
"rlanvin/php-ip": "^2.0",
5+
"ulrichsg/getopt-php": "^3.2",
6+
"phpfastcache/phpfastcache": "^7.1"
7+
},
8+
"autoload": {
9+
"psr-4": {
10+
"OvhCli\\": "src/"
11+
}
12+
}
13+
}

0 commit comments

Comments
 (0)