aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miha Petkovsek <miha.petkovsek@gmail.com> 2016-06-22 10:51:47 +0200
committerGravatar Miha Petkovsek <miha.petkovsek@gmail.com> 2016-06-22 10:51:47 +0200
commit1503de4a313c30cacc912b9eb0a55c5422f8e849 (patch)
tree03c861abf887765e9b52976515881f2c0f306ce3
parentb05c2d3ec69e60a5f25cf309e30ff591c992228b (diff)
downloadphpipam-api-clients-1503de4a313c30cacc912b9eb0a55c5422f8e849.tar.gz
Working php API client with example
-rw-r--r--php-client/.gitignore2
-rw-r--r--php-client/api-config.dist.php23
-rw-r--r--php-client/class.phpipam-api.php869
-rw-r--r--php-client/example.php25
4 files changed, 918 insertions, 1 deletions
diff --git a/php-client/.gitignore b/php-client/.gitignore
new file mode 100644
index 0000000..8c862d4
--- /dev/null
+++ b/php-client/.gitignore
@@ -0,0 +1,2 @@
+api-config.php
+token.txt
diff --git a/php-client/api-config.dist.php b/php-client/api-config.dist.php
new file mode 100644
index 0000000..494ef87
--- /dev/null
+++ b/php-client/api-config.dist.php
@@ -0,0 +1,23 @@
+<?php
+
+# set error reporting
+error_reporting(E_ALL ^ E_NOTICE ^ E_STRICT);
+
+# api params
+$api_url = "http://127.0.0.1/api/"; // server url
+$api_app_id = "myapp"; // application id
+$api_key = false; // api key - only for encrypted methods, otherwise must be false
+
+# set username / password for authentication, not needed for encrypted communications
+$api_username = "apiusername";
+$api_password = "apipassword";
+
+# save token or not ?
+# false => dont save, check each time
+# filename => will save token to filename provided
+$token_file = "token.txt";
+
+# set result format json/object/array/xml
+$result_format = "json";
+
+?> \ No newline at end of file
diff --git a/php-client/class.phpipam-api.php b/php-client/class.phpipam-api.php
index 073bbd7..632d2e1 100644
--- a/php-client/class.phpipam-api.php
+++ b/php-client/class.phpipam-api.php
@@ -2,11 +2,878 @@
/**
*
- * phpIPAM API client for php
+ * phpIPAM API client to work with phpIPAM APIv2
*
*
*/
+class phpipam_api_client {
+ /**
+ * Debug flag for curl
+ *
+ * (default value: false)
+ *
+ * @var bool
+ * @access public
+ */
+ public $debug = false;
+
+ /**
+ * API server URL
+ *
+ * (default value: false)
+ *
+ * @var bool
+ * @access private
+ */
+ private $api_url = false;
+
+ /**
+ * API APP identifier
+ *
+ * (default value: false)
+ *
+ * @var bool
+ * @access private
+ */
+ private $api_app_id = false;
+
+ /**
+ * API key
+ *
+ * (default value: false)
+ *
+ * @var bool
+ * @access private
+ */
+ private $api_key = false;
+
+ /**
+ * Flag if we need to encrypt API communication
+ *
+ * (default value: false)
+ *
+ * @var bool
+ * @access private
+ */
+ private $api_encrypt = false;
+
+ /**
+ * phpipam account username / passwork for authentication
+ *
+ * (default value: false)
+ *
+ * @var bool
+ * @access private
+ */
+ private $api_username = false;
+ private $api_password = false;
+
+ /**
+ * Holder for CUrL connection
+ *
+ * (default value: false)
+ *
+ * @var bool
+ * @access private
+ */
+ private $Connecton = false;
+
+ /**
+ * Access token for phpipam
+ *
+ * (default value: false)
+ *
+ * @var bool
+ * @access private
+ */
+ private $token = false;
+
+ /**
+ * When token expires
+ *
+ * (default value: false)
+ *
+ * @var bool
+ * @access private
+ */
+ private $token_expires = false;
+
+ /**
+ * api_server_method
+ *
+ * (default value: false)
+ *
+ * @var bool|mixed
+ * @access private
+ */
+ private $api_server_method = false;
+
+ /**
+ * api_server_controller (sections, subnets, ...)
+ *
+ * (default value: false)
+ *
+ * @var bool|mixed
+ * @access private
+ */
+ private $api_server_controller = false;
+
+ /**
+ * Identifiers to add to URL
+ *
+ * (default value: false)
+ *
+ * @var bool
+ * @access private
+ */
+ private $api_server_identifiers = false;
+
+ /**
+ * List of valid API methods
+ *
+ * @var mixed
+ * @access private
+ */
+ private $api_server_valid_methods = array(
+ "OPTIONS", "GET", "POST", "PATCH", "DELETE"
+ );
+
+ /**
+ * HTTP error codes for responses
+ *
+ * @var mixed
+ * @access public
+ */
+ public $error_codes = array(
+ // OK
+ 200 => "OK",
+ 201 => "Created",
+ 202 => "Accepted",
+ 204 => "No Content",
+ // Client errors
+ 400 => "Bad Request",
+ 401 => "Unauthorized",
+ 403 => "Forbidden",
+ 404 => "Not Found",
+ 405 => "Method Not Allowed",
+ 415 => "Unsupported Media Type",
+ // Server errors
+ 500 => "Internal Server Error",
+ 501 => "Not Implemented",
+ 503 => "Service Unavailable",
+ 505 => "HTTP Version Not Supported",
+ 511 => "Network Authentication Required"
+ );
+
+ /**
+ * Set result format
+ *
+ * (default value: array("json", "array", "object", "xml"))
+ *
+ * @var string
+ * @access private
+ */
+ private $result_format_available = array("json", "array", "object", "xml");
+
+ /**
+ * Result format
+ *
+ * json/array/object/xml
+ *
+ * (default value: "json")
+ *
+ * @var string
+ * @access private
+ */
+ private $result_format = "json";
+
+ /**
+ * To store result
+ *
+ * @var mixed
+ * @access private
+ */
+ public $result = array(
+ "success" => true,
+ "code" => 204,
+ "message" => ""
+ );
+
+
+
+
+
+ /**
+ * __construct function.
+ *
+ * @access public
+ * @param bool|mixed $api_url (default: false)
+ * @param bool|mixed $app_id (default: false)
+ * @param bool|mixed $api_key (default: false)
+ * @param bool|mixed $username (default: false)
+ * @param bool|mixed $password (default: false)
+ * @param mixed $result_format (default: "json")
+ */
+ public function __construct($api_url = false, $app_id = false, $api_key = false, $username = false, $password = false, $result_format = "json") {
+ // set app server URL if provided
+ if ($api_url!==false) {
+ $this->set_api_url ($api_url);
+ }
+ // set app_id if provided
+ if ($app_id!==false) {
+ $this->set_api_app_id ($app_id);
+ }
+ // set api key if provided
+ if ($api_key!==false) {
+ $this->set_api_key ($api_key);
+ }
+ // set user/pass if provided
+ if ($username!==false && $password!==false) {
+ $this->set_api_authparams ($username, $password);
+ }
+ // set result format if provided
+ if (strlen($result_format)>0) {
+ $this->set_result_format ($result_format);
+ }
+ // check for required php extensions
+ $this->validate_php_extensions ();
+ }
+
+ /**
+ * Saves error and exits script
+ *
+ * @access public
+ * @param mixed $content
+ * @return void
+ */
+ public function exception ($content) {
+ //set result parameters
+ $this->result = array(
+ 'code' => 400,
+ 'success' => false,
+ 'message' => $content
+ );
+ // print result
+ $this->print_result ();
+ // die
+ die();
+ }
+
+ /**
+ * Returns last result
+ *
+ * @access public
+ * @return void
+ */
+ public function get_result () {
+ # output result
+ if ($this->result_format=="json") {
+ return json_encode($this->result);
+ }
+ elseif ($this->result_format=="array") {
+ return $this->result;
+ }
+ elseif ($this->result_format=="object") {
+ return (object) $this->result;
+ }
+ elseif ($this->result_format=="xml") {
+ // new SimpleXMLElement object
+ $xml = new SimpleXMLElement('<'.$_GET['controller'].'/>');
+ // generate xml from result
+ $this->array_to_xml($xml, $this->result);
+ // return XML result
+ return $xml->asXML();
+ }
+ }
+
+ /**
+ * Prints last result
+ *
+ * @access public
+ * @return void
+ */
+ public function print_result () {
+ # output result
+ if ($this->result_format=="json") {
+ print json_encode($this->result);
+ }
+ elseif ($this->result_format=="array") {
+ var_dump($this->result);
+ }
+ elseif ($this->result_format=="object") {
+ var_dump( (object) $this->result);
+ }
+ elseif ($this->result_format=="xml") {
+ // new SimpleXMLElement object
+ $xml = new SimpleXMLElement('<apiclient/>');
+ // generate xml from result
+ $this->array_to_xml($xml, $this->result);
+ // return XML result
+ print $xml->asXML();
+ }
+ }
+
+ /**
+ * Transforms array to XML
+ *
+ * @access private
+ * @param SimpleXMLElement $object
+ * @param array $data
+ * @return void
+ */
+ private function array_to_xml(SimpleXMLElement $object, array $data) {
+ // loop through values
+ foreach ($data as $key => $value) {
+ // if spaces exist in key replace them with underscores
+ if(strpos($key, " ")>0) { $key = str_replace(" ", "_", $key); }
+
+ // if key is numeric append item
+ if(is_numeric($key)) $key = "item".$key;
+
+ // if array add child
+ if (is_array($value)) {
+ $new_object = $object->addChild($key);
+ $this->array_to_xml($new_object, $value);
+ }
+ // else write value
+ else {
+ $object->addChild($key, $value);
+ }
+ }
+ }
+
+ /**
+ * Check if all extensions are present
+ *
+ * @access private
+ * @return void
+ */
+ private function validate_php_extensions () {
+ // Required extensions
+ $required_ext = array("openssl", "curl");
+ // mcrypt for crypted extensions
+ if($this->api_key !== false)
+ $required_ext[] = "mcrypt";
+ // json
+ if($this->result_format == "json")
+ $required_ext[] = "json";
+ // xml
+ if($this->result_format == "xml")
+ $required_ext[] = "xmlreader";
+
+ // Available extensions
+ $available_ext = get_loaded_extensions();
+
+ // check
+ foreach ($required_ext as $e) {
+ if(!in_array($e, $available_ext)) {
+ $this->exception("Missing php extension ($e)");
+ }
+ }
+ }
+
+ /**
+ * Debugging flag
+ *
+ * @access public
+ * @param bool $debug (default: false)
+ * @return void
+ */
+ public function set_debug ($debug = false) {
+ if(is_bool($debug)) {
+ $this->debug = $debug;
+ }
+ }
+
+ /**
+ * Checks requested result format and saves it
+ *
+ * @access public
+ * @param string $result_format (default: "json")
+ * @return void
+ */
+ public function set_result_format ($result_format = "json") {
+ if (strlen($result_format)>0) {
+ if (!in_array($result_format, $this->result_format_available)) {
+ $this->exception ("Invalid result format");
+ }
+ else {
+ // recheck extensions
+ $this->validate_php_extensions ();
+ // set
+ $this->result_format = $result_format;
+ }
+ }
+ }
+
+ /**
+ * Set API url parameter
+ *
+ * @access public
+ * @param mixed $api_url
+ * @return void
+ */
+ public function set_api_url ($api_url) {
+ // we need http/https
+ if(strpos($api_url, "http://")!==false || strpos($api_url, "https://")!==false) {
+ // trim
+ $api_url = trim($api_url);
+ // add last / if missing
+ if (substr($api_url, -1)!=="/") { $api_url .= "/"; }
+ // save
+ $this->api_url = $api_url;
+ }
+ else {
+ $this->exception("Invalid APP id");
+ }
+ }
+
+ /**
+ * Sets api app_id variable
+ *
+ * @access public
+ * @param bool $id (default: false)
+ * @return void
+ */
+ public function set_api_app_id ($app_id = false) {
+ if ($app_id!==false) {
+ // name must be more than 2 and alphanumberic
+ if(strlen($app_id)<3 || strlen($app_id)>12 || !ctype_alnum($app_id)) {
+ $this->exception("Invalid APP id");
+ }
+ else {
+ $this->api_app_id = $app_id;
+ }
+ }
+ else {
+ $this->exception("Invalid APP id");
+ }
+ }
+
+ /**
+ * Set api key
+ *
+ * @access public
+ * @param bool $api_key (default: false)
+ * @return void
+ */
+ public function set_api_key ($api_key = false) {
+ if ($api_key!==false) {
+ $this->api_key = $api_key;
+
+ // set encrypt flag
+ $this->api_encrypt = true;
+ }
+ else {
+ $this->exception("Invalid APP id");
+ }
+ }
+
+ /**
+ * Sets username/password for URL auth
+ *
+ * @access public
+ * @param bool $username (default: false)
+ * @param bool $password (default: false)
+ * @return void
+ */
+ public function set_api_authparams ($username = false, $password = false) {
+ if($username===false || $password===false) {
+ $this->exception("Invalid username or password");
+ }
+ else {
+ $this->api_username = $username;
+ $this->api_password = $password;
+ }
+ }
+
+ /**
+ * Sreets api method.
+ *
+ * @access public
+ * @param string $method (default: "GET")
+ * @return void
+ */
+ public function set_api_method ($method = "GET") {
+ // validate
+ $this->set_api_method_validate ($method);
+ // set
+ $this->api_server_method = strtoupper($method);
+ }
+
+ /**
+ * Validates API method against available
+ *
+ * @access private
+ * @param mixed $method
+ * @return void
+ */
+ private function set_api_method_validate ($method) {
+ if(!in_array(strtoupper($method), $this->api_server_valid_methods)) {
+ $this->exception("Invalid method $method");
+ }
+ }
+
+ /**
+ * Sets API controller - required
+ *
+ * @access public
+ * @param bool $controller (default: false)
+ * @return void
+ */
+ public function set_api_controller ($controller = false) {
+ if($controller!==false) {
+ $this->api_server_controller = strtolower($controller);
+ }
+ else {
+ $this->exception("Invalid controller $controller");
+ }
+ }
+
+ /**
+ * Sets additional identifiers to be passed to URL directly
+ *
+ * e.g.: /api/appid/controller/<identifier1>/<identifier2>/
+ *
+ * @access public
+ * @param mixed $identifiers
+ * @return void
+ */
+ public function set_api_identifiers ($identifiers) {
+ if(is_array($identifiers)) {
+ if(sizeof($identifiers)>0 && !$this->api_encrypt) {
+ // reset
+ $this->api_server_identifiers = implode("/", $identifiers);
+ }
+ elseif (sizeof($identifiers)>0 && $this->api_encrypt) {
+ $this->api_server_identifiers = array();
+ foreach ($identifiers as $cnt=>$i) {
+ if($cnt==0) { $this->api_server_identifiers['id'] = $i; }
+ else { $this->api_server_identifiers['id'.$i] = $i; }
+ }
+
+ }
+ }
+ }
+
+
+
+
+
+
+
+
+
+
+
+ /* @api-server communication --------------- */
+
+ /**
+ * Executes request to API server
+ *
+ * @access public
+ * @param bool $method (default: false)
+ * @param bool $controller (default: false)
+ * @param array $identifiers (default: array())
+ * @param array $params (default: array())
+ * @param bool $token_file (default: false)
+ * @return void
+ */
+ public function execute ($method = false, $controller = false, $identifiers = array(), $params = array(), $token_file = false) {
+ // check and set method
+ $this->set_api_method ($method);
+ // set api controller
+ $this->set_api_controller ($controller);
+ // set api identifiers
+ $this->set_api_identifiers ($identifiers);
+
+ // set connection
+ $this->curl_set_connection ($token_file);
+ // save params
+ $this->curl_set_params ($params);
+ // set HTTP method
+ $this->curl_set_http_method ();
+
+ // if not encrypted set params
+ if(!$this->api_encrypt) {
+ // add token to header, authenticate if it fails
+ $this->curl_add_token_header ($token_file);
+ }
+ // if token is set execute
+ if ($this->token !== false) {
+ // execute
+ $res = $this->curl_execute ();
+ // save result
+ $this->result = (array) $res;
+
+ // check for invalid token and retry
+ if ($this->result['code']=="401" && $token_file!==false) {
+ // remove old token
+ $this->delete_token_file ($token_file);
+ // auth again
+ $this->curl_add_token_header ($token_file);
+ // execute
+ $res = $this->curl_execute ();
+ // save result
+ $this->result = (array) $res;
+ }
+ }
+ // exncrypted request
+ elseif ($this->api_encrypt) {
+ // execute
+ $res = $this->curl_execute ();
+ // save result
+ $this->result = (array) $res;
+ }
+ }
+
+ /**
+ * Opens cURL resource and sets initial parameters
+ *
+ * @access private
+ * @param mixed $token_file
+ * @return void
+ */
+ private function curl_set_connection ($token_file) {
+ // check if it exists
+ if ($this->Connection!==false) {
+ // Get cURL resource
+ $this->Connection = curl_init();
+
+ // set default curl options and params
+ curl_setopt_array($this->Connection, array(
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_URL => $this->api_url.$this->api_app_id.str_replace("//", "/", "/".$this->api_server_controller."/".$this->api_server_identifiers."/"),
+ CURLOPT_HEADER => 0,
+ CURLOPT_VERBOSE => $this->debug,
+ CURLOPT_TIMEOUT => 4,
+ CURLOPT_HTTPHEADER => array("Content-Type: application/json"),
+ CURLOPT_USERAGENT => 'phpipam-api php class',
+ // ssl
+ CURLOPT_SSL_VERIFYHOST => false,
+ CURLOPT_SSL_VERIFYPEER => false
+ )
+ );
+ }
+ }
+
+ /**
+ * Adds params to request if required
+ *
+ * @access private
+ * @param mixed $params
+ * @return void
+ */
+ private function curl_set_params ($params) {
+ // params set ?
+ if (is_array($params) && !$this->api_encrypt ) {
+ if (sizeof($params)>0) {
+ curl_setopt($this->Connection, CURLOPT_URL, $this->api_url.$this->api_app_id.str_replace("//", "/", "/".$this->api_server_controller."/".$this->api_server_identifiers."/?".http_build_query($params)));
+ }
+ }
+ // encrypt
+ elseif ($this->api_encrypt) {
+ // empty
+ if(!is_array($params)) $params = array();
+ if(!is_array($this->api_server_identifiers)) $this->api_server_identifiers = array();
+
+ // join identifiers and parameters
+ $params = array_merge($this->api_server_identifiers, $params);
+ $params['controller'] = $this->api_server_controller;
+
+ // create encrypted request
+ $encrypted_request = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->api_key, json_encode($params), MCRYPT_MODE_ECB));
+
+ // reset url
+ curl_setopt($this->Connection, CURLOPT_URL, $this->api_url."?app_id=".$this->api_app_id."&enc_request=".$encrypted_request);
+ }
+ }
+
+ /**
+ * Sets HTTP method to use for queries
+ *
+ * @access private
+ * @return void
+ */
+ private function curl_set_http_method () {
+ curl_setopt($this->Connection, CURLOPT_CUSTOMREQUEST, $this->api_server_method);
+ }
+
+ /**
+ * Adds token to http header
+ *
+ * @access private
+ * @param mixed $token_file
+ * @return void
+ */
+ private function curl_add_token_header ($token_file) {
+ if($token_file!==false) {
+ // open file and save token
+ $token = @file($token_file);
+ // save token
+ if(isset($token[0])) {
+ $this->token = $token[0];
+ $this->token_expires = $token[1];
+
+ // is token still valid ?
+ if ($this->token_expires < time()) {
+ // initiate authentication
+ $this->curl_authenticate ();
+ //save token to file
+ $this->write_token_file ($token_file);
+ }
+ }
+ else {
+ $this->curl_authenticate ();
+ //save token to file
+ $this->write_token_file ($token_file);
+
+ }
+ }
+ // token not saved, try to retrieve it
+ else {
+ $this->curl_authenticate ();
+ }
+
+ // add token to headers
+ $this->curl_add_http_header ("token", $this->token);
+ }
+
+ /**
+ * Adds http headers
+ *
+ * @access private
+ * @param mixed $name
+ * @param mixed $value
+ * @return void
+ */
+ private function curl_add_http_header ($name, $value) {
+ $headers = array(
+ "Content-Type: application/json",
+ "$name: $value"
+ );
+ // save
+ curl_setopt($this->Connection, CURLOPT_HTTPHEADER, $headers);
+ }
+
+ /**
+ * Writes token to token file
+ *
+ * @access private
+ * @param mixed $filename
+ * @return void
+ */
+ private function write_token_file ($filename) {
+ //save token
+ try {
+ $myfile = fopen($filename, "w");
+ fwrite($myfile, $this->token);
+ fwrite($myfile, "\n");
+ fwrite($myfile, $this->token_expires);
+ // close file
+ fclose($myfile);
+ }
+ catch ( Exception $e ) {
+ $this->exception("Cannot write file $filename");
+ }
+ }
+
+ /**
+ * Removes token file if expired / invalid
+ *
+ * @access private
+ * @param mixed $token_file
+ * @return void
+ */
+ private function delete_token_file ($token_file) {
+ //save token
+ try {
+ $myfile = fopen($token_file, "w");
+ fwrite($myfile, "");
+ // close file
+ fclose($myfile);
+ }
+ catch ( Exception $e ) {
+ $this->exception("Cannot write file $token_file");
+ }
+ }
+
+ /**
+ * Executes request.
+ *
+ * @access private
+ * @return void
+ */
+ private function curl_execute () {
+ // send request and save response
+ $resp = curl_exec($this->Connection);
+
+ // curl error check
+ if (curl_errno($this->Connection)) {
+ $this->exception("Curl error: ".curl_error($this->Connection));
+ }
+ else {
+ // return result object
+ return json_decode($resp);
+ }
+ }
+
+ /**
+ * send authenticate request and save token if provided, otherwise throw error.
+ *
+ * @access private
+ * @return void
+ */
+ private function curl_authenticate () {
+ // Get cURL resource
+ $c_auth = curl_init();
+
+ // set default curl options and params
+ curl_setopt_array($c_auth, array(
+ CURLOPT_RETURNTRANSFER => 1,
+ CURLOPT_URL => $this->api_url.$this->api_app_id."/user/",
+ CURLOPT_HEADER => 0,
+ CURLOPT_VERBOSE => $this->debug,
+ CURLOPT_TIMEOUT => 4,
+ CURLOPT_USERAGENT => 'phpipam-api php class',
+ // ssl
+ CURLOPT_SSL_VERIFYHOST => 0,
+ CURLOPT_SSL_VERIFYPEER => 0,
+ CURLOPT_POST => true,
+ CURLOPT_HTTPHEADER => array('Authorization: Basic '. base64_encode($this->api_username.":".$this->api_password))
+ )
+ );
+ // send request and save response
+ $resp = curl_exec($c_auth);
+
+ // curl error check
+ if (curl_errno($c_auth)) {
+ $this->exception("Curl error: ".curl_error($c_auth));
+ }
+ else {
+ // return result object
+ $auth_resp = json_decode($resp);
+ // ok ?
+ if ($auth_resp->code == 200) {
+ if (isset($auth_resp->data->token)) {
+ // save token
+ $this->token = $auth_resp->data->token;
+ $this->token_expires = strtotime($auth_resp->data->expires);
+ }
+ else {
+ $this->exception("Cannot obtain access token");
+ }
+ }
+ // error
+ else {
+ // save response
+ $this->result = $auth_resp;
+ }
+ }
+ }
+
+}
?>
diff --git a/php-client/example.php b/php-client/example.php
new file mode 100644
index 0000000..74ea511
--- /dev/null
+++ b/php-client/example.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ *
+ * example usage of phpipam_api_client class
+ *
+ *
+ */
+
+# include config file and api client class file
+require("api-config.php");
+require("class.phpipam-api.php");
+
+# init object with settings from
+$API = new phpipam_api_client ($api_url, $api_app_id, $api_key, $api_username, $api_password, $result_format);
+# debug - only to debug curl
+$API->set_debug (false);
+# execute - result is stored to $API->result, save it to own array if multiple calls needed after execute
+$API->execute ("GET", "sections", array(5), array(), $token_file);
+# ger result
+$result = $API->get_result();
+
+# print result
+print_r($result);
+?> \ No newline at end of file