phpでjuniper SSG5のコンフィグファイルを解析（配列化）する

業務自動化で必要になってくるものと思い作りました。

適当に作ったので無駄なことが多いかもしれませんが、とりあえず投稿してブラシュアップできたらと思います。
またあまりphpのクラス作成にもなれてないのでお作法ができていないと思われます。

SSG５設定コマンドのスペース区切りを階層と考えて、XMLファイルでコマンド階層のパスを追っていく仕組みにすることで、他の製品のコマンドにも応用できるプログラム作成ができるようになればと考え作りました。（実際は難しいですが土台くらいは同じ仕様にできそうな気がしてます。）




##使い方(SsgPaser.php)
```php
<?php
include_once "SsgPaser.php";


$ssg = new SsgPaser;

//コンフィグファイルを指定する
$configfile = "d:¥cfg.txt";
$ssg->setFilename($configfile);

//コンフィグファイルを解析する
$ssg->convertAllArray();

//アドレスオブジェクトの一覧取得（配列）
$address = $ssg->getAddressRaw();

//ポリシーの一覧取得（配列）
$policy = $ssg->getPolicyRaw();


```




##PHPクラス本体
```php

<?php


class SsgParser{
	
	private $data = array();
	private $srx_array = array();
	private $ssgconfigtemplate;
	private $rowin =0;
	private $currentcmd = "/configdata";
	private $optionpath = "";
	private $optionmode = 0;
	private $parts_array = array();
	private $all_array   = array();
	private $nexttype    = "";
	private $next        = "";
	private $lastobjectname = "";
	private $mode        = 0;
	private $lastpolicyid = "";
	private $debugmode    = 0;
	function setFilename($value)
	{
		$this->data["filename"] = $value;
	}

	function getFilename()
	{
		return $this->data["filename"];
	}
	
	function setSsgconfigtemplate()
	{
		$this->ssgconfigtemplate = simplexml_load_file(dirname(__FILE__) .'/ssgconfigtemplate.xml');
	}
	function debugmode()
	{
		$this->debugmode = 1;
	}
	function convertAllArray()
	{
		//$contents = file_get_contents($this->data["filename"]);


		$this->setSsgconfigtemplate();
			
		$zh = gzopen($this->data["filename"],"rb");
		if ($zh == false) {
			print "gzファイルのオープンに失敗しました。\n";
			exit;
		}
		
		while (gzeof($zh) == false) {
			
			$line = "";
			$line = gzgets($zh);
			
			//1行をスペース区切りで配列に格納
			$ssv_array = str_getcsv($line," ",'"');
			
			$ssv_array = array_filter($ssv_array, "strlen");
			//var_dump($ssv_array);
			
			foreach ($ssv_array as $word) {
				$r = $this->processing($word,0);
				if($r == 0){
					break;
				}
			}
			
			$this->processing("",1);
		
		}
		
		if($this->debugmode == 1){
			//var_dump($this->all_array['global']);	
		}
	}
	
	
	function nextpath($path,$word)
	{
		
		//echo "----".$path."\n";

		if($word =="+"){
			//echo "&&&&\n";
			//$word = "plus";
			$word = "protocol";
		}
		$result = $this->ssgconfigtemplate->xpath($path);
		
		$nexttype = (string)$result[0]->attributes->nexttype;
		
		//$nexttype = (string)$this->nexttype;
		//var_dump($nexttype);
		//echo "####".$nexttype."\n";
		
		
		if($word == ""){
			$nextpath = 0;
		} else {
			if($nexttype =="mode"){
				$nextpath = $path."/".$word;
			} else if($nexttype == "object"){
				$nextpath = $path."/".$word;
			} else if($nexttype == "value"){
				$next     = (string)$result[0]->attributes->next;
				//$this->next = (string)$result[0]->attributes->next;
				$nextpath = $path."/".$next;
			} else {
				$nextpath = $path."/".$word;
			}
		} 
		
		return $nextpath;
	}
	function processing($word,$eol)
	{
		$retrun = 1;
		$objectname = "";
		$next = "";
		if($word == ""){
			$retrun = 0;
		} else {

			//今回処理するパスを取得
			$parentpath = $this->currentcmd;
			$nextpath = $this->nextpath($this->currentcmd,$word);
			$this->currentcmd = $nextpath;
			
			if($this->debugmode == 1){
				echo "++++after   ". $word ."  :  "  .$this->currentcmd."\n";
			}
			//今回のパスからパラメータを取得
			$result = $this->ssgconfigtemplate->xpath( $nextpath );
			
			//行中かどうか
			//echo $this->rowin;
			if($this->rowin == 0){
				//echo $this->currentcmd;
				$this->rowin = 1;
			} else {

			}
			
			//設定モードの検知
			if(isset($result[0]->attributes->modechenge)){

				$modechenge  = (string)$result[0]->attributes->modechenge;
				//echo "$$$$ modechenge".$modechenge."\n";
				$this->mode = $modechenge;
			} else {
				//$modechenge  = 0;
			}
			
			
			
			if (count($result) == 0){
				//パラメータ情報がなかった場合リターン０で終了
				
				if($this->debugmode == 1){
					echo "!!!!" .$word."\n";
				}
				$retrun = 0;
				
				//echo "none\n";
			} else { //(count($result) 
				//今回のタイプ
				
				if(isset($result[0]->attributes->type)){
					//echo "ok\n";
					$type = (string)$result[0]->attributes->type;
				} else {
					echo "ng\n";
					exit;
				}
				//var_dump($result[0]);
				

				if($type == "mode"){
				} else if($type == "object"){
					//今回のオブジェクト
					$this->lastobjectname = (string)$result[0]->attributes->objectname;
					//var_dump($this->lastobjectname);
					//echo $objectname;
				} else if($type == "option"){
					//オプション前のパスを記録
					$this->optionpath = $parentpath;
					$this->optionmode = 1;
					
					if(isset($result[0]->attributes->valuename)){
						
						$valuename =(string)$result[0]->attributes->valuename;
						$this->parts_array[$valuename] = $word;
					} else {
					}
				} else if($type == "value"){
					//var_dump($result);
					$valuename  = $result[0]->attributes->valuename->__toString();
					
					$this->parts_array[$valuename] = $word;
					
				} else if($type == "exit"){
					
					if($this->mode > 0){
						$this->mode = 0;
					}
					
					$this->lastpolicyid = "";
				} //$type == "mode"
				
				
				
				if(isset($result[0]->attributes->next)){
					//echo "ok\n";
					$next  = (string)$result[0]->attributes->next;
					//var_dump($next);
				} else {
					
					$next = "";
					//echo "next get ng\n";
					//exit;
				}
				if($next == "none"){
					if($this->optionmode ==1){
						//オプション前のパスに戻す
						//echo "%%%%%% next:".$next."   optionpath:".$this->optionpath."\n";
						$this->currentcmd = $this->optionpath;
						$this->optionmode = 0;
					} else {
					}
				}
			} //(count($result) 
		} //$word == ""
		
		
		
		//var_dump($this->ssgconfigtemplate);
		if($eol ==1 ){
			//echo "改行\n";
			
			$this->currentcmd = "/configdata";
			$this->rowin = 0;
			$this->nexttype = "";
			//echo "3333 : ".$this->nexttype."\n";
			$this->next = "";
			
			if(count($this->parts_array) == 0){
			} else {
				//var_dump($this->lastobjectname);
				//$objectname = "aaa";
				
				if($this->mode == 1){
					//policy本体
					

					$parts_array_tmp = $this->parts_array;
					$this->parts_array['src'] = Array(0 => $this->parts_array['src']);
					$this->parts_array['dst'] = Array(0 => $this->parts_array['dst']);
					$this->parts_array['service'] = Array(0 => $this->parts_array['service']);
					
					//var_dump($this->parts_array);
					$this->all_array['policy'][$this->parts_array['id']] = $this->parts_array;
					
				} else if ($this->mode == 2){
					//policyマルチ
					
					if($this->lastobjectname == "policy"){
						
						//var_dump($this->parts_array);
						$this->lastpolicyid = $this->parts_array['id'];
						
					} else if($this->lastobjectname == "policy_multiple_src"){
						
						$this->all_array['policy'][$this->lastpolicyid]['src'][] = $this->parts_array['src-address'];
					} else if($this->lastobjectname == "policy_multiple_dst"){
						$this->all_array['policy'][$this->lastpolicyid]['dst'][] = $this->parts_array['dst-address'];
					} else if($this->lastobjectname == "policy_multiple_service"){
						$this->all_array['policy'][$this->lastpolicyid]['service'][] = $this->parts_array['service'];
					}
					//var_dump($this->parts_array);
					
				} else {
					$this->all_array[$this->lastobjectname][] = $this->parts_array;
					//var_dump($this->parts_array);
				}
				
				//var_dump($this->all_array);
			}
			$this->parts_array = array();
		}
		
		return $retrun;
	}
		
	function getPolicyRaw()
	{

		$policy = $this->all_array['policy'];
		
		return $policy;
	}
	function getAddressRaw()
	{

		$address = $this->all_array['address'];
		
		return $address;
	}
	function getServiceRaw()
	{

		$service = $this->all_array['service'];
		
		return $service;
	}
	function getGlobalRaw()
	{

		$global = $this->all_array['global'];
		
		return $global;
	}
	
	function getHostname()
	{

		$global = $this->all_array['global'];
		
		//var_dump($global);
		$key = array_search('hostname', $global);
		
		$hostname = $global[$key]['hostname'];
		return $hostname;
	}
	function allDump()
	{
		var_dump($this->all_array);
	}
	function getSecurityArray($type)
	{
		$security = $this->getSecurityRaw();
	}
}
```
##XMLファイル(ssgconfigtemplate.xml)
```
<?xml version="1.0"?>
<configdata>
	<attributes>
		<type>mode</type>
		<nexttype>mode</nexttype>
	</attributes>
	<set>
		<attributes>
			<type>mode</type>
			<nexttype>mode</nexttype>
		</attributes>
		<hostname>
			<attributes>
				<type>object</type>
				<objectname>global</objectname>
				<nexttype>value</nexttype>
				<next>value1</next>
			</attributes>
			<value1>
				<attributes>
					<type>value</type>
					<nexttype>none</nexttype>
					<valuename>hostname</valuename>
					<next>none</next>
				</attributes>
			</value1>
		</hostname>
		<service>
			<attributes>
				<type>object</type>
				<objectname>service</objectname>
				<nexttype>value</nexttype>
				<next>value1</next>
			</attributes>
			<value1>
				<attributes>
					<type>value</type>
					<nexttype>variable</nexttype>
					<valuename>name</valuename>
					<next>option</next>
				</attributes>
				<protocol>
					<attributes>
						<type>option</type>
						<nexttype>value</nexttype>
						<next>value1</next>
					</attributes>
					<value1>
						<attributes>
							<type>value</type>
							<nexttype>none</nexttype>
							<valuename>protocol</valuename>
							<next>none</next>
						</attributes>
					</value1>
				</protocol>
				<src-port>
					<attributes>
						<type>option</type>
						<nexttype>value</nexttype>
						<next>value1</next>
					</attributes>
					<value1>
						<attributes>
							<type>value</type>
							<nexttype>none</nexttype>
							<valuename>src-port</valuename>
							<next>none</next>
						</attributes>
					</value1>
				</src-port>
				<dst-port>
					<attributes>
						<type>option</type>
						<nexttype>value</nexttype>
						<next>value1</next>
					</attributes>
					<value1>
						<attributes>
							<type>value</type>
							<nexttype>none</nexttype>
							<valuename>dst-port</valuename>
							<next>none</next>
						</attributes>
					</value1>
				</dst-port>
				<timeout>
					<attributes>
						<type>option</type>
						<nexttype>value</nexttype>
						<next>value1</next>
					</attributes>
					<value1>
						<attributes>
							<type>value</type>
							<nexttype>none</nexttype>
							<valuename>timeout</valuename>
							<next>none</next>
						</attributes>
					</value1>
				</timeout>
			</value1>
		</service>
		<address>
			<attributes>
				<type>object</type>
				<objectname>address</objectname>
				<nexttype>value</nexttype>
				<next>value1</next>
			</attributes>
			<value1>
				<attributes>
					<type>value</type>
					<nexttype>value</nexttype>
					<valuename>zone</valuename>
					<next>value2</next>
				</attributes>
				<value2>
					<attributes>
						<type>value</type>
						<nexttype>value</nexttype>
						<valuename>addressname</valuename>
						<next>value3</next>
					</attributes>
					<value3>
						<attributes>
							<type>value</type>
							<nexttype>value</nexttype>
							<valuename>ip</valuename>
							<next>value4</next>
						</attributes>
						<value4>
							<attributes>
								<type>value</type>
								<nexttype>value</nexttype>
								<valuename>ip</valuename>
								<next>value5</next>
							</attributes>
							<value5>
								<attributes>
									<type>value</type>
									<nexttype>none</nexttype>
									<valuename>comment</valuename>
									<next>none</next>
								</attributes>
							</value5>
						</value4>
					</value3>
				</value2>
			</value1>
		</address>
		<group>
			<attributes>
				<type>mode</type>
				<nexttype>object</nexttype>
			</attributes>
			<address>
				<attributes>
					<type>object</type>
					<objectname>groupaddress</objectname>
					<nexttype>value</nexttype>
					<next>value1</next>
				</attributes>
				<value1>
					<attributes>
						<type>value</type>
						<valuename>zone</valuename>
						<nexttype>value</nexttype>
						<next>value2</next>
					</attributes>
					<value2>
						<attributes>
							<type>value</type>
							<nexttype>none</nexttype>
							<valuename>name</valuename>
							<next>none</next>
						</attributes>
						<comment>
							<attributes>
								<type>option</type>
								<nexttype>value</nexttype>
								<next>value1</next>
							</attributes>
							<value1>
								<attributes>
									<type>value</type>
									<nexttype>none</nexttype>
									<valuename>comment</valuename>
									<next>none</next>
								</attributes>
							</value1>
						</comment>
						<add>
							<attributes>
								<type>option</type>
								<nexttype>value</nexttype>
								<next>value1</next>
							</attributes>
							<value1>
								<attributes>
									<type>value</type>
									<nexttype>none</nexttype>
									<valuename>add</valuename>
									<next>none</next>
								</attributes>
							</value1>
						</add>
					</value2>
				</value1>
			</address>
		</group>
		<policy>
			<attributes>
				<type>object</type>
				<objectname>policy</objectname>
				<nexttype>option</nexttype>
				<modechenge>2</modechenge>
			</attributes>
			<id>
				<attributes>
					<type>option</type>
					<nexttype>value</nexttype>
					<next>value1</next>
				</attributes>
				<value1>
					<attributes>
						<type>value</type>
						<nexttype>none</nexttype>
						<valuename>id</valuename>
						<next>none</next>
					</attributes>
				</value1>
			</id>
			<name>
				<attributes>
					<type>option</type>
					<nexttype>value</nexttype>
					<next>value1</next>
				</attributes>
				<value1>
					<attributes>
						<type>value</type>
						<nexttype>none</nexttype>
						<valuename>name</valuename>
						<next>none</next>
					</attributes>
				</value1>
			</name>
			<from>
				<attributes>
					<type>option</type>
					<nexttype>value</nexttype>
					<next>value1</next>
					<modechenge>1</modechenge>
				</attributes>
				<value1>
					<attributes>
						<type>value</type>
						<nexttype>none</nexttype>
						<valuename>srczone</valuename>
						<next>none</next>
					</attributes>
				</value1>
			</from>
			<to>
				<attributes>
					<type>option</type>
					<nexttype>value</nexttype>
					<next>value1</next>
				</attributes>
				<value1>
					<attributes>
						<type>value</type>
						<nexttype>value</nexttype>
						<valuename>dstzone</valuename>
						<next>value2</next>
					</attributes>
					<value2>
						<attributes>
							<type>value</type>
							<nexttype>value</nexttype>
							<valuename>src</valuename>
							<next>value3</next>
						</attributes>
						<value3>
							<attributes>
								<type>value</type>
								<nexttype>value</nexttype>
								<valuename>dst</valuename>
								<next>value4</next>
							</attributes>
							<value4>
								<attributes>
									<type>value</type>
									<nexttype>none</nexttype>
									<valuename>service</valuename>
									<next>none</next>
								</attributes>
							</value4>
						</value3>
					</value2>
				</value1>
			</to>
			<permit>
				<attributes>
					<type>option</type>
					<valuename>action</valuename>
					<nexttype>none</nexttype>
					<next>none</next>
				</attributes>
			</permit>
			<deny>
				<attributes>
					<type>option</type>
					<valuename>action</valuename>
					<nexttype>none</nexttype>
					<next>none</next>
				</attributes>
			</deny>
			<nat>
				<attributes>
					<type>option</type>
					<valuename>nat</valuename>
					<nexttype>none</nexttype>
					<next>none</next>
				</attributes>
			</nat>
			<src>
				<attributes>
					<type>option</type>
					<valuename>src</valuename>
					<nexttype>none</nexttype>
					<next>none</next>
				</attributes>
			</src>
			<webauth>
				<attributes>
					<type>option</type>
					<valuename>webauth</valuename>
					<nexttype>option</nexttype>
					<next>user</next>
				</attributes>
				<user>
					<attributes>
						<type>option</type>
						<valuename>webauth_user</valuename>
						<nexttype>value</nexttype>
						<next>value1</next>
					</attributes>
					<value1>
						<attributes>
							<type>value</type>
							<nexttype>none</nexttype>
							<valuename>webauth_user_id</valuename>
							<next>none</next>
						</attributes>
					</value1>
				</user>
			</webauth>
			<log>
				<attributes>
					<type>option</type>
					<valuename>log</valuename>
					<nexttype>none</nexttype>
					<next>none</next>
				</attributes>
			</log>
			
		</policy>
		<src-address>
			<attributes>
				<type>object</type>
				<objectname>policy_multiple_src</objectname>
				<nexttype>value</nexttype>
				<next>value1</next>
			</attributes>
			<value1>
				<attributes>
					<type>value</type>
					<nexttype>none</nexttype>
					<valuename>src-address</valuename>
					<next>none</next>
				</attributes>
			</value1>
		</src-address>
		<dst-address>
			<attributes>
				<type>object</type>
				<objectname>policy_multiple_dst</objectname>
				<nexttype>value</nexttype>
				<next>value1</next>
			</attributes>
			<value1>
				<attributes>
					<type>value</type>
					<nexttype>none</nexttype>
					<valuename>dst-address</valuename>
					<next>none</next>
				</attributes>
			</value1>
		</dst-address>
		<service>
			<attributes>
				<type>object</type>
				<objectname>policy_multiple_service</objectname>
				<nexttype>value</nexttype>
				<next>value1</next>
			</attributes>
			<value1>
				<attributes>
					<type>value</type>
					<nexttype>none</nexttype>
					<valuename>service</valuename>
					<next>none</next>
				</attributes>
			</value1>
		</service>
	</set>
	<exit>
		<attributes>
			<type>exit</type>
			<nexttype>none</nexttype>
		</attributes>
	</exit>
</configdata>
```


##課題
*