Group
Extension

Net-OpenStack-Compute/lib/Net/OpenStack/Compute/Auth.pm

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 };
}


1;

__END__
=pod

=head1 NAME

Net::OpenStack::Compute::Auth

=head1 VERSION

version 1.0800

=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.

=head1 AUTHOR

Naveed Massjouni <naveedm9@gmail.com>

=head1 COPYRIGHT AND LICENSE

This software is copyright (c) 2011 by Naveed Massjouni.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.

=cut



Powered by Groonga
Maintained by Kenichi Ishigaki <ishigaki@cpan.org>. If you find anything, submit it on GitHub.