TIMEZONE PST Hatena BRANCH RSSフィード Twitter

2013-12-01 Ansible Quickstart書いた

Ansible Quickstart書いた

12月4日 クラウドマネジメントツール勉強会 第2回(東京都)でAnsibleについて話します。

ということで、Ansible quickstartを書いてみました。

他のひとのネタとかぶらないといいなぁ

2013-11-23

RDO & packstack & VirtualBox でOpenStackを簡単インストール

RDO & packstack & VirtualBoxOpenStackを簡単インストール

とある場所で話すことになったので書いてみた。

おれ、次はちゃんと2週間前くらいから書き始めるんだ...

OpenStack QuickStart - havana

2013-11-07 AnsibleのJUNOS設定モジュール書いてみた(VLAN編)

AnsibleのJUNOS設定モジュール書いてみた(VLAN編)

Ansibleのお勉強のためにJUNOS向けにNETCONFでVLANを作成・削除するモジュールを書いてみた。

動いてるけど、VC環境だとcommit syncするときにタイムアウトするかも。

Ex3300とEx2200で動作確認した。意外にちゃんとうごいて冪等性も担保できてる。

引数

  • state: 作成する時(present),削除する時(absent)
  • node: 操作対象ネットワーク機器のノード名またはIPアドレス
  • port: 操作対象ネットワーク機器がNETCONF用に口をあけているポート(デフォルト:830)
  • user: 操作対象ネットワーク機器のログインアカウント
  • password: 操作対象ネットワーク機器のパスワード
  • vlan_name: VLAN名
  • vlan_id: VLANID
  • vlan_desc: VLANのDescription

テストしてみる

VLANを作成する
$ ~/ansible/hacking/test-module -m ./junos_vlan -a "node='switch00' port=830 user='foo' password='bar' state='present' vlan_name='VLAN3000' vlan_id=3000 vlan_desc='test vlan'"
VLANを削除する

もちろん対象VLANが存在しなければ何もしない。

$ ~/ansible/hacking/test-module -m ./junos_vlan -a "node='switch00' port=830 user='foo' password='bar' state='absent' vlan_name='VLAN3000' vlan_id=3000 vlan_desc='test vlan'"

モジュール

#!/usr/bin/env python
# -*- coding: utf-8 -*-

DOCUMENTATION = '''
---
module: junos_vlan
author: Hideki Saito
short_description: Manage VLAN resources
requirements:
    - ncclient v0.3.2
description:
    - Manage VLAN resources on JUNOS devices.  This module requires the
      ncclient.
      [link]
      http://ncclient.grnet.gr/
options:
    node:
        desctiption
            - the hostname or IP address to connect
        requred: true
    port:
        description
            - the port number to connect
    user:
        description
            - junos user id
        required: true
    password:
        description
            - junos user password
        requre: true
    vlan_name:
        description:
            - name of vlan
        required: false
    vlan_id:
        description:
            - the vlan id
        required: true
    vlan_desc:
        description:
            - a descriptive name for the vlan
        required: false
    state:
        description:
            - describe the desired state of the vlan related to the config
        required: false
        default: 'present'
        choices: [ 'present', 'absent' ]
    logging:
        description:
            - enables or disables the syslog facility for this module
        required: false
        choices: [ 'true', 'false', 'yes', 'no' ]
notes:
    - The ncclient module must be installed.
    - See http://ncclient.grnet.gr/ for details
'''

import json
from jinja2 import Template
from ncclient import manager
from ncclient.operations.errors import TimeoutExpiredError
from xml.etree import ElementTree


create_vlan = """
<config>
  <configuration>
    <vlans>
      <vlan operation="create">
        <name>{{ vlan_name }}</name>
        <description>{{ vlan_desc }}</description>
        <vlan-id>{{ vlan_id }}</vlan-id>
      </vlan>
    </vlans>
  </configuration>
</config>
"""

delete_vlan = """
<config>
  <configuration>
    <vlans>
      <vlan operation="delete">
        <name>{{ vlan_name }}</name>
        <vlan-id>{{ vlan_id }}</vlan-id>
      </vlan>
    </vlans>
  </configuration>
</config>
"""

set_description = """
<config>
  <configuration>
    <vlans>
      <vlan>
        <name>{{ vlan_name }}</name>
        <description>{{ vlan_desc }}</description>
      </vlan>
    </vlans>
  </configuration>
</config>
"""


class JunosVlan(object):
    def __init__(self, module):
        self.module = module
        self.node = module.params['node']
        self.port = module.params['port']
        self.user = module.params['user']
        self.password = module.params['password']
        self.vlan_name = module.params['vlan_name']
        self.vlan_id = module.params['vlan_id']
        self.vlan_desc = module.params['vlan_desc']
        self.state = module.params['state']
        with manager.connect(host=self.node,
                             port=self.port,
                             username=self.user,
                             password=self.password,
                             hostkey_verify=False) as m:
            self.config = m.get_config(source='candidate').data_xml

    def push(self, config):
        try:
            with manager.connect(host=self.node,
                                 port=self.port,
                                 username=self.user,
                                 password=self.password,
                                 unknown_host_cb=_always_unknown_true) as mgr:
                mgr.edit_config(target="candidate",
                                config=config,
                                test_option="test-then-set")
                mgr.commit()
                rc = 0
                out = 'commit succeeded'
                err = ''
        except TimeoutExpiredError as e:
            rc = 1
            out = 'commit failure'
            err = 'operation timeout'
        return (rc, out, err)

    def vlans(self):
        elm = ElementTree.fromstring(self.config)
        elm_vlans = elm.find('.//vlans')
        vlan_info = dict()
        for elm_vlan in elm_vlans.findall('.//vlan'):
            vlan_id = elm_vlan.findtext('.//vlan-id')
            name = elm_vlan.findtext('.//name')
            description = elm_vlan.findtext('.//description')
            vlan_info[name] = dict(vlan_id=vlan_id, description=description)
        return vlan_info.keys()

def _always_unknown_true(host, fingerprint):
    return True


def main():

    module = AnsibleModule(
        argument_spec = dict(
            node=dict(default=None, requred=True, type='str'),
            port=dict(default=830, requred=True, type='int'),
            user=dict(default=None, requred=True, type='str'),
            password=dict(default=None, requred=True, type='str'),
            vlan_name=dict(default=None, required=True, type='str'),
            vlan_id=dict(default=None, type='int'),
            vlan_desc=dict(default=None, type='str'),
            state=dict(default='present',
                       choices=['present', 'absent']),
        ),
        supports_check_mode = True
    )

    obj = JunosVlan(module)
    rc = None
    result = dict()
    changed = False

    if obj.state == 'absent':
        if obj.vlan_name in obj.vlans():
            template = Template(delete_vlan)
            config = template.render(vlan_name=obj.vlan_name,
                                     vlan_id=obj.vlan_id)
            if module.check_mode:
                module.exit_json(changed=True)
            (rc, out, err) = obj.push(config)
            result['results'] = out

    elif obj.state == 'present':
        if obj.vlan_name in obj.vlans():
            template = Template(set_description)
            config = template.render(vlan_name=obj.vlan_name,
                                     vlan_desc=obj.vlan_desc)
        else:
            template = Template(create_vlan)
            config = template.render(vlan_name=obj.vlan_name,
                                     vlan_id=obj.vlan_id,
                                     vlan_desc=obj.vlan_desc)
        if module.check_mode:
            module.exit_json(changed=True)
        (rc, out, err) = obj.push(config)
        result['results'] = out

        if rc is not None and rc != 0:
            module.fail_json(msg=err, rc=rc)

    if rc is None:
        result['changed'] = False
    else:
        result['changed'] = True

    module.exit_json(**result)


# include magic from lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
main()

##
## [EOF]
##

2013-10-03

lsblkコマンドでブロックデバイスリストを取得する

恥ずかしながら、いままでlsblkコマンドの存在を知りませんでした。

RHEL系もあるのかな?

パーティション情報が紐付きリストで表示される

# lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sr0     11:0    1  1024M  0 rom  
vda    253:0    0    30G  0 disk 
├─vda1 253:1    0  28.1G  0 part /
└─vda2 253:2    0   1.9G  0 part [SWAP]
vdb    253:16   0    30G  0 disk 

-iオプション:紐がascii文字のみで構成されるようになる

# lsblk -i
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sr0     11:0    1  1024M  0 rom  
vda    253:0    0    30G  0 disk 
|-vda1 253:1    0  28.1G  0 part /
`-vda2 253:2    0   1.9G  0 part [SWAP]
vdb    253:16   0    30G  0 disk 

-bオプション:サイズがバイト単位で表示される

# lsblk -b
NAME   MAJ:MIN RM        SIZE RO TYPE MOUNTPOINT
sr0     11:0    1  1073741312  0 rom  
vda    253:0    0 32212254720  0 disk 
├─vda1 253:1    0 30198988800  0 part /
└─vda2 253:2    0  2011168768  0 part [SWAP]
vdb    253:16   0 32212254720  0 dis

-fオプション:ファイルシステムを表示してくる

# lsblk -f
NAME   FSTYPE LABEL MOUNTPOINT
sr0                 
vda                 
├─vda1 ext4         /
└─vda2 swap         [SWAP]
vdb                 

-rオプション:カラム調整や紐付けなどの装飾なしで表示される

# lsblk -r
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sr0 11:0 1 1024M 0 rom 
vda 253:0 0 30G 0 disk 
vda1 253:1 0 28.1G 0 part /
vda2 253:2 0 1.9G 0 part [SWAP]
vdb 253:16 0 30G 0 disk

-nオプション:ヘッダ情報の表示を抑止

# lsblk -n
sr0     11:0    1  1024M  0 rom  
vda    253:0    0    30G  0 disk 
├─vda1 253:1    0  28.1G  0 part /
└─vda2 253:2    0   1.9G  0 part [SWAP]
vdb    253:16   0    30G  0 disk 

スクリプトで使うには -nrb あたりが良さそう

# lsblk -nrb
sr0 11:0 1 1073741312 0 rom 
vda 253:0 0 32212254720 0 disk 
vda1 253:1 0 30198988800 0 part /
vda2 253:2 0 2011168768 0 part [SWAP]
vdb 253:16 0 32212254720 0 disk 

オプションもいろいろ

組み合わせればブロックデバイスに関しての処理に必要になる一通りの情報が得られそう。

OPTIONS
       -a, --all
              List all block devices.

       -b, --bytes
              Print the SIZE column in bytes  rather  than  in  human-readable
              format.

       -d, --nodeps
              Don't  print  device  holders  or  slaves.   For  example "lsblk
              --nodeps /dev/sda" prints information about the sda device only.

       -D, --discard
              Print information about the discard (TRIM,  UNMAP)  capabilities
              for each device.

       -e, --exclude list
              Exclude the devices specified by a comma-separated list of major
              device numbers.  Note that RAM disks (major=1) are  excluded  by
              default.

       -f, --fs
              Output info about filesystems.  This option is equivalent to "-o
              NAME,FSTYPE,LABEL,MOUNTPOINT".   The  authoritative  information
              about filesystems and raids is provided by the blkid(8) command.

       -h, --help
              Print a help text and exit.

       -i, --ascii
              Use ASCII characters for tree formatting.

       -m, --perms
              Output  info about device owner, group and mode.  This option is
              equivalent to "-o NAME,SIZE,OWNER,GROUP,MODE".

       -l, --list
              Use the list output format.

       -n, --noheadings
              Do not print a header line.

       -o, --output list
              Specify which output columns to print.  Use --help to get a list
              of all supported columns.

       -P, --pairs
              Use key="value" output format.

       -r, --raw
              Use the raw output format.

       -t, --topology
              Output info about block device topology.  This option is equiva‐
              lent    to     "-o     NAME,ALIGNMENT,MIN-IO,OPT-IO,PHY-SEC,LOG-
              SEC,ROTA,SCHED".

地味だけど便利なコマンドだな。昔からあったっけ?

2013-09-16

独習Linux専科 〜あなたに伝えたい技と知恵と鉄則〜 を読む

献本いただきましたm(__)m

Amazon CAPTCHA

ちょっと前に神保町の居酒屋で一緒に飲みながらUnix Super Text(上/下)のような最初の1冊って最近ないよねって話をしていましたが、さすが中井さん自分で書いちゃった。

コラムの内容にニヤリとしてしまい、コラムをまず全部読みました。ごめん(^^;

そして、本章はいきなり5章から読み始めるというバチあたりな読み方をしてしまいました。ごめん(^^;

最初の一冊はこれを選んで、あとは必要に応じてUNIXプログラミング環境とか詳解UNIXプログラミングとかを明倫館(その筋では有名な神保町の古本屋さん)で買えばいいんじゃないかな。

今はインターネット上に情報が溢れているけど、質の高い入門書が少なくなっているのは不幸なことだと思う。そんな中、この本はすごくいいですよ。

特にコラムがいいw

第1章 はじめてのLinuxサーバ

Linuxの歴史とインストール方法、インストール後のちょっとしたコマンドラインオペレーション

あと妙にマニアックなコラム

第2章 Linuxの基本操作を学ぶ

Linux上で暮らしていくための知識を学ぶ(shellでの暮らしとか)

初心者には大きな壁(たぶん)の正規表現も丁寧に解説されている

さらに妙にマニアックなコラムとTips

第3章 システム管理の基礎知識

Linuxを維持管理するためのアカウントやファイルアクセス権の管理、パッケージ管理・パッケージでインストールしたミドルウェアなどのサービス管理の方法を学ぶ

なぜかここでSLも走るw

本当に妙にマニアックなコラムとTips

第4章 サーバ構築・管理に挑戦

Samba/PostgreSQL/RoRおためし

sudoの仕組みなどもここで。

ぼく、SambaPostgreSQLRoRは、いままでの人生でさっぱり縁がなく知見もなかったのでありがたい:)

第5章 Linuxの動作原理を学ぶ

ぼくはいきなり5章から読みましたw

5章の情報はインターネット上では散見されるけれど、体系立てて書いてある情報は少ない(特に日本語では)ので、とても有用だと思う。ただ、これは絶対に中井さんの趣味だと思うw

---

ということで連休中に読みましたありがとうございます!