Commit 52167529 authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Simplify/correct network args in server create

Refs: #4563

In server create, replace network arguments with only two:

--network=[id=]NETWORK_ID[,[ip=]IP]
--no-network  (flag)

There arguments are mutually exclussive
parent 958c54f1
......@@ -5,7 +5,7 @@ Astakos
is the synnefo implementation of a variant of OpenStack Keystone with custom
extentions. Kamaki offer tools for managing Astakos information.
.. node:: The underlying library that calls the API is part of the synnefo
.. note:: The underlying library that calls the API is part of the synnefo
and it is called 'astakosclient'
User
......
......@@ -47,7 +47,7 @@ List available images
f1r57-1m4g3-1d Debian Base Alpha
53c0nd-1m4g3-1d Beta Debian Base
Let's pick the `C1R128D1drbd` (id: 1) flavor and the `Debian Base Alpha` (id:
Pick the `C1R128D1drbd` (id: 1) flavor and the `Debian Base Alpha` (id:
f1r57-1m4g3-1d) image to create a new virtual server called 'My First Server'
.. code-block:: console
......@@ -101,6 +101,47 @@ Destroy the virtual server (wait is still optional)
<bar showing destruction progress, until 100%>
Server 141 is now in DELETED mode
Create Servers with networks
----------------------------
First, check the available IPs:
.. code-block:: console
$ kamaki ip list
42042
instance_id: 424242
floating_network_id: 1
fixed_ip_address: None
floating_ip_address: 123.456.78.90
port_id: 24024
So, there is an ip (123.456.78.90) on network 1. We can use it:
.. code-block:: console
$ kamaki server create --network=1,123.456.78.90 --name='Extrovert Server' --flavor-id=1 --image-id=f1r57-1m4g3-1d
...
Another case it the connection to a private network (so, no IP):
.. code-block:: console
$ kamaki network list
1 Public network
7 A custom private network
9 Another custom private network
$ kamaki server create --network=7 --name='Introvert Server' --flavor-id=1 --image-id=f1r57-1m4g3-1d
.. note:: Multiple *- -network* args will create a corresponding number of
connections (nics) to the specified networks.
.. note:: Ommiting *- -network* will let the cloud apply the default network
policy. To create a server without any connections (nics), use the
*- -no-network argument*
Inject ssh keys to a debian server
----------------------------------
......@@ -134,7 +175,10 @@ Create a virtual server while injecting current user public key to root account
.. code-block:: console
$ kamaki server create --name='NoPassword Server' --flavor-id=1 --image-id=f1r57-1m4g3-1d -p /home/someuser/.ssh/id_rsa.pub,/root/.ssh/authorized_keys
$ kamaki server create --name='NoPassword Server' --flavor-id=1 --image-id=f1r57-1m4g3-1d \
--network=1,123.456.78.90 \
-p /home/someuser/.ssh/id_rsa.pub,/root/.ssh/authorized_keys
accessIPv4:
accessIPv6:
addresses:
......@@ -159,8 +203,8 @@ Create a virtual server while injecting current user public key to root account
updated: 2013-06-19T12:34:48.512867+00:00
user_id: s0m3-u53r-1d
When the virtual server is ready, get the virtual servers external IP from the
web UI. Let's assume the IP is 123.456.78.90 .
When the server is ready, we can connect through the public network 1 and the
IP 123.456.78.90 :
.. code-block:: console
......
......@@ -375,24 +375,46 @@ class PersonalityArgument(KeyValueArgument):
'%s' % ve])
class NetworkIpArgument(RepeatableArgument):
class NetworkArgument(RepeatableArgument):
"""[id=]NETWORK_ID[,[ip=]IP]"""
@property
def value(self):
return getattr(self, '_value', [])
return getattr(self, '_value', self.default)
@value.setter
def value(self, new_value):
for v in (new_value or []):
net_and_ip = v.split(',')
if len(net_and_ip) < 2:
for v in new_value or []:
part1, sep, part2 = v.partition(',')
netid, ip = '', ''
if part1.startswith('id='):
netid = part1[len('id='):]
elif part1.startswith('ip='):
ip = part1[len('ip='):]
else:
netid = part1
if part2:
if (part2.startswith('id=') and netid) or (
part2.startswith('ip=') and ip):
raise CLIInvalidArgument(
'Invalid network argument %s' % v, details=[
'Valid format: [id=]NETWORK_ID[,[ip=]IP]'])
if part2.startswith('id='):
netid = part2[len('id='):]
elif part2.startswith('ip='):
ip = part2[len('ip='):]
elif netid:
ip = part2
else:
netid = part2
if not netid:
raise CLIInvalidArgument(
'Value "%s" is missing parts' % v,
details=['Correct format: %s NETWORK_ID,IP' % (
self.parsed_name[0])])
self._value = getattr(self, '_value', list())
self._value.append(
dict(uuid=net_and_ip[0], fixed_ip=net_and_ip[1]))
'Invalid network argument %s' % v, details=[
'Valid format: [id=]NETWORK_ID[,[ip=]IP]'])
self._value = getattr(self, '_value', [])
self._value.append(dict(uuid=netid))
if ip:
self._value[-1]['fixed_ip'] = ip
@command(server_cmds)
......@@ -413,25 +435,26 @@ class server_create(_init_cyclades, _optional_json, _server_wait):
'--cluster-size'),
max_threads=IntArgument(
'Max threads in cluster mode (default 1)', '--threads'),
network_id=RepeatableArgument(
'Connect server to network (can be repeated)', '--network'),
network_id_and_ip=NetworkIpArgument(
'Connect server to network w. floating ip ( NETWORK_ID,IP )'
'(can be repeated)',
'--network-with-ip'),
automatic_ip=FlagArgument(
'Automatically assign an IP to the server', '--automatic-ip')
network_configuration=NetworkArgument(
'Connect server to network: [id=]NETWORK_ID[,[ip=]IP] . '
'Use only NETWORK_ID for private networks. . '
'Use NETWORK_ID,[ip=]IP for networks with IP. . '
'Can be repeated, mutually exclussive with --no-network',
'--network'),
no_network=FlagArgument(
'Do not create any network NICs on the server. . '
'Mutually exclusive to --network . '
'If neither --network or --no-network are used, the default '
'network policy is applied. This policy is configured on the '
'cloud and kamaki is oblivious to it',
'--no-network')
)
required = ('server_name', 'flavor_id', 'image_id')
@errors.cyclades.cluster_size
def _create_cluster(self, prefix, flavor_id, image_id, size):
if self['automatic_ip']:
networks = []
else:
networks = [dict(uuid=netid) for netid in (
self['network_id'] or [])] + (self['network_id_and_ip'] or [])
networks = networks or None
networks = self['network_configuration'] or (
None if self['no_network'] else [])
servers = [dict(
name='%s%s' % (prefix, i if size > 1 else ''),
flavor_id=flavor_id,
......@@ -483,14 +506,12 @@ class server_create(_init_cyclades, _optional_json, _server_wait):
def main(self):
super(self.__class__, self)._run()
if self['automatic_ip'] and (
self['network_id'] or self['network_id_and_ip']):
raise CLIInvalidArgument('Invalid argument combination', details=[
'Argument %s should not be combined with other' % (
self.arguments['automatic_ip'].lvalue),
'network-related arguments i.e., %s or %s' % (
self.arguments['network_id'].lvalue,
self.arguments['network_id_and_ip'].lvalue)])
if self['no_network'] and self['network']:
raise CLIInvalidArgument(
'Invalid argument compination', importance=2, details=[
'Arguments %s and %s are mutually exclusive' % (
self.arguments['no_network'].lvalue,
self.arguments['network'].lvalue)])
self._run(
name=self['server_name'],
flavor_id=self['flavor_id'],
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment