<div dir="ltr"><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small">Hi Phil,</div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small">For FRR we have been using the core Ansible template module to manage the frr.conf configuration file. Then to run an individual command I use the core command or shell modules. The reason for this is mostly so we don't have to write any sort of custom API's or wrappers to configure FRR. However you're idea is inline with many of the other vendors who have implemented a config via cli module and command module for their platforms. Cumulus put out a module with Ansible 2.3 using NCLU: <a href="http://docs.ansible.com/ansible/nclu_module.html" target="_blank">http://docs.ansible.com/ansib<wbr>le/nclu_module.html</a> which you can use to configure FRR and for running arbitrary commands on FRR and Linux OS in general. To be fair NCLU is mostly used in a Cumulus specific environment but if you want to do a command/config module I would take a look at that one. It kind of gives you the best of both worlds, CLI for running commands and idempotency using a templated file.</div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small">There are pros and cons to using a command CLI model versus a template model I would be happy to discuss and hear your thoughts it's something we've been going through a lot internally and with customers. I can see the value of a command module to "wrapper" the vtysh -c stuff and potentially eliminate the pain of order of operations.</div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small">Here are some examples of what we've been doing to maybe generate some ideas:</div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small">Example of an adhoc command:</div><div class="gmail_default" style="font-size:small"><font face="monospace, monospace">ansible -a "vtysh -c 'show ip route'" leaf01</font></div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small">Example for Ansible variable and template for configuring BGP (Since you mentioned you wanted to write modules I'll drop the code example here):</div><div><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small;display:inline">Routing </div><font face="verdana, sans-serif"><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small;display:inline">v</div>ariables:</font><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><div class="gmail_default" style="font-size:small;display:inline"></div><div class="gmail_default" style="font-size:small;display:inline"></div><div class="gmail_default" style="font-size:small;display:inline"></div>vars:</font></div><div><font face="monospace, monospace"> bgp:</font></div><div><font face="monospace, monospace"> leaf01:</font></div><div><font face="monospace, monospace"> myasn: "64603"</font></div><div><font face="monospace, monospace"> routerid: "10.30.1.1"</font></div><div><font face="monospace, monospace"> aggregate: "<a href="http://10.0.0.0/8">10.0.0.0/8</a>"</font></div><div><font face="monospace, monospace"> networks: ["<a href="http://192.168.254.0/24">192.168.254.0/24</a>","<a href="http://192.168.254.0/24">192.168.254.0/24</a>"]</font></div><div><font face="monospace, monospace"> internal_fabric:</font></div><div><font face="monospace, monospace"> interfaces: ["swp49","swp50","swp51","swp52"]</font></div><div><font face="monospace, monospace"> prefix_list_in: "allow_rack_subnets"</font></div><div><font face="monospace, monospace"> prefix_list_out: "allow_default"</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> prefix_lists:</font></div><div><font face="monospace, monospace"> leaf01:</font></div><div><font face="monospace, monospace"> allow_default:</font></div><div><font face="monospace, monospace"> - "10 permit <a href="http://0.0.0.0/0">0.0.0.0/0</a>"</font></div><div><font face="monospace, monospace"> - "100 deny any"</font></div><div><font face="monospace, monospace"> allow_rack_subnets:</font></div><div><font face="monospace, monospace"> - "10 permit <a href="http://192.168.254.0/24">192.168.254.0/24</a>"</font></div><div><font face="monospace, monospace"> - "20 permit <a href="http://10.0.0.0/8">10.0.0.0/8</a> le 32"</font></div><div><font face="monospace, monospace"> - "100 deny any"</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace">Template file:</font></div><div><font face="monospace, monospace">{% set bgpvars = bgp[ansible_hostname] -%}</font></div><div><font face="monospace, monospace">!</font></div><div><font face="monospace, monospace">router bgp {{ bgpvars.myasn }}</font></div><div><font face="monospace, monospace"> bgp router-id {{bgpvars.routerid}}</font></div><div><font face="monospace, monospace"> bgp bestpath as-path multipath-relax</font></div><div><font face="monospace, monospace"> aggregate-address {{bgpvars.aggregate}} summary-only</font></div><div><font face="monospace, monospace">{% for network in bgpvars.networks %}</font></div><div><font face="monospace, monospace"> network {{network}}</font></div><div><font face="monospace, monospace">{% endfor %}</font></div><div><font face="monospace, monospace">{### Build the spine/leaf fabric ###}</font></div><div><font face="monospace, monospace"> neighbor internal_fabric peer-group</font></div><div><font face="monospace, monospace"> neighbor internal_fabric remote-as external</font></div><div><font face="monospace, monospace"> neighbor internal_fabric capability extended-nexthop</font></div><div><font face="monospace, monospace"> neighbor internal_fabric prefix-list {{bgpvars.internal_fabric.prefix_list_out}} out</font></div><div><font face="monospace, monospace"> neighbor internal_fabric prefix-list {{bgpvars.internal_fabric.prefix_list_in}} in</font></div><div><font face="monospace, monospace">{### Configure interfaces ###}</font></div><div><font face="monospace, monospace">{% for interface in bgpvars.internal_fabric.interfaces %}</font></div><div><font face="monospace, monospace"> neighbor {{interface}} interface v6only peer-group internal_fabric</font></div><div><font face="monospace, monospace">{% endfor %}</font></div><div><font face="monospace, monospace">!</font></div><div><font face="monospace, monospace"> address-family ipv6 unicast</font></div><div><font face="monospace, monospace"> neighbor internal_fabric activate</font></div><div><font face="monospace, monospace"> exit-address-family</font></div><div><font face="monospace, monospace">!</font></div><div><font face="monospace, monospace">{### Configure prefix lists ###}</font></div><div><font face="monospace, monospace">{% set lists = prefix_lists[ansible_hostname] -%}</font></div><div><font face="monospace, monospace">{% for list_name in lists.keys() -%}</font></div><div><font face="monospace, monospace"> {% for seq in lists[list_name] %}</font></div><div><font face="monospace, monospace"> ip prefix-list {{list_name}} seq {{seq}}</font></div><div><font face="monospace, monospace">{% endfor %}</font></div><div><font face="monospace, monospace">{% endfor %}</font></div><div><font face="monospace, monospace">!</font></div><div><font face="monospace, monospace">end</font></div><div><br></div><div><br></div><div><span style="font-family:verdana,sans-serif"><br></span></div><div><span style="font-family:verdana,sans-serif">Regards,</span><div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small"><br></div><div class="gmail_default" style="font-family:verdana,sans-serif;font-size:small"><div style="font-family:arial,sans-serif;font-size:12.8px"><div class="gmail_default" style="font-size:small"><font face="verdana, sans-serif">Jason Heller</font></div></div><font face="verdana, sans-serif" style="font-size:12.8px">--<br></font><div class="gmail-m_1889258592868185365gmail-m_4790683621043348263gmail_signature" style="font-family:arial,sans-serif;font-size:12.8px"><div dir="ltr"><font face="verdana, sans-serif">Consulting Architect | Cumulus Networks | <a href="tel:(650)%20383-6700" value="+16503836700" target="_blank">+1 650.383.6700 x1193</a><br><br><font size="1">Join Cumulus on Slack: <a href="https://slack.cumulusnetworks.com/" target="_blank">https://slack.<wbr>cumulusnetworks.com/</a><br>Connect with me @jaheller</font></font></div></div></div></div></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, May 3, 2017 at 11:17 AM, Phil Huang <span dir="ltr"><<a href="mailto:phil_huang@edge-core.com" target="_blank">phil_huang@edge-core.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Donald,<br>
<br>
Thanks for your introduction<br>
<br>
Hi Jason,<br>
<br>
Nice to meet you virtually<br>
May I know that do you have any plan to do it in your side?<br>
<br>
Thanks.<br>
<span class="im HOEnZb">--<br>
Open Networking Solution Engineer<br>
Open Networking Business Unit<br>
Edgecore Networks Corporation<br>
<br>
Mail: <a href="mailto:phil_huang@edge-core.com">phil_huang@edge-core.com</a><br>
Tel: <a href="tel:%2B886-3-563-8888%20Ext%3A%203585" value="+88635638888">+886-3-563-8888 Ext: 3585</a><br>
<a href="http://blog.pichuang.com.tw" rel="noreferrer" target="_blank">http://blog.pichuang.com.tw</a><br>
<br>
<br>
</span><div class="HOEnZb"><div class="h5">On 03/05/2017, 02:42, "Donald Sharp" <<a href="mailto:sharpd@cumulusnetworks.com">sharpd@cumulusnetworks.com</a>> wrote:<br>
<br>
Phil -<br>
<br>
I've cc'ed Jason Heller who has been working on a bunch of automation<br>
work with Ansible. I believe Jason might have some ideas for how to<br>
proceed as well as a source to answer questions if you have any.<br>
<br>
thanks!<br>
<br>
donald<br>
<br>
On Tue, May 2, 2017 at 12:12 PM, Phil Huang <<a href="mailto:phil_huang@edge-core.com">phil_huang@edge-core.com</a>> wrote:<br>
> Hi Teams,<br>
><br>
><br>
><br>
> Since Anisble has released version 2.3, the most network vendor implement<br>
> their own Ansible module into their automation solution.<br>
><br>
><br>
><br>
> I am intersting to develop FRRouting Ansible Module into FRRouting GitHub<br>
> Repos.<br>
><br>
><br>
><br>
> Focus two modules:<br>
><br>
> 1. frr_config - Manage FRRouting configuration using CLI<br>
><br>
> 2. frr_command - Run commands on remote devices running FRRouting<br>
><br>
><br>
><br>
> Does anyone have any idea?<br>
><br>
><br>
><br>
> Thanks<br>
><br>
><br>
><br>
><br>
><br>
> --<br>
><br>
> Open Networking Solution Engineer<br>
> Open Networking Business Unit<br>
><br>
> Edgecore Networks Corporation<br>
><br>
><br>
> Mail: <a href="mailto:phil_huang@edge-core.com">phil_huang@edge-core.com</a><br>
> Tel: <a href="tel:%2B886-3-563-8888%20Ext%3A%203585" value="+88635638888">+886-3-563-8888 Ext: 3585</a><br>
><br>
> <a href="http://blog.pichuang.com.tw" rel="noreferrer" target="_blank">http://blog.pichuang.com.tw</a><br>
><br>
><br>
><br>
><br>
> ______________________________<wbr>_________________<br>
> dev mailing list<br>
> <a href="mailto:dev@lists.frrouting.org">dev@lists.frrouting.org</a><br>
> <a href="https://lists.frrouting.org/listinfo/dev" rel="noreferrer" target="_blank">https://lists.frrouting.org/<wbr>listinfo/dev</a><br>
><br>
<br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div style="font-size:small"><font face="verdana, sans-serif">Jason Heller</font></div></div></div><div><div dir="ltr"><div style="font-size:small"><font size="1" style="background-color:rgb(255,255,255)" color="#000000" face="verdana, sans-serif">Consulting Architect | Cumulus Networks | <a href="tel:(650)%20383-6700" value="+16503836700" target="_blank">+1 650.383.6700 x1193</a><br><br>Join Cumulus on Slack: <a href="https://slack.cumulusnetworks.com/" target="_blank">https://slack.cumulusnetworks.com/</a><br>Connect with me @jaheller</font></div></div></div></div></div>
</div>