blob: 4095c77f081b2cb0af7178eaf7caf9ef9f60b153 [file] [log] [blame]
Matthew Treinish9e26ca82016-02-23 11:43:20 -05001# Copyright 2012 OpenStack Foundation
2# All Rights Reserved.
3#
4# Licensed under the Apache License, Version 2.0 (the "License"); you may
5# not use this file except in compliance with the License. You may obtain
6# a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13# License for the specific language governing permissions and limitations
14# under the License.
15
16import itertools
17import netaddr
18import random
19import string
20import uuid
21
ChangBo Guo(gcb)cd0374a2016-06-29 15:33:56 +080022from debtcollector import removals
Yatin Kumbhareee4924c2016-06-09 15:12:06 +053023from oslo_utils import netutils
Jordan Pittier4408c4a2016-04-29 15:05:09 +020024import six.moves
25
Matthew Treinish9e26ca82016-02-23 11:43:20 -050026
27def rand_uuid():
28 """Generate a random UUID string
29
30 :return: a random UUID (e.g. '1dc12c7d-60eb-4b61-a7a2-17cf210155b6')
31 :rtype: string
32 """
33 return str(uuid.uuid4())
34
35
36def rand_uuid_hex():
37 """Generate a random UUID hex string
38
39 :return: a random UUID (e.g. '0b98cf96d90447bda4b46f31aeb1508c')
40 :rtype: string
41 """
42 return uuid.uuid4().hex
43
44
45def rand_name(name='', prefix=None):
zhufl0892cb22016-05-06 14:46:00 +080046 """Generate a random name that includes a random number
Matthew Treinish9e26ca82016-02-23 11:43:20 -050047
48 :param str name: The name that you want to include
49 :param str prefix: The prefix that you want to include
50 :return: a random name. The format is
guo yunxian1d840a62016-07-19 19:30:23 +080051 '<prefix>-<name>-<random number>'.
52 (e.g. 'prefixfoo-namebar-154876201')
Matthew Treinish9e26ca82016-02-23 11:43:20 -050053 :rtype: string
54 """
55 randbits = str(random.randint(1, 0x7fffffff))
56 rand_name = randbits
57 if name:
58 rand_name = name + '-' + rand_name
59 if prefix:
60 rand_name = prefix + '-' + rand_name
61 return rand_name
62
63
64def rand_password(length=15):
65 """Generate a random password
66
67 :param int length: The length of password that you expect to set
68 (If it's smaller than 3, it's same as 3.)
69 :return: a random password. The format is
70 '<random upper letter>-<random number>-<random special character>
71 -<random ascii letters or digit characters or special symbols>'
72 (e.g. 'G2*ac8&lKFFgh%2')
73 :rtype: string
74 """
75 upper = random.choice(string.ascii_uppercase)
76 ascii_char = string.ascii_letters
77 digits = string.digits
78 digit = random.choice(string.digits)
userca014312016-07-25 16:18:05 +030079 puncs = '~!@#%^&*_=+'
Matthew Treinish9e26ca82016-02-23 11:43:20 -050080 punc = random.choice(puncs)
81 seed = ascii_char + digits + puncs
82 pre = upper + digit + punc
83 password = pre + ''.join(random.choice(seed) for x in range(length - 3))
84 return password
85
86
87def rand_url():
zhufl0892cb22016-05-06 14:46:00 +080088 """Generate a random url that includes a random number
Matthew Treinish9e26ca82016-02-23 11:43:20 -050089
90 :return: a random url. The format is 'https://url-<random number>.com'.
91 (e.g. 'https://url-154876201.com')
92 :rtype: string
93 """
94 randbits = str(random.randint(1, 0x7fffffff))
95 return 'https://url-' + randbits + '.com'
96
97
98def rand_int_id(start=0, end=0x7fffffff):
99 """Generate a random integer value
100
101 :param int start: The value that you expect to start here
102 :param int end: The value that you expect to end here
103 :return: a random integer value
104 :rtype: int
105 """
106 return random.randint(start, end)
107
108
109def rand_mac_address():
110 """Generate an Ethernet MAC address
111
112 :return: an random Ethernet MAC address
113 :rtype: string
114 """
115 # NOTE(vish): We would prefer to use 0xfe here to ensure that linux
116 # bridge mac addresses don't change, but it appears to
117 # conflict with libvirt, so we use the next highest octet
118 # that has the unicast and locally administered bits set
119 # properly: 0xfa.
120 # Discussion: https://bugs.launchpad.net/nova/+bug/921838
121 mac = [0xfa, 0x16, 0x3e,
122 random.randint(0x00, 0xff),
123 random.randint(0x00, 0xff),
124 random.randint(0x00, 0xff)]
125 return ':'.join(["%02x" % x for x in mac])
126
127
Lenny Verkhovsky92b46e32016-03-14 13:14:58 +0200128def rand_infiniband_guid_address():
129 """Generate an Infiniband GUID address
130
131 :return: an random Infiniband GUID address
132 :rtype: string
133 """
134 guid = []
135 for i in range(8):
136 guid.append("%02x" % random.randint(0x00, 0xff))
137 return ':'.join(guid)
138
139
Matthew Treinish9e26ca82016-02-23 11:43:20 -0500140def parse_image_id(image_ref):
141 """Return the image id from a given image ref
142
143 This function just returns the last word of the given image ref string
144 splitting with '/'.
145 :param str image_ref: a string that includes the image id
146 :return: the image id string
147 :rtype: string
148 """
149 return image_ref.rsplit('/')[-1]
150
151
152def arbitrary_string(size=4, base_text=None):
153 """Return size characters from base_text
154
155 This generates a string with an arbitrary number of characters, generated
156 by looping the base_text string. If the size is smaller than the size of
zhangyanxian438824a2016-09-20 09:29:40 +0000157 base_text, returning string is shrunk to the size.
Pablo Sanchezdeabf432016-06-23 09:58:42 +0200158 :param int size: a returning characters size
Matthew Treinish9e26ca82016-02-23 11:43:20 -0500159 :param str base_text: a string you want to repeat
160 :return: size string
161 :rtype: string
162 """
163 if not base_text:
164 base_text = 'test'
165 return ''.join(itertools.islice(itertools.cycle(base_text), size))
166
167
168def random_bytes(size=1024):
169 """Return size randomly selected bytes as a string
170
171 :param int size: a returning bytes size
172 :return: size randomly bytes
173 :rtype: string
174 """
Sirushti Murugesan12dc9732016-07-13 22:49:17 +0530175 return b''.join([six.int2byte(random.randint(0, 255))
Matthew Treinish9e26ca82016-02-23 11:43:20 -0500176 for i in range(size)])
177
178
ChangBo Guo(gcb)cd0374a2016-06-29 15:33:56 +0800179@removals.remove(
180 message="use get_ipv6_addr_by_EUI64 from oslo_utils.netutils",
181 version="Newton",
182 removal_version="Ocata")
Matthew Treinish9e26ca82016-02-23 11:43:20 -0500183def get_ipv6_addr_by_EUI64(cidr, mac):
184 """Generate a IPv6 addr by EUI-64 with CIDR and MAC
185
186 :param str cidr: a IPv6 CIDR
187 :param str mac: a MAC address
188 :return: an IPv6 Address
189 :rtype: netaddr.IPAddress
190 """
191 # Check if the prefix is IPv4 address
Yatin Kumbhareee4924c2016-06-09 15:12:06 +0530192 is_ipv4 = netutils.is_valid_ipv4(cidr)
Matthew Treinish9e26ca82016-02-23 11:43:20 -0500193 if is_ipv4:
194 msg = "Unable to generate IP address by EUI64 for IPv4 prefix"
195 raise TypeError(msg)
196 try:
197 eui64 = int(netaddr.EUI(mac).eui64())
198 prefix = netaddr.IPNetwork(cidr)
199 return netaddr.IPAddress(prefix.first + eui64 ^ (1 << 57))
200 except (ValueError, netaddr.AddrFormatError):
201 raise TypeError('Bad prefix or mac format for generating IPv6 '
202 'address by EUI-64: %(prefix)s, %(mac)s:'
203 % {'prefix': cidr, 'mac': mac})
204 except TypeError:
205 raise TypeError('Bad prefix type for generate IPv6 address by '
206 'EUI-64: %s' % cidr)
Jordan Pittier4408c4a2016-04-29 15:05:09 +0200207
208
209# Courtesy of http://stackoverflow.com/a/312464
210def chunkify(sequence, chunksize):
211 """Yield successive chunks from `sequence`."""
Sirushti Murugesan12dc9732016-07-13 22:49:17 +0530212 for i in range(0, len(sequence), chunksize):
Jordan Pittier4408c4a2016-04-29 15:05:09 +0200213 yield sequence[i:i + chunksize]