package Net::Kubernetes;
# ABSTRACT: An object oriented interface to the REST API's provided by kubernetes
$Net::Kubernetes::VERSION = '1.03';
use Moose;
require Net::Kubernetes::Namespace;
require LWP::UserAgent;
require HTTP::Request;
require URI;;
require Throwable::Error;
use MIME::Base64;
require Net::Kubernetes::Exception;
with 'Net::Kubernetes::Role::APIAccess';
with 'Net::Kubernetes::Role::ResourceLister';
with 'Net::Kubernetes::Role::ResourceFetcher';
has 'default_namespace' => (
is => 'rw',
isa => 'Net::Kubernetes::Namespace',
required => 0,
lazy => 1,
handles => [qw(get_pod get_rc get_replication_controller get_secret get_service create create_from_file build_secret)],
builder => '_get_default_namespace',
);
sub get_namespace {
my($self, $namespace) = @_;
if (! defined $namespace || ! length $namespace) {
Throwable::Error->throw(message=>'$namespace cannot be null');
}
my $res = $self->ua->request($self->create_request(GET => $self->path.'/namespaces/'.$namespace));
if ($res->is_success) {
my $ns = $self->json->decode($res->content);
my(%create_args) = (url => $self->url, base_path=>$ns->{metadata}{selfLink}, api_version=>$self->api_version, namespace=> $namespace, _namespace_data=>$ns);
$create_args{username} = $self->username if(defined $self->username);
$create_args{password} = $self->password if(defined $self->password);
$create_args{ssl_cert_file} = $self->ssl_cert_file if(defined $self->ssl_cert_file);
$create_args{ssl_key_file} = $self->ssl_key_file if(defined $self->ssl_key_file);
$create_args{ssl_ca_file} = $self->ssl_ca_file if(defined $self->ssl_ca_file);
return Net::Kubernetes::Namespace->new(%create_args);
}else{
Net::Kubernetes::Exception->throw(code=>$res->code, message=>"Error getting namespace $namespace:\n".$res->message);
}
}
sub list_nodes {
my $self = shift;
my(%options);
if (ref($_[0])) {
%options = %{ $_[0] };
}else{
%options = @_;
}
my $uri = URI->new($self->path.'/nodes');
my(%form) = ();
$form{labelSelector}=$self->_build_selector_from_hash($options{labels}) if (exists $options{labels});
$form{fieldSelector}=$self->_build_selector_from_hash($options{fields}) if (exists $options{fields});
$uri->query_form(%form);
my $res = $self->ua->request($self->create_request(GET => $uri));
if ($res->is_success) {
my $node_list = $self->json->decode($res->content);
my(@nodes)=();
foreach my $node (@{ $node_list->{items}}){
$node->{apiVersion} = $node_list->{apiVersion};
push @nodes, $self->create_resource_object($node, 'Node');
}
return wantarray ? @nodes : \@nodes;
}else{
Net::Kubernetes::Exception->throw(code=>$res->code, message=>$res->message);
}
}
sub get_node {
my($self, $name) = @_;
Net::Kubernetes::Exception->throw(message=>"Missing required parameter 'name'") if(! defined $name || ! length $name);
return $self->get_resource_by_name($name, 'nodes');
}
sub list_service_accounts {
my $self = shift;
my(%options);
if (ref($_[0])) {
%options = %{ $_[0] };
}else{
%options = @_;
}
my $uri = URI->new($self->path.'/serviceaccounts');
my(%form) = ();
$form{labelSelector}=$self->_build_selector_from_hash($options{labels}) if (exists $options{labels});
$form{fieldSelector}=$self->_build_selector_from_hash($options{fields}) if (exists $options{fields});
$uri->query_form(%form);
my $res = $self->ua->request($self->create_request(GET => $uri));
if ($res->is_success) {
my $sa_list = $self->json->decode($res->content);
my(@saccs)=();
foreach my $sacc (@{ $sa_list->{items}}){
$sacc->{apiVersion} = $sa_list->{apiVersion};
push @saccs, $self->create_resource_object($sacc, 'ServiceAccount');
}
return wantarray ? @saccs : \@saccs;
}else{
Net::Kubernetes::Exception->throw(code=>$res->code, message=>$res->message);
}
}
sub _get_default_namespace {
my($self) = @_;
return $self->get_namespace('default');
}
# SEEALSO: Net::Kubernetes::Namespace, Net::Kubernetes::Resource
return 42;
__END__
=pod
=encoding UTF-8
=head1 NAME
Net::Kubernetes - An object oriented interface to the REST API's provided by kubernetes
=head1 VERSION
version 1.03
=head1 SYNOPSIS
my $kube = Net::Kubernetes->new(url=>'http://127.0.0.1:8080', username=>'dave', password=>'davespassword');
my $pod_list = $kube->list_pods();
my $nginx_pod = $kube->create_from_file('kubernetes/examples/pod.yaml');
my $ns = $kube->get_namespace('default');
my $services = $ns->list_services;
my $pod = $ns->get_pod('my-pod');
$pod->delete;
my $other_pod = $ns->create_from_file('./my-pod.yaml');
=head1 METHODS
=head2 new - Create a new $kube object
All parameters are optional and have some basic default values (where appropriate).
=over 1
=item url ['http://localhost:8080']
The base url for the kubernetes. This should include the protocal (http or https) but not "/api/v1beta3" (see base_path).
=item base_path ['/api/v1beta3']
The entry point for api calls, this may be used to set the api version with which to interact.
=item username
Username to use with basic authentication. If either username or password are not provided, basic authentication will not
be used.
=item password
Password to use with basic authentication. If either username or password are not provided, basic authentication will not
be used.
=item token
An authentication token to be used to access the apiserver. This may be provided as a plain string, a path to a file
from which to read the token (like /var/run/secrets/kubernetes.io/serviceaccount/token from within a pod), or a reference
to a file handle (from which to read the token).
=item ssl_cert_file, ssl_key_file, ssl_ca_file
This there options passed into new will cause Net::Kubernetes in inlcude SSL client certs to requests to the kuberernetes
API server for authentication. There are basically just a passthrough to the underlying LWP::UserAgent used to handle the
api requests.
=back
=head2 get_namespace("myNamespace");
This method returns a "Namespace" object on which many methods can be called implicitly
limited to the specified namespace.
=head2 get_pod('my-pod-name')
Delegates automatically to L<Net::Kubernetes::Namespace> via $self->get_namespace('default')
=head2 get_repllcation_controller('my-rc-name') (aliased as $ns->get_rc('my-rc-name'))
Delegates automatically to L<Net::Kubernetes::Namespace> via $self->get_namespace('default')
=head2 get_service('my-servce-name')
Delegates automatically to L<Net::Kubernetes::Namespace> via $self->get_namespace('default')
=head2 get_secret('my-secret-name')
Delegates automatically to L<Net::Kubernetes::Namespace> via $self->get_namespace('default')
=head2 list_nodes([label=>{label=>value}], [fields=>{field=>value}])
returns a list of L<Net::Kubernetes::Resource::Node>s
=head2 list_service_accounts([label=>{label=>value}], [fields=>{field=>value}])
returns a list of L<Net::Kubernetes::Resource::Service>s
=begin html
<h2>Build Status</h2>
<img src="https://travis-ci.org/perljedi/net-kubernetes.svg?branch=release-0.21" />
=end html
=head1 AUTHOR
Dave Mueller <[email protected]>
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2015 by Dave Mueller.
This is free software, licensed under:
The MIT (X11) License
=head1 SEE ALSO
Please see those modules/websites for more information related to this module.
=over 4
=item *
L<Net::Kubernetes::Namespace|Net::Kubernetes::Namespace>
=item *
L<Net::Kubernetes::Resource|Net::Kubernetes::Resource>
=back
=head1 CONSUMES
=over 4
=item * L<Net::Kubernetes::Role::APIAccess>
=item * L<Net::Kubernetes::Role::ResourceFactory>
=item * L<Net::Kubernetes::Role::ResourceFetcher>
=item * L<Net::Kubernetes::Role::ResourceLister>
=back
=head1 CONTRIBUTORS
=for stopwords Christopher Pruden Dave Mueller Kevin Johnson
=over 4
=item *
Christopher Pruden <[email protected]>
=item *
Dave <[email protected]>
=item *
Dave Mueller <[email protected]>
=item *
Kevin Johnson <[email protected]>
=back
=cut