~rvb/maas/testin-br

« back to all changes in this revision

Viewing changes to etc/maas/templates/commissioning-user-data/snippets/maas_ipmi_autodetect.py

  • Committer: Raphael Badin
  • Date: 2014-02-04 09:29:37 UTC
  • mfrom: (1606.1.280 maas)
  • Revision ID: raphael.badin@canonical.com-20140204092937-4v73lfr3duol6gcw
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
# You should have received a copy of the GNU Affero General Public License
20
20
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
21
21
 
 
22
from __future__ import (
 
23
    absolute_import,
 
24
    print_function,
 
25
    #unicode_literals,
 
26
    )
 
27
 
 
28
str = None
 
29
 
 
30
__metaclass__ = type
 
31
 
 
32
import commands
 
33
import json
22
34
import os
23
 
import commands
24
 
import glob
 
35
import random
25
36
import re
26
37
import string
27
 
import random
28
38
import time
29
 
import json
30
 
 
31
 
def detect_ipmi():
32
 
    # XXX: andreserl 2013-04-09 bug=1064527: Try to detect if node
33
 
    # is a Virtual Machine. If it is, do not try to detect IPMI.
34
 
    with open('/proc/cpuinfo', 'r') as cpuinfo:
35
 
        for line in cpuinfo:
36
 
            if line.startswith('model name') and 'QEMU' in line:
37
 
                return (False, None)
38
 
 
39
 
    (status, output) = commands.getstatusoutput('ipmi-locate')
40
 
    show_re = re.compile('(IPMI\ Version:) (\d\.\d)')
41
 
    res = show_re.search(output)
42
 
    if res == None:
43
 
        found = glob.glob("/dev/ipmi[0-9]")
44
 
        if len(found):
45
 
            return (True, "UNKNOWN: %s" % " ".join(found))
46
 
        return (False, "")
47
 
    return (True, res.group(2))
 
39
 
48
40
 
49
41
def is_ipmi_dhcp():
50
 
    (status, output) = commands.getstatusoutput('bmc-config --checkout --key-pair="Lan_Conf:IP_Address_Source"')
 
42
    status, output = commands.getstatusoutput(
 
43
        'bmc-config --checkout --key-pair="Lan_Conf:IP_Address_Source"')
51
44
    show_re = re.compile('IP_Address_Source\s+Use_DHCP')
52
 
    res = show_re.search(output)
53
 
    if res == None:
54
 
        return False
55
 
    return True
 
45
    return show_re.search(output) is not None
 
46
 
56
47
 
57
48
def set_ipmi_network_source(source):
58
 
    (status, output) = commands.getstatusoutput('bmc-config --commit --key-pair="Lan_Conf:IP_Address_Source=%s"' % source)
 
49
    status, output = commands.getstatusoutput(
 
50
        'bmc-config --commit --key-pair="Lan_Conf:IP_Address_Source=%s"'
 
51
        % source)
 
52
 
59
53
 
60
54
def get_ipmi_ip_address():
61
 
    (status, output) = commands.getstatusoutput('bmc-config --checkout --key-pair="Lan_Conf:IP_Address"')
 
55
    status, output = commands.getstatusoutput(
 
56
        'bmc-config --checkout --key-pair="Lan_Conf:IP_Address"')
62
57
    show_re = re.compile('([0-9]{1,3}[.]?){4}')
63
58
    res = show_re.search(output)
64
59
    return res.group()
65
60
 
 
61
 
66
62
def get_ipmi_user_number(user):
67
63
    for i in range(1, 17):
68
64
        ipmi_user_number = "User%s" % i
69
 
        (status, output) = commands.getstatusoutput('bmc-config --checkout --key-pair="%s:Username"' % ipmi_user_number)
 
65
        status, output = commands.getstatusoutput(
 
66
            'bmc-config --checkout --key-pair="%s:Username"'
 
67
            % ipmi_user_number)
70
68
        if user in output:
71
69
            return ipmi_user_number
72
70
    return None
73
71
 
 
72
 
74
73
def commit_ipmi_user_settings(user, password):
75
74
    ipmi_user_number = get_ipmi_user_number(user)
76
75
    if ipmi_user_number is None:
77
 
        (status, output) = commands.getstatusoutput('bmc-config --commit --key-pair="User10:Username=%s"' % user)
 
76
        status, output = commands.getstatusoutput(
 
77
            'bmc-config --commit --key-pair="User10:Username=%s"' % user)
78
78
        ipmi_user_number = get_ipmi_user_number(user)
79
 
    (status, output) = commands.getstatusoutput('bmc-config --commit --key-pair="%s:Username=%s"' % (ipmi_user_number, user))
80
 
    (status, output) = commands.getstatusoutput('bmc-config --commit --key-pair="%s:Password=%s"' % (ipmi_user_number, password))
81
 
    (status, output) = commands.getstatusoutput('bmc-config --commit --key-pair="%s:Enable_User=Yes"' % ipmi_user_number)
82
 
    (status, output) = commands.getstatusoutput('bmc-config --commit --key-pair="%s:Lan_Enable_IPMI_Msgs=Yes"' % ipmi_user_number)
83
 
    (status, output) = commands.getstatusoutput('bmc-config --commit --key-pair="%s:Lan_Privilege_Limit=Administrator"' % ipmi_user_number)
 
79
    status, output = commands.getstatusoutput(
 
80
        'bmc-config --commit --key-pair="%s:Username=%s"'
 
81
        % (ipmi_user_number, user))
 
82
    status, output = commands.getstatusoutput(
 
83
        'bmc-config --commit --key-pair="%s:Password=%s"'
 
84
        % (ipmi_user_number, password))
 
85
    status, output = commands.getstatusoutput(
 
86
        'bmc-config --commit --key-pair="%s:Enable_User=Yes"'
 
87
        % ipmi_user_number)
 
88
    status, output = commands.getstatusoutput(
 
89
        'bmc-config --commit --key-pair="%s:Lan_Enable_IPMI_Msgs=Yes"'
 
90
        % ipmi_user_number)
 
91
    status, output = commands.getstatusoutput(
 
92
        'bmc-config --commit --key-pair="%s:Lan_Privilege_Limit=Administrator"'
 
93
        % ipmi_user_number)
 
94
 
84
95
 
85
96
def commit_ipmi_settings(config):
86
 
    (status, output) = commands.getstatusoutput('bmc-config --commit --filename %s' % config)
87
 
 
88
 
def get_maas_power_settings(user, password, ipaddress):
89
 
    return "%s,%s,%s" % (user, password, ipaddress)
90
 
 
91
 
def get_maas_power_settings_json(user, password, ipaddress):
92
 
    power_params = {"power_address": ipaddress, "power_pass": password, "power_user": user}
93
 
    return json.dumps(power_params) 
94
 
 
95
 
def generate_random_password(min=8,max=15):
96
 
    length=random.randint(min,max)
97
 
    letters=string.ascii_letters+string.digits
 
97
    status, output = commands.getstatusoutput(
 
98
        'bmc-config --commit --filename %s' % config)
 
99
 
 
100
 
 
101
def get_maas_power_settings(user, password, ipaddress, version):
 
102
    return "%s,%s,%s,%s" % (user, password, ipaddress, version)
 
103
 
 
104
 
 
105
def get_maas_power_settings_json(user, password, ipaddress, version):
 
106
    power_params = {
 
107
        "power_address": ipaddress,
 
108
        "power_pass": password,
 
109
        "power_user": user,
 
110
        "power_driver": version,
 
111
    }
 
112
    return json.dumps(power_params)
 
113
 
 
114
 
 
115
def generate_random_password(min_length=8, max_length=15):
 
116
    length = random.randint(min_length, max_length)
 
117
    letters = string.ascii_letters + string.digits
98
118
    return ''.join([random.choice(letters) for _ in range(length)])
99
119
 
 
120
 
 
121
def get_ipmi_version():
 
122
    (status, output) = commands.getstatusoutput('ipmi-locate')
 
123
    #IPMI Version: 2.0
 
124
    #IPMI locate driver: SMBIOS
 
125
    #IPMI interface: KCS
 
126
    #BMC driver device:
 
127
    #BMC I/O base address: 0xCA2
 
128
    #Register spacing: 1
 
129
    #show_re = re.compile('(IPMI\ Version:) (\d\.\d)')
 
130
    show_re = re.compile(
 
131
        '(IPMI\ Version:) (\d\.\d)(\n)(.*)(\n)(.*)(\n)(.*)(\n)'
 
132
        '(BMC\ I\/O\ base\ address:) (0xCA2)')
 
133
    res = show_re.search(output)
 
134
    if res is None:
 
135
        return
 
136
    return res.group(2)
 
137
 
 
138
 
100
139
def main():
101
 
 
102
140
    import argparse
103
141
 
104
142
    parser = argparse.ArgumentParser(
105
143
        description='send config file to modify IPMI settings with')
106
 
    parser.add_argument("--configdir", metavar="folder",
107
 
        help="specify config file directory", default=None)
108
 
    parser.add_argument("--dhcp-if-static", action="store_true",
109
 
        dest="dhcp", help="set network source to DHCP if Static", default=False)
110
 
    parser.add_argument("--commission-creds", action="store_true",
111
 
        dest="commission_creds", help="Create IPMI temporary credentials", default=False)
 
144
    parser.add_argument(
 
145
        "--configdir", metavar="folder", help="specify config file directory",
 
146
        default=None)
 
147
    parser.add_argument(
 
148
        "--dhcp-if-static", action="store_true", dest="dhcp",
 
149
        help="set network source to DHCP if Static", default=False)
 
150
    parser.add_argument(
 
151
        "--commission-creds", action="store_true", dest="commission_creds",
 
152
        help="Create IPMI temporary credentials", default=False)
112
153
 
113
154
    args = parser.parse_args()
114
155
 
115
 
    # Check whether IPMI exists or not.
116
 
    (status, ipmi_version) = detect_ipmi()
117
 
    if status != True:
118
 
        # if False, then failed to detect ipmi
119
 
        exit(1)
120
 
 
121
156
    # Check whether IPMI is being set to DHCP. If it is not, and
122
157
    # '--dhcp-if-static' has been passed,  Set it to IPMI to DHCP.
123
158
    if not is_ipmi_dhcp() and args.dhcp:
126
161
        time.sleep(120)
127
162
 
128
163
    # create user/pass
129
 
    IPMI_MAAS_USER="maas"
130
 
    IPMI_MAAS_PASSWORD=generate_random_password()
 
164
    IPMI_MAAS_USER = "maas"
 
165
    IPMI_MAAS_PASSWORD = generate_random_password()
131
166
 
132
167
    # Configure IPMI user/password
133
168
    commit_ipmi_user_settings(IPMI_MAAS_USER, IPMI_MAAS_PASSWORD)
152
187
        # has been detected
153
188
        exit(1)
154
189
 
 
190
    IPMI_VERSION = "LAN"
 
191
    if get_ipmi_version() == "2.0":
 
192
        IPMI_VERSION = "LAN_2_0"
155
193
    if args.commission_creds:
156
 
        print get_maas_power_settings_json(IPMI_MAAS_USER, IPMI_MAAS_PASSWORD, IPMI_IP_ADDRESS)
 
194
        print(get_maas_power_settings_json(
 
195
            IPMI_MAAS_USER, IPMI_MAAS_PASSWORD, IPMI_IP_ADDRESS, IPMI_VERSION))
157
196
    else:
158
 
        print get_maas_power_settings(IPMI_MAAS_USER, IPMI_MAAS_PASSWORD, IPMI_IP_ADDRESS)
 
197
        print(get_maas_power_settings(
 
198
            IPMI_MAAS_USER, IPMI_MAAS_PASSWORD, IPMI_IP_ADDRESS, IPMI_VERSION))
159
199
 
160
200
if __name__ == '__main__':
161
201
    main()