/lib/Net/OpenStack/Compute/AuthRole.pm

https://github.com/ironcamel/Net-OpenStack-Compute · Perl · 108 lines · 96 code · 12 blank · 0 comment · 7 complexity · d763dcad6f347a1c1c55c31c50da0eec MD5 · raw file

  1. package Net::OpenStack::Compute::AuthRole;
  2. use Moose::Role;
  3. use JSON qw(from_json to_json);
  4. requires qw(
  5. auth_url
  6. user
  7. password
  8. project_id
  9. region
  10. service_name
  11. is_rax_auth
  12. verify_ssl
  13. _agent
  14. endpoint_type
  15. );
  16. sub get_auth_info {
  17. my ($self) = @_;
  18. my $auth_url = $self->auth_url;
  19. my ($version) = $auth_url =~ /(v\d+\.\d+)$/;
  20. die "Could not determine version from url [$auth_url]" unless $version;
  21. return $self->auth_rax() if $self->is_rax_auth;
  22. return $self->auth_basic() if $version lt 'v2';
  23. return $self->auth_keystone();
  24. }
  25. sub auth_basic {
  26. my ($self) = @_;
  27. my $res = $self->_agent->get($self->auth_url,
  28. x_auth_user => $self->user,
  29. x_auth_key => $self->password,
  30. x_auth_project_id => $self->project_id,
  31. );
  32. die $res->status_line . "\n" . $res->content unless $res->is_success;
  33. return {
  34. base_url => $res->header('x-server-management-url'),
  35. token => $res->header('x-auth-token'),
  36. };
  37. }
  38. sub auth_keystone {
  39. my ($self) = @_;
  40. return $self->_parse_catalog({
  41. auth => {
  42. tenantName => $self->project_id,
  43. passwordCredentials => {
  44. username => $self->user,
  45. password => $self->password,
  46. }
  47. }
  48. });
  49. }
  50. sub auth_rax {
  51. my ($self) = @_;
  52. return $self->_parse_catalog({
  53. auth => {
  54. 'RAX-KSKEY:apiKeyCredentials' => {
  55. apiKey => $self->password,
  56. username => $self->user,
  57. }
  58. }
  59. });
  60. }
  61. sub _parse_catalog {
  62. my ($self, $auth_data) = @_;
  63. my $res = $self->_agent->post($self->auth_url . "/tokens",
  64. content_type => 'application/json', content => to_json($auth_data));
  65. die $res->status_line . "\n" . $res->content unless $res->is_success;
  66. my $data = from_json($res->content);
  67. my $token = $data->{access}{token}{id};
  68. my @catalog = @{ $data->{access}{serviceCatalog} };
  69. @catalog = grep { $_->{type} eq 'compute' } @catalog;
  70. die "No compute catalog found" unless @catalog;
  71. if ($self->service_name) {
  72. @catalog = grep { $_->{name} eq $self->service_name } @catalog;
  73. die "No catalog found named " . $self->service_name unless @catalog;
  74. }
  75. my $catalog = $catalog[0];
  76. my $base_url = $catalog->{endpoints}[0]{$self->endpoint_type};
  77. if ($self->region) {
  78. for my $endpoint (@{ $catalog->{endpoints} }) {
  79. my $region = $endpoint->{region} or next;
  80. if ($region eq $self->region) {
  81. $base_url = $endpoint->{$self->endpoint_type};
  82. last;
  83. }
  84. }
  85. }
  86. return { base_url => $base_url, token => $token };
  87. }
  88. =head1 DESCRIPTION
  89. This role is used by L<Net::OpenStack::Compute> for OpenStack authentication.
  90. It supports the old 1.0 style auth,
  91. L<Keystone|https://github.com/openstack/keystone> auth,
  92. and Rackspace's RAX auth.
  93. =cut
  94. 1;