Commit 2320de66 authored by Stavros Sachtouris's avatar Stavros Sachtouris
Browse files

Merge branch 'hotfix-0.12.1'

parents 81cf516b 39a608ca
CHANGELOG for version 0.12.rc6
CHANGELOG for hotfix version 0.12.1
Add self.poolsize for kamaki.clients.Client
CHANGELOG for version 0.12.rc5
Add ip attach/detach (shortcuts for port create/delete)
CHANGELOG for version 0.12.rc4
Fix syntax errors in network commands
CHANGELOG for version 0.12.rc3
Check clients unittests
CHANGELOG for version 0.12rc3
Correct keys in HTTP bodies on network-related requests
- Various minor typos
- Rename comand group "kamaki project membership" --> "kamaki membership"
- Add docs for astakos-related commands:
user, quota, resources, project, membership
- Correct/simplify network arguments in server create (#4563)
CHANGELOG for version 0.12
Bug Fixes:
-In file list, the path or prefix was converted to boolean value. Fixed.
-Thread options did not work [#4616]
- In file list, the path or prefix was converted to boolean value. Fixed.
- Thread options did not work [#4616]
- Various minor typos
Changes:
1. Make astakosclient a mantatory requirement for kamaki [#4312]
......@@ -35,6 +24,8 @@ Changes:
6. Deprecate (with note) server stats/console/addr (move to server info)
7. A vanilla kamaki call now shows only the available commands instead of
loading a shell [#4612]
8. Add self.poolsize at kamaki.clients.Client
9. Add ip attach/detach (shortcuts for port create/delete)
Features:
......
......@@ -65,9 +65,23 @@ project (Astakos)
modify Modify a project
terminate Terminate a project (special privileges needed)
application Application management commands
membership Project membership management commands
reinstate Reinstate a terminated project (special privileges needed)
membership (Astakos)
--------------------
.. code-block:: text
info Details on a membership
enroll Enroll somebody to a project you manage
join Join a project
list List all memberships
accept Accept a membership for a project you manage
leave Leave a project you have membership to
remove Remove a membership for a project you manage
reject Reject a membership for a project you manage
cancel Cancel your (probably pending) membership to a project
quota (Account/Astakos)
-----------------------
......
......@@ -362,11 +362,11 @@ inject them into each server, with the personality argument
personality.append(dict(
contents=b64encode(f.read()),
path='/root/.ssh/authorized_keys',
owner='root', group='root', mode='0600')
owner='root', group='root', mode=0600)
personality.append(dict(
contents=b64encode('StrictHostKeyChecking no'),
path='/root/.ssh/config',
owner='root', group='root', mode='0600'))
owner='root', group='root', mode=0600))
create_params = [dict(
name='%s%s' % (CLUSTER_PREFIX, i),
......@@ -633,18 +633,18 @@ logging more. We also added some command line interaction candy.
personality.append(dict(
contents=b64encode(f.read()),
path='/root/.ssh/id_rsa',
owner='root', group='root', mode='0600'))
owner='root', group='root', mode=0600))
if pub_keys_path:
with open(abspath(pub_keys_path)) as f:
personality.append(dict(
contents=b64encode(f.read()),
path='/root/.ssh/authorized_keys',
owner='root', group='root', mode='0600'))
owner='root', group='root', mode=0600))
if ssh_keys_path or pub_keys_path:
personality.append(dict(
contents=b64encode('StrictHostKeyChecking no'),
path='/root/.ssh/config',
owner='root', group='root', mode='0600'))
owner='root', group='root', mode=0600))
return personality
def create(self, ssh_k_path='', pub_k_path='', server_log_path=''):
......
......@@ -12,3 +12,4 @@ Examples
examplesdir/imageregister
examplesdir/server
examplesdir/network
examplesdir/astakos
Astakos
=======
`Astakos <http://www.synnefo.org/docs/synnefo/latest/astakos-api-guide.html>`_
is the synnefo implementation of a variant of OpenStack Keystone with custom
extentions. Kamaki offer tools for managing Astakos information.
.. note:: The underlying library that calls the API is part of the synnefo
and it is called 'astakosclient'
User
----
The *authenticate* command will send a token to the server, for authentication.
Be default, the token provided in the cloud configuration (config file) will be
used:
.. code-block:: console
$ kamaki user authenticate
...
endpoints:
SNF:uiURL: https://example.com/ui/
versionId:
region: default
publicURL: https://example.com/admin
endpoints_links:
type: admin
name: cyclades_admin
user:
roles_links:
id: s0m3-u53r-1d
roles:
id: 1
name: default
name: Example User
To authenticate other users, provide their token, as shown bellow:
.. code-block:: console
$ kamaki user add z01db3rgs-u53r-t0k3n
...
endpoints:
SNF:uiURL: https://example.com/ui/
versionId:
region: default
publicURL: https://example.com/admin
endpoints_links:
type: admin
name: cyclades_admin
user:
roles_links:
id: z01db3rgs-u53r-1d
roles:
id: 1
name: default
name: Dr. Harold Zoidberg
$ kamaki user list
s0m5-u53r-1d Example User
z01db3rgs-u53r-1d Dr. Harold Zoidberg
At any time, get the current user's information, or provide a user id for
information on any existing user. In the following example, "Example User" is
the current user, meaning that all kamaki commands will run for him/her.
.. code-block:: console
$ kamaki user info
roles_links:
id: s0m3-u53r-1d
roles:
id: 1
name: default
name: Example User
$ kamaki user info --uuid=z01db3rgs-u53r-1d
roles_links:
id: z01db3rgs-u53r-1d
roles:
id: 1
name: default
name: EDr. Harold Zoidberg
You can switch between authenticated users
.. code-block:: console
$ kamaki user select z01db3rgs-u53r-1d
Are you sure? [y/N]: y
Use the *uuid2name* and *name2uuid* commands to map uuids to usernames and vice
versa.
.. code-block:: console
$ kamaki user uuid2name z01db3rgs-u53r-1d s0m3-u53r-1d
z01db3rgs-u53r-1d: zoidberg@planetexpress.com
s0m3-u53r-1d: someuser@example.com
Quotas and resources
--------------------
Each user is assigned a set of limits on various resources:
.. code-block:: console
$ kamaki quota list
system:
cyclades.disk:
usage: 0B
limit: 100GiB
pending: 0B
cyclades.vm:
usage: 0
limit: 2
pending: 0
pithos.diskspace:
usage: 5.11GiB
limit: 50GiB
pending: 0B
cyclades.ram:
usage: 0B
limit: 8GiB
pending: 0B
cyclades.cpu:
usage: 0
limit: 8
pending: 0
cyclades.network.private:
usage: 0
limit: 5
pending: 0
If the information above is not clear, use *resource list* for descriptions
fetched fresh from the server:
.. code-block:: console
$ kamaki resource list
cyclades.disk:
service: cyclades_compute
description: Virtual machine disk size
unit: bytes
allow_in_projects: True
cyclades.vm:
service: cyclades_compute
description: Number of virtual machines
unit: None
allow_in_projects: True
pithos.diskspace:
service: pithos_object-store
description: Pithos account diskspace
unit: bytes
allow_in_projects: True
cyclades.ram:
service: cyclades_compute
description: Virtual machine memory size
unit: bytes
allow_in_projects: True
cyclades.cpu:
service: cyclades_compute
description: Number of virtual machine processors
unit: None
allow_in_projects: True
cyclades.network.private:
service: cyclades_compute
description: Number of private networks
unit: None
allow_in_projects: True
Projects
--------
If the standard policy of a synnefo deployment does not meet the needs of an
organization, they should make a request for a *synnefo project*.
First, create a file with the project specification. The specification should
be in json format, as described at the
`project API <http://www.synnefo.org/docs/synnefo/latest/project-api-guide.html#create-a-project>`_
(see "Example request").
Let's request a project of 48 CPUs, with an 8 CPU limit per member. Also 200GB
storage space per user, without a project limit.
.. code-block:: console
$ cat > my_project.txt
{
"name": "My example project",
"homepage": "http://www.exampleorganization.org",
"description": "An example testing project",
"comments": "We need more CPUs and more disk space",
"end_date": "2031-02-13",
"resources": {
"cyclades.vm": {
"project_capacity": 48,
"member_capacity": 8
},
"pithos.diskspace": {
"project_capacity": None,
"member_capacity": 53687091200
}
}
}
$ cat my_project.txt | kamaki project create
List all the projects to see if our project is listed
.. code-block:: console
$ kamaki project list
1 newtitle.film.example.com
end_date: 2014-03-31T00:00:00+00:00
description: Our new film project
join_policy: auto
max_members: None
applicant: s0m3-4pp1ic4n7
leave_policy: auto
creation_date: 2013-01-31T09:36:04.061130+00:00
application: 4
state: active
start_date: 2013-01-31T00:00:00+00:00
owner: s0m3-4pp1ic4n7
homepage: http://example.com/film
resources:
29 many.quotas
end_date: 2013-12-12T00:00:00+00:00
description: I need more quotas
join_policy: moderated
max_members: 10
applicant: s0m3-u53r-1d
leave_policy: auto
creation_date: 2013-02-14T09:26:23.034177+00:00
application: 108
state: active
start_date: 2013-02-14T00:00:00+00:00
owner: s0m3-u53r-1d
homepage: http://example.com
resources:
cyclades.disk:
member_capacity: 109951162777600
project_capacity: None
cyclades.vm:
member_capacity: 1000
project_capacity: None
cyclades.cpu:
member_capacity: 2000
project_capacity: None
cyclades.ram:
member_capacity: 4398046511104
project_capacity: None
pithos.diskspace:
member_capacity: 107374182400
project_capacity: None
cyclades.floating_ip:
member_capacity: 1000
project_capacity: None
No, our project is not in the list yet, probably because we wait for (manual)
authorization.
To get information on a project:
.. code-block:: console
$ kamaki project info 29
name: many.quotas
id: 29
end_date: 2013-12-12T00:00:00+00:00
description: I need more quotas
join_policy: moderated
max_members: 10
applicant: s0m3-u53r-1d
leave_policy: auto
creation_date: 2013-02-14T09:26:23.034177+00:00
application: 108
state: active
start_date: 2013-02-14T00:00:00+00:00
owner: s0m3-u53r-1d
homepage: http://example.com
resources:
cyclades.disk:
member_capacity: 109951162777600
project_capacity: None
cyclades.vm:
member_capacity: 1000
project_capacity: None
cyclades.cpu:
member_capacity: 2000
project_capacity: None
cyclades.ram:
member_capacity: 4398046511104
project_capacity: None
pithos.diskspace:
member_capacity: 107374182400
project_capacity: None
cyclades.floating_ip:
member_capacity: 1000
project_capacity: None
Project membership
------------------
Assuming that our project has been approved and assigned the id 42, we can now
see its details and assign users to benefit from it.
.. code-block:: console
$ kamaki project info 42
name: My example project
id: 42
end_date: 2031-02-13T00:00:00+00:00
description: An example testing project
commends: We need more CPUs and more disk space
join_policy: moderated
applicant: s0m3-u53r-1d
leave_policy: auto
creation_date: <NOW>
application: 109
state: active
start_date: <NOW>
owner: s0m3-u53r-1d
homepage: http://example.com
resources:
cyclades.disk:
member_capacity: 107374182400
project_capacity: None
cyclades.vm:
member_capacity: 2
project_capacity: None
cyclades.cpu:
member_capacity: 8
project_capacity: 48
cyclades.ram:
member_capacity: 6442450944
project_capacity: None
pithos.diskspace:
member_capacity: 53687091200
project_capacity: None
cyclades.floating_ip:
member_capacity: 2
project_capacity: None
Great! Now, we should allow some users to benefit from this project:
.. code-block:: console
$ kamaki membership enroll 42 my_favorite@user.example.com
Membership id: 128345
$ kamaki membership enroll 42 that_guy@user.example.com
Membership id: 128346
$ kamaki membership list --with-project-id=42
128345
42 my_favorite@user.example.com OK
238346
42 that_guy@user.example.com OK
We changed our minds: we don't want the last user to be part of the project:
.. code-block:: console
$ kamaki membership remove 238346 "Our cooperation was not productive"
Later, the removed user attempts to apply for our project:
.. code-block:: console
that_guy$ kamaki membership join 42
We may reject his application:
.. code-block:: console
$ kamaki memebrship list
128345
42 my_favorite@user.example.com OK
238347
42 that_guy@user.example.com PENDING
$ kamaki membership reject 238347 "Not in need of a new partner"
or accept:
.. code-block:: console
$ kamaki membership accept 238347
In the later case, the user decided to leave the project:
.. code-block:: console
that_guy$ kamaki membership leave 42
......@@ -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
......
......@@ -38,6 +38,9 @@ user
project
Astakos project API commands
membership
Astakos project membership API commands
quota
Astakos/Account API commands for quotas
......@@ -146,6 +149,19 @@ project
* membership Project membership management commands
* reinstate Reinstate a terminated project (special privileges needed)
membership
**********
* info Details on a membership
* enroll Enroll somebody to a project you manage
* join Join a project
* list List all memberships
* accept Accept a membership for a project you manage
* leave Leave a project you have membership to
* remove Remove a membership for a project you manage
* reject Reject a membership for a project you manage
* cancel Cancel your (probably pending) membership to a project
quota
*****
......
......@@ -41,7 +41,7 @@ from kamaki.cli.history import History
from kamaki.cli.utils import print_dict, red, magenta, yellow
from kamaki.cli.errors import CLIError, CLICmdSpecError
from kamaki.cli import logger
from kamaki.clients.astakos import AstakosClient as AuthCachedClient
from kamaki.clients.astakos import CachedAstakosClient
from kamaki.clients import ClientError
_help = False
......@@ -308,7 +308,7 @@ def init_cached_authenticator(config_argument, cloud, logger):
if auth_base:
auth_base.authenticate(token)
else:
tmp_base = AuthCachedClient(url, token)
tmp_base = CachedAstakosClient(url, token)
from kamaki.cli.commands import _command_init
fake_cmd = _command_init(dict(config=config_argument))
fake_cmd.client = auth_base
......@@ -496,7 +496,7 @@ def is_non_API(parser):
return False
def main(foo):
def main(func):
def wrap():
try:
exe = basename(argv[0])
......@@ -517,7 +517,7 @@ def main(foo):
global _colors
exclude = ['ansicolors'] if not _colors == 'on' else []
suggest_missing(exclude=exclude)
foo(exe, parser)
func(exe, parser)
except CLIError as err:
print_error_message(err)
if _debug:
......