Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 1 | # 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 | |
| 16 | import itertools |
Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 17 | import random |
| 18 | import string |
| 19 | import uuid |
| 20 | |
ChangBo Guo(gcb) | cd0374a | 2016-06-29 15:33:56 +0800 | [diff] [blame] | 21 | from debtcollector import removals |
Masayuki Igawa | 134d9f7 | 2017-02-10 18:05:26 +0900 | [diff] [blame] | 22 | import netaddr |
Yatin Kumbhare | ee4924c | 2016-06-09 15:12:06 +0530 | [diff] [blame] | 23 | from oslo_utils import netutils |
janonymous | 69413b9 | 2016-12-06 13:34:19 +0530 | [diff] [blame] | 24 | from oslo_utils import uuidutils |
Jordan Pittier | 4408c4a | 2016-04-29 15:05:09 +0200 | [diff] [blame] | 25 | import six.moves |
| 26 | |
Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 27 | |
| 28 | def rand_uuid(): |
| 29 | """Generate a random UUID string |
| 30 | |
| 31 | :return: a random UUID (e.g. '1dc12c7d-60eb-4b61-a7a2-17cf210155b6') |
| 32 | :rtype: string |
| 33 | """ |
janonymous | 69413b9 | 2016-12-06 13:34:19 +0530 | [diff] [blame] | 34 | return uuidutils.generate_uuid() |
Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 35 | |
| 36 | |
| 37 | def rand_uuid_hex(): |
| 38 | """Generate a random UUID hex string |
| 39 | |
| 40 | :return: a random UUID (e.g. '0b98cf96d90447bda4b46f31aeb1508c') |
| 41 | :rtype: string |
| 42 | """ |
| 43 | return uuid.uuid4().hex |
| 44 | |
| 45 | |
Ken'ichi Ohmichi | 11cf2c5 | 2017-02-28 14:50:44 -0800 | [diff] [blame] | 46 | def rand_name(name='', prefix='tempest'): |
zhufl | 0892cb2 | 2016-05-06 14:46:00 +0800 | [diff] [blame] | 47 | """Generate a random name that includes a random number |
Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 48 | |
| 49 | :param str name: The name that you want to include |
| 50 | :param str prefix: The prefix that you want to include |
| 51 | :return: a random name. The format is |
guo yunxian | 1d840a6 | 2016-07-19 19:30:23 +0800 | [diff] [blame] | 52 | '<prefix>-<name>-<random number>'. |
| 53 | (e.g. 'prefixfoo-namebar-154876201') |
Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 54 | :rtype: string |
| 55 | """ |
| 56 | randbits = str(random.randint(1, 0x7fffffff)) |
| 57 | rand_name = randbits |
| 58 | if name: |
| 59 | rand_name = name + '-' + rand_name |
| 60 | if prefix: |
| 61 | rand_name = prefix + '-' + rand_name |
| 62 | return rand_name |
| 63 | |
| 64 | |
| 65 | def rand_password(length=15): |
| 66 | """Generate a random password |
| 67 | |
| 68 | :param int length: The length of password that you expect to set |
| 69 | (If it's smaller than 3, it's same as 3.) |
| 70 | :return: a random password. The format is |
| 71 | '<random upper letter>-<random number>-<random special character> |
| 72 | -<random ascii letters or digit characters or special symbols>' |
| 73 | (e.g. 'G2*ac8&lKFFgh%2') |
| 74 | :rtype: string |
| 75 | """ |
| 76 | upper = random.choice(string.ascii_uppercase) |
| 77 | ascii_char = string.ascii_letters |
| 78 | digits = string.digits |
| 79 | digit = random.choice(string.digits) |
user | ca01431 | 2016-07-25 16:18:05 +0300 | [diff] [blame] | 80 | puncs = '~!@#%^&*_=+' |
Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 81 | punc = random.choice(puncs) |
| 82 | seed = ascii_char + digits + puncs |
| 83 | pre = upper + digit + punc |
| 84 | password = pre + ''.join(random.choice(seed) for x in range(length - 3)) |
| 85 | return password |
| 86 | |
| 87 | |
| 88 | def rand_url(): |
zhufl | 0892cb2 | 2016-05-06 14:46:00 +0800 | [diff] [blame] | 89 | """Generate a random url that includes a random number |
Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 90 | |
| 91 | :return: a random url. The format is 'https://url-<random number>.com'. |
| 92 | (e.g. 'https://url-154876201.com') |
| 93 | :rtype: string |
| 94 | """ |
| 95 | randbits = str(random.randint(1, 0x7fffffff)) |
| 96 | return 'https://url-' + randbits + '.com' |
| 97 | |
| 98 | |
| 99 | def rand_int_id(start=0, end=0x7fffffff): |
| 100 | """Generate a random integer value |
| 101 | |
| 102 | :param int start: The value that you expect to start here |
| 103 | :param int end: The value that you expect to end here |
| 104 | :return: a random integer value |
| 105 | :rtype: int |
| 106 | """ |
| 107 | return random.randint(start, end) |
| 108 | |
| 109 | |
| 110 | def rand_mac_address(): |
| 111 | """Generate an Ethernet MAC address |
| 112 | |
| 113 | :return: an random Ethernet MAC address |
| 114 | :rtype: string |
| 115 | """ |
| 116 | # NOTE(vish): We would prefer to use 0xfe here to ensure that linux |
| 117 | # bridge mac addresses don't change, but it appears to |
| 118 | # conflict with libvirt, so we use the next highest octet |
| 119 | # that has the unicast and locally administered bits set |
| 120 | # properly: 0xfa. |
| 121 | # Discussion: https://bugs.launchpad.net/nova/+bug/921838 |
| 122 | mac = [0xfa, 0x16, 0x3e, |
| 123 | random.randint(0x00, 0xff), |
| 124 | random.randint(0x00, 0xff), |
| 125 | random.randint(0x00, 0xff)] |
| 126 | return ':'.join(["%02x" % x for x in mac]) |
| 127 | |
| 128 | |
Lenny Verkhovsky | 92b46e3 | 2016-03-14 13:14:58 +0200 | [diff] [blame] | 129 | def rand_infiniband_guid_address(): |
| 130 | """Generate an Infiniband GUID address |
| 131 | |
| 132 | :return: an random Infiniband GUID address |
| 133 | :rtype: string |
| 134 | """ |
| 135 | guid = [] |
| 136 | for i in range(8): |
| 137 | guid.append("%02x" % random.randint(0x00, 0xff)) |
| 138 | return ':'.join(guid) |
| 139 | |
| 140 | |
Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 141 | def parse_image_id(image_ref): |
| 142 | """Return the image id from a given image ref |
| 143 | |
| 144 | This function just returns the last word of the given image ref string |
| 145 | splitting with '/'. |
| 146 | :param str image_ref: a string that includes the image id |
| 147 | :return: the image id string |
| 148 | :rtype: string |
| 149 | """ |
| 150 | return image_ref.rsplit('/')[-1] |
| 151 | |
| 152 | |
| 153 | def arbitrary_string(size=4, base_text=None): |
| 154 | """Return size characters from base_text |
| 155 | |
| 156 | This generates a string with an arbitrary number of characters, generated |
| 157 | by looping the base_text string. If the size is smaller than the size of |
zhangyanxian | 438824a | 2016-09-20 09:29:40 +0000 | [diff] [blame] | 158 | base_text, returning string is shrunk to the size. |
Pablo Sanchez | deabf43 | 2016-06-23 09:58:42 +0200 | [diff] [blame] | 159 | :param int size: a returning characters size |
Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 160 | :param str base_text: a string you want to repeat |
| 161 | :return: size string |
| 162 | :rtype: string |
| 163 | """ |
| 164 | if not base_text: |
| 165 | base_text = 'test' |
| 166 | return ''.join(itertools.islice(itertools.cycle(base_text), size)) |
| 167 | |
| 168 | |
| 169 | def random_bytes(size=1024): |
| 170 | """Return size randomly selected bytes as a string |
| 171 | |
| 172 | :param int size: a returning bytes size |
| 173 | :return: size randomly bytes |
| 174 | :rtype: string |
| 175 | """ |
Sirushti Murugesan | 12dc973 | 2016-07-13 22:49:17 +0530 | [diff] [blame] | 176 | return b''.join([six.int2byte(random.randint(0, 255)) |
Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 177 | for i in range(size)]) |
| 178 | |
| 179 | |
ChangBo Guo(gcb) | cd0374a | 2016-06-29 15:33:56 +0800 | [diff] [blame] | 180 | @removals.remove( |
| 181 | message="use get_ipv6_addr_by_EUI64 from oslo_utils.netutils", |
| 182 | version="Newton", |
| 183 | removal_version="Ocata") |
Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 184 | def get_ipv6_addr_by_EUI64(cidr, mac): |
| 185 | """Generate a IPv6 addr by EUI-64 with CIDR and MAC |
| 186 | |
| 187 | :param str cidr: a IPv6 CIDR |
| 188 | :param str mac: a MAC address |
| 189 | :return: an IPv6 Address |
| 190 | :rtype: netaddr.IPAddress |
| 191 | """ |
| 192 | # Check if the prefix is IPv4 address |
Yatin Kumbhare | ee4924c | 2016-06-09 15:12:06 +0530 | [diff] [blame] | 193 | is_ipv4 = netutils.is_valid_ipv4(cidr) |
Matthew Treinish | 9e26ca8 | 2016-02-23 11:43:20 -0500 | [diff] [blame] | 194 | if is_ipv4: |
| 195 | msg = "Unable to generate IP address by EUI64 for IPv4 prefix" |
| 196 | raise TypeError(msg) |
| 197 | try: |
| 198 | eui64 = int(netaddr.EUI(mac).eui64()) |
| 199 | prefix = netaddr.IPNetwork(cidr) |
| 200 | return netaddr.IPAddress(prefix.first + eui64 ^ (1 << 57)) |
| 201 | except (ValueError, netaddr.AddrFormatError): |
| 202 | raise TypeError('Bad prefix or mac format for generating IPv6 ' |
| 203 | 'address by EUI-64: %(prefix)s, %(mac)s:' |
| 204 | % {'prefix': cidr, 'mac': mac}) |
| 205 | except TypeError: |
| 206 | raise TypeError('Bad prefix type for generate IPv6 address by ' |
| 207 | 'EUI-64: %s' % cidr) |
Jordan Pittier | 4408c4a | 2016-04-29 15:05:09 +0200 | [diff] [blame] | 208 | |
| 209 | |
| 210 | # Courtesy of http://stackoverflow.com/a/312464 |
| 211 | def chunkify(sequence, chunksize): |
| 212 | """Yield successive chunks from `sequence`.""" |
Sirushti Murugesan | 12dc973 | 2016-07-13 22:49:17 +0530 | [diff] [blame] | 213 | for i in range(0, len(sequence), chunksize): |
Jordan Pittier | 4408c4a | 2016-04-29 15:05:09 +0200 | [diff] [blame] | 214 | yield sequence[i:i + chunksize] |