Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Added new_from_env constructor.

Also Refactored auth logic into a role and converted from Any::Moose to
Moo.
  • Loading branch information...
commit d93f1af1aa2561e31373c20c9a2db7e756460ea3 1 parent 4f0c966
@ironcamel authored
View
5 Changes
@@ -1,5 +1,10 @@
Revision history for Net-OpenStack-Compute
+1.1000 2012-04-12
+ Added new_from_env constructor.
+ Refactored auth logic into a role.
+ Converted to Moo from Any::Moose.
+
1.0900 2012-04-05
Added support for OSCOMPUTE_INSECURE option.
View
22 bin/oscompute
@@ -23,27 +23,11 @@ sub setup {
$c->register(s => \&server, 'alias for server');
$c->register(i => \&image, 'alias for image');
$c->register(f => \&flavor, 'alias for flavor');
- $c->more_help(_parse_pod());
-
- my $msg = "%s env var is missing. Did you forget to source novarc?\n";
- die sprintf($msg, 'NOVA_URL or OS_AUTH_URL')
- unless $ENV{NOVA_URL} || $ENV{OS_AUTH_URL};
- die sprintf($msg, 'NOVA_USERNAME or OS_USERNAME')
- unless $ENV{NOVA_USERNAME} || $ENV{OS_USERNAME};
- die sprintf($msg, 'NOVA_PASSWORD or NOVA_API_KEY or OS_PASSWORD')
- unless $ENV{NOVA_PASSWORD} || $ENV{NOVA_API_KEY} || $ENV{OS_PASSWORD};
+ $c->more_help(_parse_pod());
$c->getopt('verbose|v', 'insecure', 'query|q=s');
- $c->stash->{compute} = Net::OpenStack::Compute->new(
- auth_url => $ENV{NOVA_URL} || $ENV{OS_AUTH_URL},
- user => $ENV{NOVA_USERNAME} || $ENV{OS_USERNAME},
- password => $ENV{NOVA_PASSWORD} || $ENV{NOVA_API_KEY}
- || $ENV{OS_PASSWORD},
- project_id => $ENV{NOVA_PROJECT_ID} || $ENV{OS_TENANT_NAME},
- region => $ENV{NOVA_REGION_NAME} || $ENV{OS_AUTH_REGION},
- service_name => $ENV{NOVA_SERVICE_NAME},
- is_rax_auth => $ENV{NOVA_RAX_AUTH},
- verify_ssl => !($c->options->{insecure} || $ENV{OSCOMPUTE_INSECURE}),
+ $c->stash->{compute} = Net::OpenStack::Compute->new_from_env(
+ $c->options->{insecure} ? (verify_ssl => 0) : ()
);
}
View
4 dist.ini
@@ -4,15 +4,15 @@ license = Perl_5
copyright_holder = Naveed Massjouni
copyright_year = 2011
-version = 1.0900
+version = 1.1000
[Prereqs]
-Any::Moose = 0
App::Rad = 0
App::Rad::Plugin::MoreHelp = 0
HTTP::Request = 0
JSON = 0
LWP = 0
+Moo = 0.009014
Pod::Select = 0
[MetaResources]
View
87 lib/Net/OpenStack/Compute.pm
@@ -1,6 +1,5 @@
package Net::OpenStack::Compute;
-use Any::Moose;
-with 'Net::OpenStack::Compute::AuthRole';
+use Moo;
# VERSION
@@ -8,34 +7,79 @@ use Carp;
use HTTP::Request;
use JSON qw(from_json to_json);
use LWP;
-use Net::OpenStack::Compute::Auth;
-
-has _auth => (
- is => 'rw',
- isa => 'Net::OpenStack::Compute::Auth',
- lazy => 1,
- default => sub {
- my $self = shift;
- return Net::OpenStack::Compute::Auth->new(
- map { $_, $self->$_ } qw(auth_url user password project_id region
- service_name is_rax_auth verify_ssl)
- );
- },
- handles => [qw(base_url token)],
+#use Net::OpenStack::Compute::Auth;
+
+has auth_url => (is => 'rw', required => 1);
+has user => (is => 'ro', required => 1);
+has password => (is => 'ro', required => 1);
+has project_id => (is => 'ro');
+has region => (is => 'ro');
+has service_name => (is => 'ro');
+has is_rax_auth => (is => 'ro');
+has verify_ssl => (is => 'ro', default => ! $ENV{OSCOMPUTE_INSECURE});
+
+has base_url => (
+ is => 'ro',
+ lazy => 1,
+ default => sub { shift->_auth_info->{base_url} },
+);
+has token => (
+ is => 'ro',
+ lazy => 1,
+ default => sub { shift->_auth_info->{token} },
);
+has _auth_info => (is => 'ro', lazy => 1, builder => '_build_auth_info');
-has _ua => (
+has _agent => (
is => 'ro',
lazy => 1,
default => sub {
my $self = shift;
my $agent = LWP::UserAgent->new(
ssl_opts => { verify_hostname => $self->verify_ssl });
- $agent->default_header(x_auth_token => $self->token);
return $agent;
},
);
+with 'Net::OpenStack::Compute::AuthRole';
+
+sub new_from_env {
+ my ($self, %params) = @_;
+ my $msg = "%s env var is required. Did you forget to source novarc?\n";
+ die sprintf($msg, 'NOVA_URL or OS_AUTH_URL')
+ unless $ENV{NOVA_URL} || $ENV{OS_AUTH_URL};
+ die sprintf($msg, 'NOVA_USERNAME or OS_USERNAME')
+ unless $ENV{NOVA_USERNAME} || $ENV{OS_USERNAME};
+ die sprintf($msg, 'NOVA_PASSWORD or NOVA_API_KEY or OS_PASSWORD')
+ unless $ENV{NOVA_PASSWORD} || $ENV{NOVA_API_KEY} || $ENV{OS_PASSWORD};
+ my %env = (
+ auth_url => $ENV{NOVA_URL} || $ENV{OS_AUTH_URL},
+ user => $ENV{NOVA_USERNAME} || $ENV{OS_USERNAME},
+ password => $ENV{NOVA_PASSWORD} || $ENV{NOVA_API_KEY}
+ || $ENV{OS_PASSWORD},
+ project_id => $ENV{NOVA_PROJECT_ID} || $ENV{OS_TENANT_NAME},
+ region => $ENV{NOVA_REGION_NAME} || $ENV{OS_AUTH_REGION},
+ service_name => $ENV{NOVA_SERVICE_NAME},
+ is_rax_auth => $ENV{NOVA_RAX_AUTH},
+ );
+ return Net::OpenStack::Compute->new(%env, %params);
+}
+
+sub BUILD {
+ my ($self) = @_;
+ # Make sure trailing slashes are removed from auth_url
+ my $auth_url = $self->auth_url;
+ $auth_url =~ s|/+$||;
+ $self->auth_url($auth_url);
+}
+
+sub _build_auth_info {
+ my ($self) = @_;
+ my $auth_info = $self->get_auth_info();
+ $self->_agent->default_header(x_auth_token => $auth_info->{token});
+ return $auth_info;
+}
+
sub _get_query {
my %params = @_;
my $q = $params{query} or return '';
@@ -170,12 +214,12 @@ sub _url {
sub _get {
my ($self, $url) = @_;
- return $self->_ua->get($url);
+ return $self->_agent->get($url);
}
sub _post {
my ($self, $url, $data) = @_;
- return $self->_ua->post(
+ return $self->_agent->post(
$self->_url($url),
content_type => 'application/json',
content => to_json($data),
@@ -184,9 +228,8 @@ sub _post {
sub _delete {
my ($self, $url) = @_;
- print "_delete $url\n";
my $req = HTTP::Request->new(DELETE => $url);
- return $self->_ua->request($req);
+ return $self->_agent->request($req);
}
sub _action {
View
145 lib/Net/OpenStack/Compute/Auth.pm
@@ -1,145 +0,0 @@
-package Net::OpenStack::Compute::Auth;
-use Any::Moose;
-with 'Net::OpenStack::Compute::AuthRole';
-
-#use Data::Dumper;
-use JSON qw(from_json to_json);
-use LWP;
-
-has _info => (is => 'ro', lazy => 1, builder => '_build_info');
-
-has base_url => (
- is => 'ro',
- lazy => 1,
- default => sub { shift->_info->{base_url} },
-);
-
-has token => (
- is => 'ro',
- lazy => 1,
- default => sub { shift->_info->{token} },
-);
-
-sub BUILD {
- my ($self) = @_;
- # Make sure trailing slash is removed from auth_url
- my $auth_url = $self->auth_url;
- $auth_url =~ s/\/$//;
- $self->auth_url($auth_url);
-}
-
-sub _build_info {
- my ($self) = @_;
- my $auth_url = $self->auth_url;
- my ($version) = $auth_url =~ /(v\d\.\d)$/;
- die "Could not determine version from url [$auth_url]" unless $version;
- return $self->auth_rax() if $self->is_rax_auth;
- return $self->auth_basic() if $version lt 'v2';
- return $self->auth_keystone();
-}
-
-has _ua => (
- is => 'ro',
- lazy => 1,
- default => sub {
- my $self = shift;
- my $agent = LWP::UserAgent->new(
- ssl_opts => { verify_hostname => $self->verify_ssl });
- return $agent;
- },
-);
-
-sub auth_basic {
- my ($self) = @_;
- my $res = $self->_ua->get($self->auth_url,
- x_auth_user => $self->user,
- x_auth_key => $self->password,
- x_auth_project_id => $self->project_id,
- );
- die $res->status_line . "\n" . $res->content unless $res->is_success;
-
- return {
- base_url => $res->header('x-server-management-url'),
- token => $res->header('x-auth-token'),
- };
-}
-
-sub auth_keystone {
- my ($self) = @_;
- return $self->_parse_catalog({
- auth => {
- tenantName => $self->project_id,
- passwordCredentials => {
- username => $self->user,
- password => $self->password,
- }
- }
- });
-}
-
-sub auth_rax {
- my ($self) = @_;
- return $self->_parse_catalog({
- auth => {
- 'RAX-KSKEY:apiKeyCredentials' => {
- apiKey => $self->password,
- username => $self->user,
- }
- }
- });
-}
-
-sub _parse_catalog {
- my ($self, $auth_data) = @_;
- my $res = $self->_ua->post($self->auth_url . "/tokens",
- content_type => 'application/json', content => to_json($auth_data));
- die $res->status_line . "\n" . $res->content unless $res->is_success;
- my $data = from_json($res->content);
- my $token = $data->{access}{token}{id};
-
- my @catalog = @{ $data->{access}{serviceCatalog} };
- @catalog = grep { $_->{type} eq 'compute' } @catalog;
- die "No compute catalog found" unless @catalog;
- if ($self->service_name) {
- @catalog = grep { $_->{name} eq $self->service_name } @catalog;
- die "No catalog found named " . $self->service_name unless @catalog;
- }
- my $catalog = $catalog[0];
- my $base_url = $catalog->{endpoints}[0]{publicURL};
- if ($self->region) {
- for my $endpoint (@{ $catalog->{endpoints} }) {
- my $region = $endpoint->{region} or next;
- if ($region eq $self->region) {
- $base_url = $endpoint->{publicURL};
- last;
- }
- }
- }
-
- return { base_url => $base_url, token => $token };
-}
-
-=head1 SYNOPSIS
-
- use Net::OpenStack::Compute::Auth;
-
- my $auth = Net::OpenStack::Compute::Auth->new(
- auth_url => $auth_url,
- user => $user,
- password => $key,
- project_id => $project_id,
- region => $region, # Optional
- );
-
- my $token = $auth->token;
- my $base_url = $auth->base_url;
-
-=head1 DESCRIPTION
-
-This class is responsible for authenticating for OpenStack.
-It supports the old style auth and the new
-L<Keystone|https://github.com/openstack/keystone> auth.
-
-=cut
-
-1;
View
114 lib/Net/OpenStack/Compute/AuthRole.pm
@@ -1,13 +1,107 @@
package Net::OpenStack::Compute::AuthRole;
-use Any::Moose 'Role';
-
-has auth_url => (is => 'rw', required => 1);
-has user => (is => 'ro', required => 1);
-has password => (is => 'ro', required => 1);
-has project_id => (is => 'ro');
-has region => (is => 'ro');
-has service_name => (is => 'ro');
-has is_rax_auth => (is => 'ro', isa => 'Bool'); # Rackspace auth
-has verify_ssl => (is => 'ro', isa => 'Bool', default => 1);
+use Moo::Role;
+
+use JSON qw(from_json to_json);
+
+requires qw(
+ auth_url
+ user
+ password
+ project_id
+ region
+ service_name
+ is_rax_auth
+ verify_ssl
+ _agent
+);
+
+sub get_auth_info {
+ my ($self) = @_;
+ my $auth_url = $self->auth_url;
+ my ($version) = $auth_url =~ /(v\d\.\d)$/;
+ die "Could not determine version from url [$auth_url]" unless $version;
+ return $self->auth_rax() if $self->is_rax_auth;
+ return $self->auth_basic() if $version lt 'v2';
+ return $self->auth_keystone();
+}
+
+sub auth_basic {
+ my ($self) = @_;
+ my $res = $self->_agent->get($self->auth_url,
+ x_auth_user => $self->user,
+ x_auth_key => $self->password,
+ x_auth_project_id => $self->project_id,
+ );
+ die $res->status_line . "\n" . $res->content unless $res->is_success;
+
+ return {
+ base_url => $res->header('x-server-management-url'),
+ token => $res->header('x-auth-token'),
+ };
+}
+
+sub auth_keystone {
+ my ($self) = @_;
+ return $self->_parse_catalog({
+ auth => {
+ tenantName => $self->project_id,
+ passwordCredentials => {
+ username => $self->user,
+ password => $self->password,
+ }
+ }
+ });
+}
+
+sub auth_rax {
+ my ($self) = @_;
+ return $self->_parse_catalog({
+ auth => {
+ 'RAX-KSKEY:apiKeyCredentials' => {
+ apiKey => $self->password,
+ username => $self->user,
+ }
+ }
+ });
+}
+
+sub _parse_catalog {
+ my ($self, $auth_data) = @_;
+ my $res = $self->_agent->post($self->auth_url . "/tokens",
+ content_type => 'application/json', content => to_json($auth_data));
+ die $res->status_line . "\n" . $res->content unless $res->is_success;
+ my $data = from_json($res->content);
+ my $token = $data->{access}{token}{id};
+
+ my @catalog = @{ $data->{access}{serviceCatalog} };
+ @catalog = grep { $_->{type} eq 'compute' } @catalog;
+ die "No compute catalog found" unless @catalog;
+ if ($self->service_name) {
+ @catalog = grep { $_->{name} eq $self->service_name } @catalog;
+ die "No catalog found named " . $self->service_name unless @catalog;
+ }
+ my $catalog = $catalog[0];
+ my $base_url = $catalog->{endpoints}[0]{publicURL};
+ if ($self->region) {
+ for my $endpoint (@{ $catalog->{endpoints} }) {
+ my $region = $endpoint->{region} or next;
+ if ($region eq $self->region) {
+ $base_url = $endpoint->{publicURL};
+ last;
+ }
+ }
+ }
+
+ return { base_url => $base_url, token => $token };
+}
+
+=head1 DESCRIPTION
+
+This role is used by L<Net::OpenStack::Compute> for OpenStack authentication.
+It supports the old 1.0 style auth,
+L<Keystone|https://github.com/openstack/keystone> auth,
+and Rackspace's RAX auth.
+
+=cut
1;
Please sign in to comment.
Something went wrong with that request. Please try again.