pyATS事始め#2 - Genie Conf を使ったインターフェイス設定

# pyATSの続き

今回も写経ベース、[Genie ConfによるCisco機器のConfig自動生成][2]のインターフェイス設定だけ写経

その前に Cisco DevNETのpyATS Documentsに[pyATS Getting Started][1] が新しくできた

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Learning a new infrastructure may be a daunting task... and that&#39;s why we&#39;re always working on ways to help you get automating with <a href="https://twitter.com/hashtag/pyATS?src=hash&amp;ref_src=twsrc%5Etfw">#pyATS</a>. The team is thrilled to announce the latest getting started guide @ <a href="https://t.co/eZ7e7wWFnU">https://t.co/eZ7e7wWFnU</a> <br><br>Let us know if you like it!</p>&mdash; Siming Yuan (@simingy) <a href="https://twitter.com/simingy/status/1171175110411214848?ref_src=twsrc%5Etfw">September 9, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## 写経環境

pyATS19.8 with VIRL、既に物理インターフェイスは接続済みなので Loopback Interfaceを作成

## Example code

ref.) [Configure a device without using any command - Conf object][3]

```python
from genie.conf import Genie
from genie.conf.base import Interface

# Load genie testbed
testbed = Genie.init('../testbed.yaml')
csr1 = testbed.devices['csr1000v-1']
csr1.connect()

# create an IOS-XE loopback 1 interface
csr1_interface = Interface(device=csr1, name='Loopback1')
csr1_interface.ipv4 = '200.1.1.1'
csr1_interface.ipv4.netmask = '255.255.255.0'

print(csr1_interface.build_config(apply=False))


csr1_interface.build_config() # To apply on the device
csr1_interface.build_unconfig() # To remove configuration
```

### 実行結果

#### dry-run（のようなもの）

device にconfigを設定するのは build_config()のようだけど、apply=Falseとすることで
configだけを表示してくれる dry-run を実施

```shell
...snip...

csr1000v-1#
interface Loopback1
 ip address 200.1.1.1 255.255.255.0
 exit
```

##### 該当コード

```python
# create an IOS-XXE loopback 1 interface
csr1_interface = Interface(device=csr1, name='Loopback1')
csr1_interface.ipv4 = '200.1.1.1'
csr1_interface.ipv4.netmask = '255.255.255.0'

print(csr1_interface.build_config(apply=False))
```

#### 設定/削除

あとは build_config() でdeviceにconfigを流し込んで、build_unconfig()で
device に設定したconfigを削除する。

```shell
[2019-09-12 13:03:01,272] +++ csr1000v-1: config +++
config term
Enter configuration commands, one per line.  End with CNTL/Z.
csr1000v-1(config)#interface Loopback1
csr1000v-1(config-if)# ip address 200.1.1.1 255.255.255.0
csr1000v-1(config-if)# exit
csr1000v-1(config)#end
csr1000v-1#
[2019-09-12 13:03:01,495] +++ csr1000v-1: config +++
config term
Enter configuration commands, one per line.  End with CNTL/Z.
csr1000v-1(config)#no interface Loopback1
csr1000v-1(config)#end
```
##### 該当コード

```python
csr1_interface.build_config() # To apply on the device
csr1_interface.build_unconfig() # To remove configuration
```

### まとめ

build_config()に apply=Falseを引数として渡すと dry-runになり、引数を与えないと実際にConfigを適用する
build_unconfig()で設定したConfigを削除することができる。

今回はLoopback Interfaceを設定するとてもシンプルな設定なので
build_unconfig()が  no int lo1 をするのはわかるのだけど、vrfや protocol *** のときはどう消すのか、別途試してみたい。

### おまけ

csr1_interface instanceはどういったpropertyを持つのか気になったので iPythonでお試し

```python
In [1]: from genie.conf import Genie 
   ...: from genie.conf.base import Interface 
   ...:  
   ...: # Load genie testbed 
   ...: testbed = Genie.init('../testbed.yaml') 
   ...: csr1 = testbed.devices['csr1000v-1'] 
   ...: csr1.connect() 
   ...:  
   ...: # create an IOS-XXE loopback 1 interface 
   ...: csr1_interface = Interface(device=csr1, name='Loopback1')

In [2]: type(csr1_interface)                                                                                                                    
Out[2]: genie.libs.conf.interface.iosxe.interface.LoopbackInterface

In [3]: for key, value in csr1_interface.__dict__.items():  
   ...:     print(key, ': ', value)  
   ...:                                                                                                                                         
aliases :  []
alias :  Loopback1
features :  set()
name :  Loopback1
__device__ :  <weakref at 0x7ffb5a3c2278; to 'Device' at 0x7ffb5aa6cf60>
type :  None
_ipv4 :  None
_ipv6 :  None
__link__ :  Link csr1000v-1:Loopback1
_link :  Link csr1000v-1:Loopback1         
```

[1]: https://developer.cisco.com/docs/pyats-getting-started/
[2]: https://qiita.com/tech_kitara/items/cf39ecf0ae409235bf5d
[3]: https://pubhub.devnetcloud.com/media/pyats-packages/docs/genie/cookbooks/conf.html#configure-a-device-without-using-any-command-conf-object