Chef-REST-Client

 view release on metacpan or  search on metacpan

LICENSE  view on Meta::CPAN

This software is copyright (c) 2014 by Bhavin Patel.

This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself and The 
Artistic License 2.0 (GPL compatible)

MANIFEST  view on Meta::CPAN

LICENSE
lib/Chef/Header.pm
lib/Chef/REST/Client.pm
lib/Chef/REST/Client/roles.pm
lib/Chef/REST/Client/clients.pm
lib/Chef/REST/Client/cookbook_version.pm
lib/Chef/REST/Client/sandboxes.pm
lib/Chef/REST/Client/cookbooks.pm
lib/Chef/REST/Client/node.pm
lib/Chef/REST/Client/search.pm
lib/Chef/REST/Client/attributes.pm
lib/Chef/REST/Client/attribute.pm
lib/Chef/REST/Client/runlist.pm
lib/Chef/REST/Client/environment.pm
lib/Chef/REST/Client/databag.pm
lib/Chef/REST/Client/envrunlist.pm
lib/Chef/REST/Client/EndPoints.pm
lib/Chef/REST/Client/environments.pm
lib/Chef/REST/Client/recipe.pm
lib/Chef/REST/Client/cookbook.pm
lib/Chef/REST/Client/data.pm
lib/Chef/REST/Client/cookbook_versions.pm
lib/Chef/REST/Client/nodes.pm
lib/Chef/REST/Client/role.pm
lib/Chef/REST/Client/principals.pm
lib/Chef/Encoder.pm
lib/Chef/REST.pm
lib/Chef.pm
MANIFEST
README.md
Makefile.PL
t/Chef/REST.t
t/Chef/Header.t
t/Chef/REST/sandboxes.t
t/Chef/REST/principals.t
t/Chef/REST/clients.t
t/Chef/REST/nodes.t
t/Chef/REST/environments.t
t/Chef/REST/EndPoints.t
t/Chef/REST/search.t
t/Chef/REST/roles.t
t/Chef/REST/data.t
t/Chef/REST/client.t
t/Chef/REST/cookbooks.t
t/Chef/base64_60.t
t/Chef/Encoder.t
t/RequiredModules.t
META.yml                                 Module YAML meta-data (added by MakeMaker)
META.json                                Module JSON meta-data (added by MakeMaker)

META.json  view on Meta::CPAN

{
   "abstract" : "Interface for Chef Clients REST API",
   "author" : [
      "Bhavin Patel <bpatel10@nyit.edu>"
   ],
   "dynamic_config" : 1,
   "generated_by" : "ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921",
   "license" : [
      "artistic_2"
   ],
   "meta-spec" : {
      "url" : "http://search.cpan.org/perldoc?CPAN::Meta::Spec",
      "version" : "2"
   },
   "name" : "Chef-REST-Client",
   "no_index" : {
      "directory" : [
         "t",
         "inc"
      ]
   },
   "prereqs" : {
      "build" : {
         "requires" : {
            "English" : "0",
            "Test::More" : "0",
            "utf8" : "0"
         }
      },
      "configure" : {
         "requires" : {
            "ExtUtils::MakeMaker" : "0"
         }
      },
      "runtime" : {
         "requires" : {
            "Crypt::OpenSSL::RSA" : "0",
            "File::Basename" : "0",
            "File::Slurp" : "0",
            "File::Spec::Functions" : "0",
            "LWP::UserAgent" : "0",
            "Module::Load" : "0",
            "Mojo::JSON" : "0",
            "parent" : "0"
         }
      }
   },
   "release_status" : "stable",
   "resources" : {
      "repository" : {
         "url" : "https://github.com/github4bhavin/ChefRESTClient"
      }
   },
   "version" : "1.2"
}

META.yml  view on Meta::CPAN

---
abstract: 'Interface for Chef Clients REST API'
author:
  - 'Bhavin Patel <bpatel10@nyit.edu>'
build_requires:
  English: 0
  Test::More: 0
  utf8: 0
configure_requires:
  ExtUtils::MakeMaker: 0
dynamic_config: 1
generated_by: 'ExtUtils::MakeMaker version 6.66, CPAN::Meta::Converter version 2.120921'
license: artistic_2
meta-spec:
  url: http://module-build.sourceforge.net/META-spec-v1.4.html
  version: 1.4
name: Chef-REST-Client
no_index:
  directory:
    - t
    - inc
requires:
  Crypt::OpenSSL::RSA: 0
  File::Basename: 0
  File::Slurp: 0
  File::Spec::Functions: 0
  LWP::UserAgent: 0
  Module::Load: 0
  Mojo::JSON: 0
  parent: 0
resources:
  repository: https://github.com/github4bhavin/ChefRESTClient
version: 1.2

Makefile.PL  view on Meta::CPAN

use ExtUtils::MakeMaker;

WriteMakefile1(
	NAME         => 'Chef::REST::Client',
	AUTHOR       => 'Bhavin Patel <bpatel10@nyit.edu>',
	VERSION_FROM => 'lib/Chef/REST/Client.pm',
	PREREQ_PM    => {
				          'Mojo::JSON'            => 0,
				          'File::Slurp'           => 0,
				          'Module::Load'          => 0,
				          'LWP::UserAgent'        => 0,
				          'File::Basename'        => 0,
				          'Crypt::OpenSSL::RSA'   => 0,
				          'File::Spec::Functions' => 0,
				          'parent'                => 0,
	                },
   dist         => { 
                       COMPRESS => 'gzip -9f', 
                       SUFFIX   => 'gz'
                   },
   INSTALLDIRS  => 'perl',
   ABSTRACT     => 'Interface for Chef Clients REST API',
   BUILD_REQUIRES 
                => {
                       'English'    => 0,
                       'Test::More' => 0,
                       'utf8'       => 0,
                   },
	LICENSE => 'artistic_2',
	META_MERGE => {
		resources => {
			repository => 'https://github.com/github4bhavin/ChefRESTClient',
		},
	},

   test         => {
                       'RECURSIVE_TEST_FILES' => 1,
                   }
);

sub WriteMakefile1 {  #Compatibility code for old versions of EU::MM. Written by Alexandr Ciornii, version 0.23. Added by eumm-upgrade.
	my %params=@_;
	my $eumm_version=$ExtUtils::MakeMaker::VERSION;
	$eumm_version=eval $eumm_version;
	die "EXTRA_META is deprecated" if exists $params{EXTRA_META};
	die "License not specified" if not exists $params{LICENSE};
	if ($params{AUTHOR} and ref($params{AUTHOR}) eq 'ARRAY' and $eumm_version < 6.5705) {
		$params{META_ADD}->{author}=$params{AUTHOR};
		$params{AUTHOR}=join(', ',@{$params{AUTHOR}});
	}
	if ($params{TEST_REQUIRES} and $eumm_version < 6.64) {
		$params{BUILD_REQUIRES}={ %{$params{BUILD_REQUIRES} || {}} , %{$params{TEST_REQUIRES}} };
		delete $params{TEST_REQUIRES};
	}
	if ($params{BUILD_REQUIRES} and $eumm_version < 6.5503) {
		#EUMM 6.5502 has problems with BUILD_REQUIRES
		$params{PREREQ_PM}={ %{$params{PREREQ_PM} || {}} , %{$params{BUILD_REQUIRES}} };
		delete $params{BUILD_REQUIRES};
	}
	delete $params{CONFIGURE_REQUIRES} if $eumm_version < 6.52;
	delete $params{MIN_PERL_VERSION} if $eumm_version < 6.48;
	delete $params{META_MERGE} if $eumm_version < 6.46;
	delete $params{META_ADD} if $eumm_version < 6.46;
	delete $params{LICENSE} if $eumm_version < 6.31;

	WriteMakefile(%params);
}

README.md  view on Meta::CPAN

# NAME

Chef::REST::Client

# VERSION

1.1

# SYNOPSIS

use Chef::REST::Client;

	my $obj = new Chef::REST::Client
   	       ( 'chef\_client\_name' => $chef\_client\_name )
	$obj->name( $chef\_client\_name );
  	$obj->roles('vagrant')->details;
  	$obj->roles('vagrant','environments')->details
  	$obj->roles->list;
   

  	$obj->search( 'secrets' , {  q => 'id:centrify', rows => 1 } )->details
    

  	$obj->environments(<env_name>,'cookbooks' , <cookbook_name>)->details;

  	$obj->environments(<env_name>,'cookbooks_versions'
                                 ,{ 'method' => 'post'
                                 , 'data' => { 'runlist' => [ 'ms-scribe'] }
                                   }
                      );
 	$obj->roles(<role_name>)->details->override_attributes;
                    

# DESCRIPTION

This is the interface to the Chef server api methods listed on opscode documentation 
[opscode Chef Api](http://docs.opscode.com/api\_chef\_server.html)
currently it provides implementation for only GET methods

# METHODS

## role( $role )

returns new [Chef::REST::Client::role](http://search.cpan.org/perldoc?Chef::REST::Client::role) object
used by other classes

## roles ( @roles )

makes a GET request to the chef server for all the @roles and returns and [Chef::REST::Client::roles](http://search.cpan.org/perldoc?Chef::REST::Client::roles) object.
you can directly get details for all the roles as $obj->role( 'role1', 'role2' )->details;

this inturn will return [Chef::REST::Client::role](http://search.cpan.org/perldoc?Chef::REST::Client::role) 

	/roles

	$obj->roles->list 

	/roles/<role\_name>

	$obj->roles(<role\_name>)->details

	$obj->roles(<role\_name>)->details->run\_list;

	$obj->roles(<role\_name>)->details->override\_attributes;

## runlist ( @$recipes )

returns new [Chef::REST::Client::runlist](http://search.cpan.org/perldoc?Chef::REST::Client::runlist) object. it takes a list of recipies as parameter.
used by other classes

## sandboxes

returns new [Chef::REST::Client::sandboxes](http://search.cpan.org/perldoc?Chef::REST::Client::sandboxes) object. $obj->sandboxes->list;

	/sandboxes

	$obj->sandboxes->list 

	/sandboxes/<id>

	$obj->sandboxes(<id>)->details

## search

returns new [Chef::REST::Client::search](http://search.cpan.org/perldoc?Chef::REST::Client::search) 

	/search

	$obj->search->listen

	/search/<index>

	$obj->search(<index>)->details

	/search/ query id:centrify and get rows 1

	$obj->search( 'secrets' , {  q => 'id:centrify', rows => 1 } )->details

## recipe

returns new [Chef::REST::Client::recipe](http://search.cpan.org/perldoc?Chef::REST::Client::recipe) object. used by other classes

## principals

returns new [Chef::REST::Client::principals](http://search.cpan.org/perldoc?Chef::REST::Client::principals) object. $obj->principals->details;

	/principals

	$obj->principals->list 

	/principals/<name>

	$obj->principals(<name>)->details

## node

returns new [Chef::REST::Client::node](http://search.cpan.org/perldoc?Chef::REST::Client::node) object. $obj->node->details;
used by other classes
 

## nodes

returns new [Chef::REST::Client::nodes](http://search.cpan.org/perldoc?Chef::REST::Client::nodes) object. $obj->nodes->list;

	/nodes

	$obj->nodes->listen

	/nodes/<node\_name>

	$obj->nodes(<node\_name>)->details 

## envrunlist

returns new [Chef::REST::Client::envrunnlist](http://search.cpan.org/perldoc?Chef::REST::Client::envrunnlist) object. used by other classes

## environment

returns new [Chef::REST::Client::environment](http://search.cpan.org/perldoc?Chef::REST::Client::environment) object. used by other classes

## environments

returns new [Chef::REST::Client::environments](http://search.cpan.org/perldoc?Chef::REST::Client::environments) object.

	/environment/<env\_name>

	$obj->environments(<env\_name>)->details;

	/environment/<env\_name>/cookbooks/<cookbook\_name>

	$obj->environments(<env\_name>,'cookbooks' , <cookbook\_name>)->details;

	/environment/<env\_name>/cookbooks

	$obj->environments(<env\_name>,'cookbooks')

	POST /environments/<env\_name>/cookbooks\_versions

	$obj->environments(<env\_name>,'cookbooks\_versions'
        	                     ,{ 'method' => 'post'
                	              , 'data' => { 'runlist' => \[ 'ms-scribe'\] }
                        	      }
                   	);

## databag

returns new [Chef::REST::Client::databag](http://search.cpan.org/perldoc?Chef::REST::Client::databag) object.

## data

returns new [Chef::REST::Client::data](http://search.cpan.org/perldoc?Chef::REST::Client::data) object.

	/data

	$obj->data->list

	/data/<var\_name>

	$obj->data( <var\_name> )->details

## cookbook

returns new [Chef::REST::Client::cookbook](http://search.cpan.org/perldoc?Chef::REST::Client::cookbook) object.

## cookbooks

returns new [Chef::REST::Client::cookbooks](http://search.cpan.org/perldoc?Chef::REST::Client::cookbooks) object.

	/cookbooks

	$obj->cookbooks->list 

	/cookbooks/<cookbook\_name>

	$obj->cookbooks(<cookbook\_name>)->details 

	$obj->cookbooks(<cookbook\_name> , '\_latest' )->details->recipes;

	$obj->cookbooks(<cookbook\_name> , '\_latest' )->details->attributes;

## cookbook\_version

returns new [Chef::REST::Client::cookbook\_version](http://search.cpan.org/perldoc?Chef::REST::Client::cookbook\_version) object.
used by other classes

## cookbook\_versions

returns new [Chef::REST::Client::cookbook\_versions](http://search.cpan.org/perldoc?Chef::REST::Client::cookbook\_versions) object.
collection of [Chef::REST::Client::cookbook\_version](http://search.cpan.org/perldoc?Chef::REST::Client::cookbook\_version)

## clients

returns new [Chef::REST::Client::clients](http://search.cpan.org/perldoc?Chef::REST::Client::clients) object.

	/clients

	$obj->clients->list 

	/clients/<client\_name>/

	$obj->clients(<client\_name>)->details



## attribute

returns new [Chef::REST::Client::attribute](http://search.cpan.org/perldoc?Chef::REST::Client::attribute) object.
used by other classes to structure data

## attributes

returns new [Chef::REST::Client::attributes](http://search.cpan.org/perldoc?Chef::REST::Client::attributes) object.
collection of [Chef::REST::Client::attribute](http://search.cpan.org/perldoc?Chef::REST::Client::attribute)

# KNOWN BUGS

# SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

# COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

lib/Chef.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# Class : Chef                                                       #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef;
$Chef::VERSION = 1.0;

sub new {
  my $class = shift;
  my $param  = {@_};
  my $self   = {};

  bless $self, $class;
  $self->server( $param->{'chef_server'} ) if defined $param->{'chef_server'};
  $self->chef_version( $param->{'chef_version'} ) if defined $param->{'chef_version'};  
  return $self;

  sub server {
    my ($self,$server) = (@_);
       $self->{ 'CHEF_SERVER' } = $server if defined $server;
    return $self->{ 'CHEF_SERVER' };
  }
  sub chef_version {
    my ($self,$chef_version) = (@_);
       $self->{ 'CHEF_VERSION' } = $chef_version if defined $chef_version;
    return $self->{ 'CHEF_VERSION' };
  }
  sub host_port {
    my $self = shift;
    my $server = $self->server;
       $server =~ m/^(http|https):\/\/(.*)(:(\d))?/;
    return "$2";
  }
  sub organization_name {
    my ($self,$organization_name) = (@_);
       $self->{ 'ORGANIZATION_NAME' } = $organization_name if defined $organization_name;
    return $self->{ 'ORGANIZATION_NAME' };
  }
  sub hosted_chef {
    my ($self,$hosted_chef) = (@_);
       $self->{ 'HOSTED_CHEF_' } = $hosted_chef if defined $server;;
    return $self->{ 'HOSTED_CHEF' };
  }
  
  sub private_key {
    my ($self,$private_key) = (@_);
           $self->{ 'CHEF_CLIENT_PRIVATE_KEY' } = $private_key if defined $private_key;
    return $self->{ 'CHEF_CLIENT_PRIVATE_KEY' };
  }
}#nwe

__DATA__

=pod

=head1 NAME 

Chef - Super Class for L<Chef::REST::Client>

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef;

  my $obj = new Chef( 'chef_server'   => 'https://api.opscode.com/organizations/zyx'
                     , 'chef_version' => '11.0.4' );

=head1 DESCRIPTION

This is the Super Class module, Methods listed under this class shouldn't be access directly. 
Inturn these are used internally by other modules eg: L<Chef::REST::Client> 

=head1 METHODS

=head2 Constructor

=head3 Chef( chef_server , chef_version );

returns new Chef object and loads Chef module;

=head3 sever ( [<chef server>] )

sets CHEF_SERVER if the values is passed or returns the initialized value

=head3 chef_version ( [<chef version>] )

sets CHEF_VERSION if passed or returns initialized value

=head3 organization_name( [name] )

set ORGANIZATION_NAME if passed or returns initialized value

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

1;

lib/Chef/Encoder.pm  view on Meta::CPAN

package Chef::Encoder;
$Chef::Encoder::VERSION = 1.1;

=pod

=head1 NAME

Chef::Encoder

=head1 VERSION

1.1

=head1 SYNOPSIS

 use Chef::Encoder;

 my $obj  = new Chef::Encoder
           ( 
             'data'             => $data
           , 'private_key_file' => ../data/private_key.pem
           );
           
    $obj->pki->sign     ( 'data' => $data );
    $obj->sha1->digest  ( 'data' => $data );
    $obj->base64->encode( 'data' => $data );
    $obj->base64->decode( 'data' => $data );
    
=head1 DESCRIPTION

This module imiplements methods that perform the encoding and decoding and signing of the header
once you load this module it will inturn load three classes

=over 

=item * Chef::Encode::pki

=item * Chef::Encode::sha1

=item * Chef::Encode::base64

=back

=begin html

+----------------+
|  Chef::Encode  |        
+---------------------+
|  Chef::Encode::pki  |
+----------------------+
|  Chef::Encode::sha1  |
+------------------------+
|  Chef::Encode::base64  |
+------------------------+

=end html    

=head1 METHODS

=head2 Chef::Encoder( %params )

return new object initialzied as per %params.

=head2 private_key_file 

returns $private_key_file 

=head2 private_key

returns $private_key

=head2 data

returns $data

=cut


my @base;
BEGIN {
use File::Basename qw { dirname };
use File::Spec::Functions qw { splitdir rel2abs };
 @base = ( splitdir ( rel2abs ( dirname(__FILE__) ) ) );
 pop @base; #Chef
 push @INC, '/', @base;
};

sub new {
  my $class = shift;
  my $param = {@_};
  my $self  = {};
  my $_tmp =  pop @base; #lib;  
  bless $self, $class;
    
    $self->{'data'            } = $param->{'data'} if defined $param->{'data'};
    $self->{'private_key_file'} = join '/' , @base , 'data', 'private_key.pem';
    $self->{'private_key_file'} = $param->{'private_key_file'} if defined $param->{'private_key_file'};

    push @base , $_tmp;
     
  return $self;
}

sub private_key_file {
  my $self = shift;
  return $self->{'private_key_file'};
}

sub private_key {
  my $self = shift;
  return $self->{'private_key'};
}

sub execute {
  my ($self , $command) = (@_);
  my $output = undef;
  eval {
  		$output = `$command`;
  		chomp($output);
  };
  return ($@) ? undef : $output;
}

sub data
{ $_[0]->{'data'} = $_[1] if defined $_[1]; return $_[0]->{'data'}; }

=pod

=head2 pki ( %params)

loads L<Chef::Encoder::pki> class and returns new object of class L<Chef::Encoder::pki>
it accepts ( 'private_key_file' => $private_key_file , 'private_key' => $private_key )
if none is provided it will try to use the values initialized from parent class L<Chef::Encoder>

=head3 NAME

Chef::Encoder::pki

=head3 VERSION

1.0

=head3 DESCRIPTION

This class provides siging request as per private key specified.

=head3 METHODS

=head4 B<sign>

returns signed data based on the private_key_file or privete_key

=cut

#----------------------------#
#  class Chef::Encoder::pki  #
#----------------------------#

sub pki {
  my $class = shift;
  my $param = {@_};
  
  package Chef::Encoder::pki;
  use parent qw{ Chef::Encoder };
  use Crypt::OpenSSL::RSA; 
  use File::Slurp;

  my $self = {};
  bless $self, qw { Chef::Encoder::pki };
  
  $self->{'private_key_file'} = (defined($param->{'private_key_file'}))?
                                         $param->{'private_key_file'}  :
                                         $class->private_key_file;
  $self->{'private_key'} = (defined($param->{'private_key'}))?
                                    $param->{'private_key'}  :
                                    $class->private_key;
  return $self;

    sub sign {
      my $self = shift;
      my $param = {@_};
      my $data = $param->{'data'};
      my $private_key = $self->private_key_file;

      return $self->execute("echo -n '$data'| openssl rsautl -sign -inkey $private_key| openssl enc -base64");
    }

    sub rsa_private {
      my $self = shift;
      my $param = {@_};
      $self->{'private_key'} = read_file( $param->{'private_key_file'} ) if
                                 defined( $param->{'private_key_file'} ) ;
                                 
      my $_openssl_rsa_obj;
      eval {
         $_openssl_rsa_obj = Crypt::OpenSSL::RSA->new_private_key( 
      								defined( $param->{'private_key'} ) ?
      								         $param->{'private_key'}   :
      								         $self->private_key 
                             );
      };
      return ($@)? $self : $_openssl_rsa_obj;
    }
    
    sub private_key {
      my $self = shift;

      if( !defined( $self->{'private_key'} ) ){
        $self->{'private_key'} = read_file( $self->private_key_file );
      }

      return $self->{'private_key'};
    }
    
    sub private_key_file {
      my $self = shift;
      return $self->{'private_key_file'};
    }

}# package pki ends

=pod

=head2 sha1 ( %params)

loads L<Chef::Encoder::sha1> class and returns new object of class L<Chef::Encoder::sha1>
it accepts ( 'data' => $data )
if none is provided it will try to use the values initialized from parent class L<Chef::Encoder>

=head3 NAME

Chef::Encoder::sha1

=head3 VERSION

1.0

=head3 DESCRIPTION

This class provides sha1 digest of the data initialized

=head3 METHODS

=head4 B<digest>

it accepts data as parameter $obj->digest( 'data' => $data )
returns sha1 digest in binary  encoded with base64 of the data passed.

=cut

#----------------------------#
#  class Chef::Encoder::sha1 #
#----------------------------#

sub sha1 {
  my $class = shift;
  my $param = {@_};

  package Chef::Encoder::sha1;
  
  use parent qw { Chef::Encoder };
  
  my $self = {};
    bless $self, qw { Chef::Encoder::sha1 };
  return $self;
      
    sub digest {
      my $self = shift;
      my $param = {@_};
      my $data = $param->{'data'};
     # return undef unless defined $data;
      return $self->execute("echo -n '$data'| openssl dgst -sha1 -binary| openssl enc -base64");
    }
    
}#sha1 package ends

=pod

=head2 base64 ( %params)

loads L<Chef::Encoder::base64> class and returns new object of class L<Chef::Encoder::base64>
it accepts ( 'data' => $data )
if none is provided it will try to use the values initialized from parent class L<Chef::Encoder>

=head3 NAME

Chef::Encoder::base64

=head3 VERSION

1.0

=head3 DESCRIPTION

This class provides base64 encoding and ecoding functionality 

=head3 METHODS

=head4 B<encode>

it accepts data as parameter $obj->encode( 'data' => $data )
returns base64 encoded value of data

=head4 B<decode>

it accepts data as parameter $obj->decode( 'data' => $data )
returns base64 decoded value of data

=cut

#-------------------------------#
#  class Chef::Encoder::base64  #
#-------------------------------#

sub base64 {
  my $class = shift;
  my $param ={@_};

  package Chef::Encoder::base64;
  use parent qw { Chef::Encoder };

  my $self = {};
  bless $self , qw{ Chef::Encoder::base64 };
  return $self;
 
   sub encode {
      my $self = shift;
      my $param = {@_};
      my $data = $param->{'data'};
      return undef unless defined $data;
      return $self->execute("echo '$data'| openssl enc -base64");
   }
   
   sub decode {
      my $self = shift;
      my $param = {@_};
      return undef unless defined $data;      
      return decode_base64( $param->{'data'} );
   }
                                
}# base64 package end


1;

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/Header.pm  view on Meta::CPAN

package Chef::Header;

=pod

=head1 NAME

Chef::Header - Class that will generate Chef::Headers 

=head1 VERSION

1.0

=cut

$Chef::Header::VERSION = 1.0;

my @base;
BEGIN {
use File::Basename qw { dirname };
use File::Spec::Functions qw { splitdir rel2abs };
 @base = ( splitdir ( rel2abs ( dirname(__FILE__) ) ) );
 pop @base; #Chef
 push @INC, '/', @base;
};

use parent qw { Chef };
use Chef::Encoder;

=pod

=head1 DESCRIPTION

This class inherites from Chef. This class will generate encrypted headers as described in the 
L<ChefHeaderDocumentation|http://docs.opscode.com/api_chef_server.html/>

Once you call L<header> method it will load L<Chef::Header::header> class . Which will generate and fill up
User Agent with appropriate Chef Headrs as specified in the above documentation.

=begin html

+---------------+
|  Chef::Header |
+-----------------------+
|  Chef::Header::header | 
+-----------------------------------+
|  Chef::Header::header::chefheader |
+-----------------------------------+

=end html

=head2 header

loads L<Chef::Header::header> class and returns an object.

=head2 Methods of B<L<Chef::Header::header>> class

=over

=item  Method( $Method )

set internally to either 'GET' or 'POST'

=item HashedPath ( $path )

calcualtes hash of end point for chef

=item XOpsContentHash ( $content )

calculdates hash of the content

=item XOpsUserId ( $class->name )

initialized user-id field sets to the user_id or client-name.

=item Host( $server )

initialized Host parameter of UA to chef server

=item XChefVersion ( $chef_server_version )

initialized Chef server Version to use

=item XOpsSign( $XOpsSign )

initializes to 'version=1.0' as specified in the chef API documentation.

=item XOpsTimestamp

initialized the request timestamp for http request to now

=item header

returns all the headers 

=item hash

returns hash of all the headers , initialized so far.

=item header_to_string

return a comma seperated list of keys and values of the header

=back 

=cut
  
  sub header {
    my $class = shift;
    my $param = {@_};
    
    package Chef::Header::header;

    use parent -norequire,qw { Chef::Header };
       
    my $self = new Chef::Header::header();

    $self->_chef_encoder( new Chef::Encoder( 'private_key_file'  => $class->private_key ) );
    
    $self->Method          ($param->{'Method'         });
    $self->HashedPath      ($param->{'Path'           });
    $self->XOpsContentHash ($param->{'Content'        });
    #$self->XOpsTimestamp   ($param->{'X-Ops-Timestamp'  });
    $self->XOpsUserId      ($class->name               );
  
    #default_values
    #$self->Accept          ($param->{'Accept'         });
    $self->Host            ($class->server             );
    $self->XChefVersion    ($class->chef_version       );
    $self->XOpsSign        ($param->{'XOpsSign'       });
    $self->Accept          ($param->{'Accept'         });    

    return $self;
  
  	 sub _chef_encoder {
		my $self = shift;
		my $obj  = shift;
		       $self->{'header_chef_encoder'} = $obj if defined $obj;
		return $self->{'header_chef_encoder'};
  	 }
  	 
    sub XOpsSign
    {
      my ($self, $x_ops_sign) = (@_);
             $self->header->{'X-Ops-Sign'} = $x_ops_sign if defined $x_ops_sign;
             $self->header->{'X-Ops-Sign'} = 'version=1.0;' unless 
     defined $self->header->{'X-Ops-Sign'};
      return $self->header->{'X-Ops-Sign'};  
    }

    sub XChefVersion
    {
      my ($self, $x_chef_version) = (@_);
             $self->header->{'X-Chef-Version'} = $x_chef_version if defined $x_chef_version;
      return $self->header->{'X-Chef-Version'};  
    }

    sub Host 
    {
      my ($self, $host) = (@_);
      if( defined ($host) ){
        $host =~ s/^(http|https):\/\/(.*)/$2/;
        $self->header->{'Host'} = $host;
      }
      return $self->header->{'Host'};  
    }

    sub Accept 
    {
      my ($self, $accept) = (@_);
             $self->header->{'Accept'} = $method if defined $accept;
             $self->header->{'Accept'} = 'application/json' unless 
     defined $self->header->{'Accept'};           
      return $self->header->{'Accept'};  
    }

    sub Method 
    {
      my ($self, $method) = (@_);
             $self->header->{'Method'} = $method if defined $method;
      return $self->header->{'Method'};
    }

    sub HashedPath
    {  
      my ($self,$path) = (@_);
			
      if (defined ($path) )
      {
         my $end_point = ($path =~ m/^\//) ? $path : "/$path";
         my $chef_encoder = $self->_chef_encoder();
         $self->header->{'Hashed Path'} = $chef_encoder->sha1
                                                        ->digest( 'data' => $end_point );
      }
            
      return $self->header->{'Hashed Path'};
    }

    sub XOpsContentHash 
    {
      my ($self,$content) = (@_);
      my $chef_encoder = $self->_chef_encoder();         
        
         $self->header->{'X-Ops-Content-Hash'} = $chef_encoder->sha1
                                                              ->digest( 'data' => $content );
      return $self->header->{'X-Ops-Content-Hash'};
    }
    
    sub XOpsTimestamp 
    {
      my ($self,$x_ops_timestamp) = (@_);
             $self->header->{'X-Ops-Timestamp'} = $x_ops_timestamp 
                                       if defined $x_ops_timestamp;
                                             
         if (!$self->header->{'X-Ops-Timestamp'}){
       		$self->header->{'X-Ops-Timestamp'} = `date -u "+%Y-%m-%dT%H:%M:%SZ"`;         
       	}
       	chomp( $self->header->{'X-Ops-Timestamp'} );
      return $self->header->{'X-Ops-Timestamp'};
		      
    }

    sub XOpsUserId 
    {
      my ($self,$x_ops_user_id) = (@_);
             $self->header->{'X-Ops-UserId'} = $x_ops_user_id 
                                    if defined $x_ops_user_id;
      return $self->header->{'X-Ops-UserId'};
    }  

    sub header 
    {
      my $self = shift;
             $self->{'header'} = {} unless defined $self->{'header'};
      return $self->{'header'};
    }

    sub hash{
      my $self = shift;
      
      return { 
      	'Accept'          => $self->Accept       ,
      	'Host'            => $self->Host         ,
      	'X-Chef-Version'  => $self->XChefVersion ,
      	'X-Ops-Userid'    => $self->XOpsUserId   ,
      	'X-Ops-Timestamp' => $self->XOpsTimestamp,
      	'X-Ops-Sign'      => $self->XOpsSign     ,
      	'X-Ops-Content-Hash' => $self->XOpsContentHash,
      	%{$self->chef_header->XOpsAuthorization} 
        } ;
    }

    sub header_to_string 
    {
      my $self = shift;
      return ( $self->{'header'} );
    }  
    
=pod
    
=head2 Methods of B<L<Chef::Header::header::chefheader>>

=over

=item Method ( $method )

initialized chefheader with $method . either 'GET' or 'POST'

=item HashedPath ( $hashed_path )

initializes hashed path and 'Hashed Path' heder value.

=item XOpsContentHash ( $content_hash )

initializes content hash and 'X-Ops-Content-Hash' header.

=item XOpsTimestamp 

initializes X-Ops-Timestamp values

=item XOpsUserId

initialized X-Ops-UserId value

=item XOpsAuthorization

initializes X-Ops-Authorization-xxxx values . for more details refere to chef header API

=item split_60

split the heder in chuncks of 60 characters 

=item hash

return chef_header in hash format

=item to_string

returns chef_header in string format . directly insertable to UserAgent headers.

=back

=cut 
    
    #-----------------------------------------#
    #  class Chef::Header::header::chefheader #
    #-----------------------------------------#

    sub chef_header {
       my $class = shift;

       package Chef::Header::header::chefheader;
       
       my $self = {};
       bless $self, qw { Chef::Header::header::chefheader };
      
       $self->_chef_encoder( $class->_chef_encoder );        
	    $self->Method          ( $class->Method          );
       $self->HashedPath      ( $class->HashedPath      );
       $self->XOpsContentHash ( $class->XOpsContentHash );                     
       $self->XOpsTimestamp   ( $class->XOpsTimestamp   );
       $self->XOpsUserId      ( $class->XOpsUserId      );
       
	    return $self;
	  	 sub _chef_encoder {
			my $self = shift;
			my $obj  = shift;
	  	          $self->{'header_chef_encoder'} = $obj if defined $obj;
			return $self->{'header_chef_encoder'};
  	 	}
  	 	    
       sub Method {
         my ($self,$method) = (@_);
                $self->{'chef_header'}->{'Method'} = $method if
                                             defined $method;
         return $self->{'chef_header'}->{'Method'};
       }

       sub HashedPath {
         my ($self,$hashed_path) = (@_);
                $self->{'chef_header'}->{'Hashed Path'} = $hashed_path if
                                                  defined $hashed_path;
         return $self->{'chef_header'}->{'Hashed Path'};
       }

       sub XOpsContentHash {
         my ($self,$x_ops_content_hash) = (@_);
                $self->{'chef_header'}->{'X-Ops-Content-Hash'} = $x_ops_content_hash if
                                                         defined $x_ops_content_hash;
         return $self->{'chef_header'}->{'X-Ops-Content-Hash'};
       }                     

       sub XOpsTimestamp {
         my ($self,$x_ops_Timestamp) = (@_);
                $self->{'chef_header'}->{'X-Ops-Timestamp'} = $x_ops_Timestamp if
                                                      defined $x_ops_Timestamp;
         return $self->{'chef_header'}->{'X-Ops-Timestamp'};
       }

       sub XOpsUserId {
         my ($self,$x_ops_user_id) = (@_);
                $self->{'chef_header'}->{'X-Ops-UserId'} = $x_ops_user_id if
                                                   defined $x_ops_user_id;
         return $self->{'chef_header'}->{'X-Ops-UserId'};
       }

       sub hash {
         my $self = shift;
         return $self->{'chef_header'};
       } 
			
       sub to_string{
         my $self = shift;
		   return undef unless defined $self->Method 
		                    && defined $self->HashedPath
		                    && defined $self->XOpsContentHash
		                    && defined $self->XOpsTimestamp
		                    && defined $self->XOpsUserId;
		                      
         return join "\n", ( 	'Method:'             . $self->Method          ,
  										'Hashed Path:'        . $self->HashedPath      ,                     
                             	'X-Ops-Content-Hash:' . $self->XOpsContentHash ,
                             	'X-Ops-Timestamp:'    . $self->XOpsTimestamp   ,
                             	'X-Ops-UserId:'       . $self->XOpsUserId      ,
                           );
       }

       sub XOpsAuthorization {
         my $self = shift;
         my $chef_encoder = $self->_chef_encoder();
         my $canonical_headers = $self->to_string;
         my $raw_header = $chef_encoder->pki->sign( 'data' => $canonical_headers );

				chomp($raw_header);
								                
         my $authorization_header = {};
         my $authorization_header_count = 1;
			
         foreach my $line (@{$self->split_60($raw_header,[])}){
         	chomp($line);
              $authorization_header->{ "X-Ops-Authorization-$authorization_header_count"} 
                                   = $line;
              $authorization_header_count++;
         }
         
         return $authorization_header;
       }

       sub split_60 {
         my ($self,$string,$result) = (@_);

         return $result unless defined $string;
         $string =~ s/\n//g if defined $string;
 
         my $fp = substr $string , 0 , 60;
         my $sp = substr $string , 60;
           push @{$result} , $fp if defined $fp;
           $self->split_60( $sp,$result) if defined $sp;

         return $result;
      }
      
    }#chef_header ends.  
  
  }#header
  
#}# new

1;

=pod

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST.pm  view on Meta::CPAN

package Chef::REST;
$Chef::REST::VERSION = 1.0;

my @base;
BEGIN {
use File::Basename qw { dirname };
use File::Spec::Functions qw { splitdir rel2abs };
 @base = ( splitdir ( rel2abs ( dirname(__FILE__) ) ) );
 pop @base; #Chef
 push @INC, '/', @base;
};

use parent qw { Chef Chef::Header };
use LWP::UserAgent;
use Mojo::JSON;

sub new {
   my $class = shift;
   my $self  = $class->SUPER::new(@_);
   bless $self, $class;

		 	
	$self->_UA_( new LWP::UserAgent( ) );
	$self->_UA_->ssl_opts( 'verify_hostname' => 0 );   
   
   return $self;

}

sub _UA_ 
{
	my ($self,$new_ua) = (@_);
  	    $self->{'_UA_'} = $new_ua if defined $new_ua;
  	return $self->{'_UA_'};
}

sub add_headers 
{
  		  my $self = shift;
  		  my $param = shift;
  		  foreach my $header_field( keys( %$param) ){
  		     $self->_UA_->default_header( $header_field, $param->{ $header_field }); 
  		  }
  		  return $self;
}  

sub get {
	my $self  = shift;
	my $param = {@_};
	         
	my $response = 
	   $self->add_headers( 
	       $self->header(
		           'Method'  => 'GET',
		           'Path'    => $param->{'api_end_point'},
		           'Content' => ''
		    )->hash
	   )
		->_UA_
		->get( 
		     $self->get_uri( $param->{'api_end_point'} )
	   );
  			  
	return $response;
}

sub post 
{
	my $self  = shift;
	my $param = {@_};
	my $mojo_json = new Mojo::JSON();
	my $response  = $self->add_headers( 
	                    $self->header(
		                             'Method'  => 'POST',
		                             'Path'    => $param->{'api_end_point'},
		                             'Content' => $mojo_json->encode($param->{'data'})
		                        )->hash
		                      )
		                      ->_UA_
		                      ->post( 
		                         $self->get_uri( $param->{'api_end_point'} ),
		                         'Content' => $mojo_json->encode($param->{'data'})	                     
	                          );
                      
	return $response;

}

sub get_uri 
{
	my ($self,$api_end_point) = (@_);
	return join '/', ( $self->server, 
	                   $api_end_point )
	        if defined $api_end_point ;
}

sub name 
{
	my ($self,$client_name) = (@_);
       $self->{ 'CHEF_CLIENT' } = $client_name if defined $client_name;
   return $self->{ 'CHEF_CLIENT' };
}


1;

__DATA__

=pod

=head1 NAME 

Chef::REST

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef;

  my $obj = new Chef::REST( );

=head1 DESCRIPTION

This clas inherites methods from Chef and Chef::Header. Please do not use these methods directly. 
Inturn these are used internally by L<Chef::REST::Client> to make REST HTTP Requests 

=head1 METHODS

=head2 Constructor

=head3 REST;

returns new Chef::REST object and initialized UserAgent;

=head3 _UA_ 

sets UserAgent object

=head3 add_headers

uses to add headers for UserAgent. It takes hash as key value  

=head3 get

generates GET HTTP request

=head3 post

generates POST HTTP request

=head3 get_uri

generates end point URI for chef request.

=head3 name

sets or gets chef client name
 
=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client.pm  view on Meta::CPAN

package Chef::REST::Client;
$Chef::REST::Client::VERSION = 1.2;

=pod

=head1 NAME

Chef::REST::Client

=head1 VERSION

1.2

=head1 SYNOPSIS

use Chef::REST::Client;

my $obj = new Chef::REST::Client
          ( 'chef_client_name' => $chef_client_name ,
            'chef_client_privaate_key' => $private_key );

   $obj->private_key( $private_key );
   $obj->name( $chef_client_name );
   $obj->roles('vagrant')->details;
   $obj->roles('vagrant','environments')->details
   $obj->roles->list;
   
   $obj->search( 'secrets' , {  q => 'id:centrify', rows => 1 } )->details
   
   $obj->environments(<env_name>,'cookbooks' , <cookbook_name>)->details;

   $obj->environments(<env_name>,'cookbooks_versions'
                                ,{ 'method' => 'post'
                                , 'data' => { 'runlist' => [ 'ms-scribe'] }
                                  }
                     );
   $obj->roles(<role_name>)->details->override_attributes;
                   
=head1 DESCRIPTION

This is the interface to the Chef server api methods listed on opscode documentation 
L<opscode Chef Api|http://docs.opscode.com/api_chef_server.html>
currently it provides implementation for only GET methods

=head1 METHODS

=head2 role( $role )

returns new L<Chef::REST::Client::role> object
used by other classes

=head2 roles ( @roles )

makes a GET request to the chef server for all the @roles and returns and L<Chef::REST::Client::roles> object.
you can directly get details for all the roles as $obj->role( 'role1', 'role2' )->details;

this inturn will return L<Chef::REST::Client::role> 

=over 

=item /roles

$obj->roles->list 

=item /roles/<role_name>

$obj->roles(<role_name>)->details

$obj->roles(<role_name>)->details->run_list;

$obj->roles(<role_name>)->details->override_attributes;

=back

=head2 runlist ( @$recipes )

returns new L<Chef::REST::Client::runlist> object. it takes a list of recipies as parameter.
used by other classes

=head2 sandboxes

returns new L<Chef::REST::Client::sandboxes> object. $obj->sandboxes->list;

=over 

=item /sandboxes

$obj->sandboxes->list 

=item /sandboxes/<id>

$obj->sandboxes(<id>)->details

=back

=head2 search

returns new L<Chef::REST::Client::search> 

=over

=item /search

$obj->search->listen

=item /search/<index>

$obj->search(<index>)->details

=item /search/ query id:centrify and get rows 1

$obj->search( 'secrets' , {  q => 'id:centrify', rows => 1 } )->details

=back  

=head2 recipe

returns new L<Chef::REST::Client::recipe> object. used by other classes

=head2 principals

returns new L<Chef::REST::Client::principals> object. $obj->principals->details;

=over 

=item /principals

$obj->principals->list 

=item /principals/<name>

$obj->principals(<name>)->details

=back

=head2 node

returns new L<Chef::REST::Client::node> object. $obj->node->details;
used by other classes
 
=head2 nodes

returns new L<Chef::REST::Client::nodes> object. $obj->nodes->list;

=over 

=item /nodes

$obj->nodes->listen

=item /nodes/<node_name>

$obj->nodes(<node_name>)->details 

=back

=head2 envrunlist

returns new L<Chef::REST::Client::envrunnlist> object. used by other classes

=head2 environment

returns new L<Chef::REST::Client::environment> object. used by other classes

=head2 environments

returns new L<Chef::REST::Client::environments> object.

=over 

=item  /environment/<env_name>

$obj->environments(<env_name>)->details;

=item /environment/<env_name>/cookbooks/<cookbook_name>

$obj->environments(<env_name>,'cookbooks' , <cookbook_name>)->details;

=item /environment/<env_name>/cookbooks

$obj->environments(<env_name>,'cookbooks')

=item POST /environments/<env_name>/cookbooks_versions

$obj->environments(<env_name>,'cookbooks_versions'
                             ,{ 'method' => 'post'
                              , 'data' => { 'runlist' => [ 'ms-scribe'] }
                              }
                   );

=back

=head2 databag

returns new L<Chef::REST::Client::databag> object.

=head2 data

returns new L<Chef::REST::Client::data> object.

=over 

=item /data

$obj->data->list

=item /data/<var_name>

$obj->data( <var_name> )->details

=back

=head2 cookbook

returns new L<Chef::REST::Client::cookbook> object.

=head2 cookbooks

returns new L<Chef::REST::Client::cookbooks> object.

=over 

=item /cookbooks

$obj->cookbooks->list 

=item /cookbooks/<cookbook_name>

$obj->cookbooks(<cookbook_name>)->details 

$obj->cookbooks(<cookbook_name> , '_latest' )->details->recipes;

$obj->cookbooks(<cookbook_name> , '_latest' )->details->attributes;

=back

=head2 cookbook_version

returns new L<Chef::REST::Client::cookbook_version> object.
used by other classes

=head2 cookbook_versions

returns new L<Chef::REST::Client::cookbook_versions> object.
collection of L<Chef::REST::Client::cookbook_version>

=head2 clients

returns new L<Chef::REST::Client::clients> object.

=over 

=item /clients

$obj->clients->list 

=item /clients/<client_name>/

$obj->clients(<client_name>)->details


=back

=head2 attribute

returns new L<Chef::REST::Client::attribute> object.
used by other classes to structure data

=head2 attributes

returns new L<Chef::REST::Client::attributes> object.
collection of L<Chef::REST::Client::attribute>

=cut

my @base;
BEGIN {
use File::Basename qw { dirname };
use File::Spec::Functions qw { splitdir rel2abs };
 @base = ( splitdir ( rel2abs ( dirname(__FILE__) ) ) );
 pop @base; #REST
 pop @base; #Chef
 push @INC, '/', @base;
};

use parent qw { Chef::REST };
use Mojo::JSON;
use Module::Load;
use vars qw { $AUTOLOAD };

sub new {
  my $class = shift;
  my $param = {@_};
  my $self  = $class->SUPER::new(@_);
     $self->name($param->{'chef_client_name'}) if defined $param->{'chef_client_name'};
     $self->private_key($param->{'chef_client_private_key'}) if defined $param->{'chef_client_private_key'};     
  bless $self, $class;
  return $self;
}

sub name {
  my ($self,$client_name) = (@_);
         $self->{ 'CHEF_CLIENT' } = $client_name if defined $client_name;
  return $self->{ 'CHEF_CLIENT' };
}

#----------------------------------#
# Class : Chef::REST::Client::Role #
#----------------------------------#
sub role_ 
{
  my $self = shift;
  my $param = {@_};


}

#-----------------------------------#
# Class : Chef::REST::Client::Roles #
#-----------------------------------#
sub roles_ 
{
  my $self = shift;
  
  package Chef::REST::Client::roles;

  use parent qw { Chef::REST::Client };

  bless $self, 'Chef::REST::Client::roles';
        $self->api_end_point('roles');
  return $self;
  
  sub api_end_point 
  {
    my ($self,$api_end_point) = (@_);
           $self->{ 'API_END_POINT' } = $api_end_point if defined $api_end_point;
    return $self->{ 'API_END_POINT' };
  }
    
  sub list 
  {
    my $self = shift;
    my $end_point = $self->api_end_point;
    my $mojo_json = new Mojo::JSON();
    my $list_of_roles = 
       $mojo_json->decode(
             $self->ua(  'client_name'   => $self->name )
                  ->get( 'api_end_point' => $end_point  )
                  ->decoded_content
          );
    my @_roles;      
    foreach my $r ( keys(%$list_of_roles) ){
      my $role = Chef::REST::Client::role( 'name' => $r,  
                                           'url'  => $list_of_roles->{$r} 
                                         );
       push @_roles , $role;
    }
    return \@_roles;
  }

}

sub AUTOLOAD {
   my $self = shift;
   my $hash_param = pop @_;
   my ($method, $data) = ( 'GET');
   my $request_url = undef;
   
   if( ref $hash_param ne 'HASH')
   {
      push @_ , $hash_param if defined $hash_param;
      undef $hash_param;
   }
   else {
   	$method = 'POST' if $hash_param->{'method'} =~ m/post/i;
   	$data   = $hash_param->{'data'};
   }  

   my @param = @_;

	my $module =  (split ('::', $AUTOLOAD))[-1];
	load $AUTOLOAD;	
	my $obj = $AUTOLOAD->new();

	my (@api_end_point, @q );
	   @api_end_point = ( $module , @param );
	   
	foreach my $k ( keys(%$hash_param))
	{		
		push @q , join '=' , ($k , $hash_param->{$k});
	}
	
	$request_url = join '/', @api_end_point;
	$request_url = join '?' , $request_url , (join '&', @q ) if defined $q[0];
   
	my $result;
	
	 if ($method eq 'GET' )
	 { 
	   $result = $self->get( 'api_end_point' =>  $request_url )->decoded_content;
	 }
	 elsif( $method eq 'POST')
	 {
	   $result = $self->post( 
	                    'api_end_point' =>  $request_url ,
	                    'data'          => $data
	                 );
	 }         
   $obj->populate( $result ); 
	return $obj;
}

1;

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/EndPoints.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::EndPoints                            #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::EndPoints;
$Chef::REST::Client::EndPoints::VERSION = 1.0;

=pod 

=head1 NAME

Chef::REST::Client::EndPoints

=head1 VERSION

1.0

=head1 SYNOPSIS

my $obj = new Chef::REST::Client::EndPoints( 'api_end_point' => $end_point );
   $obj->populate($result);
   $obj->raw;
   
=head1 DESCRIPTION

used internally by other classes

=head1 METHODS

=head2 Constructor

initialized api_end_point

=head2 api_end_point( $end_point )

set api_end_point if passed otherwise returns current value 

=head2 populate($result)

internal method  generates data structure based on the result of the http request

=head2 raw

returns the raw data structure.

=cut

my @base;
BEGIN {
use File::Basename qw { dirname };
use File::Spec::Functions qw { splitdir rel2abs };
 @base = ( splitdir ( rel2abs ( dirname(__FILE__) ) ) );
 pop @base; #REST
 pop @base; #Chef
 push @INC, '/', @base;
};

use Mojo::JSON;

sub new {
  my $class  = shift;
  my $param  = {@_};
  my $self   = {};
  bless $self, $class;
  $self->api_end_point($param->{'api_end_point'});
  return $self;
}

 sub api_end_point 
  {
    my ($self,$api_end_point) = (@_);
           $self->{ 'API_END_POINT' } = $api_end_point if defined $api_end_point;
    return $self->{ 'API_END_POINT' };
  }

sub populate
{
  my $self = shift;
  my $result = shift;
     $self->___data___($result);
}

sub ___data___
{
	my $self = shift;
	my $result = shift;
	my $mojo_json = new Mojo::JSON();
	   $self->{'___data___'} = 
	   		$mojo_json->decode( $result )  
     						if defined $result;
     						
	return $self->{'___data___'};
}

sub raw { return  $_[0]->___data___; }
	
1;

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/attribute.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::attribute                            #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::attribute;
$Chef::REST::Client::attribute::VERSION = 1.0;

sub new
{
	my $class = shift;
	my $param = {@_};
	my $self = {};
	bless $self, $class;
	
	$self->key  ( $param->{'key'  });
	$self->value( $param->{'value'});

	return $self;
}

sub key   { $_[0]->{'key'  } = $_[1] if defined $_[1]; return $_[0]->{'key'  }; }
sub value { $_[0]->{'value'} = $_[1] if defined $_[1]; return $_[0]->{'value'}; }

1;

__DATA__

=pod

=head1 NAME 

Chef::REST::Client::attribute

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::attribute;

  my $obj = new Chef::REST::Client::attribute( 'key' => $key, 'value' => $value );
     $obj->key;
     $obj->value;

=head1 DESCRIPTION

Chef attribute class. used internally

=head1 METHODS

=head2 Chef::REST::Client::attribute( key => $key , value => $value )

returns new object of class L<Chef::REST::Client::attribute> with %params

=head2 key ( $key )

get or set value for 'key'

=head2 value ($value )

get or set value for 'value'

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/attributes.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::attributes                           #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::attributes;
use Chef::REST::Client::attribute;

$Chef::REST::Client::attributes::VERSION = 1.0;

sub new
{
	my $class = shift;
	my $param = shift;
	my $self = {};
	bless $self, $class;
	$self->array_parse($param);
	$self->parse( $param );
	return $self->{'___collection___'};
}

sub array_parse
{
	my $self = shift;
	my $param = shift;
   return $self->{'___collection___'} unless ref $param eq 'ARRAY';
	map { $self->parse( $_ );  } @$param;
}

sub parse 
{
	my $self  = shift;
	my $param = shift;

	return  unless ref $param eq 'HASH';
	
		foreach my $k ( keys (%$param ) )
		{
			if ( ref $param->{$k} eq 'HASH' )
			{
			   my $_obj =  new Chef::REST::Client::attribute( 
			     					key   => $k , 
			     					value => $self->parse( $param->{ $k } ) 
			     	 	);
				push @{ $self->{ '___collection___'} } , $_obj if defined $_obj; 
			} 
			elsif ( ref $param->{$k} eq 'ARRAY' )
			{
				#my $_obj = new Chef::REST::Client::attribute( key => $k , value => $param->{$k} );
				return $param->{$k};
			}
			else
			{
				my $_obj =  new Chef::REST::Client::attribute( 
			     					key   => $k , 
			     					value => $param->{ $k } 
			     	 			);

				push @{ $self->{ '___collection___'} } , $_obj if defined $_obj; 
			}
			
		}
	#return $self->{'___collection___'};
}

1;

__DATA__

=pod

=head1 NAME 

Chef::REST::Client::attributes

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::attributes;

  my $obj = new Chef::REST::Client::attributes( @attributes | %attributes );
     $obj->array_parse( @attributes)
     $obj->parse( %attributes );

=head1 DESCRIPTION

Chef attributes collection class. used internally

=head1 METHODS

=head2 Chef::REST::Client::attributes( @attributes | %attributes )

returns new object of class L<Chef::REST::Client::attributes> with @attributes or %attributes 

=head2 array_parse ( @attributes )

returns list of L<Chef::REST::Client::attribute> class

=head2 parse ( %attributes )

returns list of L<Chef::REST::Client::attribute> class

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/clients.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::clients                              #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::clients;
use parent qw { Chef::REST::Client::EndPoints };

$Chef::REST::Client::clients::VERSION = 1.0;

sub list 
  {
    my $self = shift;
    my $list_of_roles = $self->___data___;
    foreach my $c ( keys(%$list_of_clients) ){
      my $client = Chef::REST::Client::client( 'name' => $r,  
                                             'url'  => $list_of_roles->{$r} 
                                           );
      push @{'___clients_list___'} , $client;
    }
    return @{'___clients_list___'};
  }
  
  1;
  
__DATA__
 
=pod
  
=head1 NAME
  
Chef::REST::Client::clients
  
=head1 VERSION
  
1.0
  
=head1 SYNOPSIS

$obj->client->list;
 
=head1 DESCRIPTION

This is an internal module used by L<Chef::REST::Client>

=head1 METHODS

=head2 list

lists all the L<Chef::REST::Client::client> clients

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/cookbook.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::cookbook                             #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::cookbook;

use Chef::REST::Client::cookbook_versions;
use Chef::REST::Client::attributes;

$Chef::REST::Client::cookbook::VERSION = 1.0;

=pod 

=head1 NAME

Chef::REST::Client::cookbook

=head1 VERSION

1.0

=head1 SYNOPSIS

my $obj = new Chef::REST::Client::cookbook( 'name'       => $cookbook_name
                                          , 'url'        => $cookbook_url
                                          , 'versions'   => $versions
                                          , 'libraries'  => $libraries
                                          , 'providers'  => $providers
                                          , 'resources'  => $resources
                                          , 'root_files' => $root_files
                                          , 'version'    => $cookbook_version
                                          , 'templates'  => $templates
                                          , 'files'      => $files
                                          , 'attributes' => $attributes
                                          , 'recipes'    => $recipes
                                          , 'metadata'   => $metadata );
   
=head1 DESCRIPTION

used internally by other classes like L<Chef::REST::Client::cookbooks>

=head1 METHODS

=head2 Constructor

returns new Chef::REST::Client::cookbook object

=cut

sub new {
   my $class = shift;
   my $param = {@_};
   
   my $self = {};
 	bless $self, $class;   

   $self->name(     $param->{'name'      });
   $self->url(      $param->{'url'       });
   $self->versions( $param->{'versions'  });
   
   $self->libraries(  $param->{'libraries' });
   $self->providers(  $param->{'providers' });
   $self->resources(  $param->{'resources' });
   $self->root_files( $param->{'root_files'});
   $self->version (   $param->{'version'   });
   $self->templates ( $param->{'templates' });
   $self->files (     $param->{'files'     });
   $self->attributes( $param->{'attributes'});
   $self->recipes(    $param->{'recipes'   });
   $self->metadata(   $param->{'metadata'  });

  return $self;
}

=pod

=head2 url( $url )

set 'url' property value if speicfied else return previous value;

=cut

sub url        { $_[0]->{'url'       } = $_[1] if defined $_[1]; return $_[0]->{'url'       };}  

=pod

=head2 name( $name )

set 'name' property value if speicfied else return previous value;

=cut

sub name       { $_[0]->{'name'      } = $_[1] if defined $_[1]; return $_[0]->{'name'      };}

=pod

=head2 version( $version )

set 'version' property value if speicfied else return previous value;

=cut

sub version    { $_[0]->{'version'   } = $_[1] if defined $_[1]; return $_[0]->{'version'   };}

=pod

=head2 libraries( $libraries )

set 'libraries' value if speicfied else return previous value;

=cut

sub libraries
{
	my $self = shift;
	my $libraries = shift;
	$self->{'libraries'} = $libraries;
	return $self->{'libraries'}; 
}

=pod

=head2 providers( $providers )

set 'providers' value if speicfied else return previous value;

=cut

sub providers
{
	my $self = shift;
	my $providers = shift;
	$self->{'providers'} = $providers;
	return $self->{'providers'}; 
}

=pod

=head2 resources( $resources )

set 'resources' value if speicfied else return previous value;

=cut

sub resources
{
	my $self = shift;
	my $resources = shift;
	$self->{'resources'} = $resources;
	return $self->{'resources'};
}

=pod

=head2 root_files( $root_files )

set 'root_files' value if speicfied else return previous value;

=cut

sub root_files
{
	my $self = shift;
	my $root_files = shift;
	$self->{'root_files'} = $root_files;
	return $self->{'root_files'};
}

=pod

=head2 templates( $templates )

set 'templates' value if speicfied else return previous value;

=cut

sub templates
{
	my $self = shift;
	my $templates = shift;
	$self->{'templates'} = $templates;
	return $self->{'templates'};
}

=pod

=head2 files( $files )

set 'filess' value if speicfied else return previous value;

=cut

sub files
{
	my $self = shift;
	my $files = shift;
	$self->{'files'} = $files;
	return $self->{'files'};
}

=pod

=head2 attributes( $attributes )

$attributes is converted to L<Chef::REST::Client::attributes> class and is assigned to 'attributes' property
returns values of 'attributes' property if no argument is given.

=cut

sub attributes
{
	my $self = shift;
	my $attributes = shift;
	$self->{'attributes'} = new Chef::REST::Client::attributes($attributes) if defined $attributes;
	return $self->{'attributes'};
}

=pod

=head2 recipes( $recipes )

set 'recipes' value if speicfied else return previous value;

=cut

sub recipes
{
	my $self = shift;
	my $recipes = shift;
	$self->{'recipes'} = $recipes if defined $recipes;
	return $self->{'recipes'};
}

=pod

=head2 metadata( $metadata )

set 'metadata' value if speicfied else return previous value;

=cut

sub metadata
{
	my $self = shift;
	my $metadata = shift;
	$self->{'metadata'} = $metadata;
	return $self->{'metadata'};
}

=pod

=head2 versions( $versions )

set 'versions' value if speicfied else return previous value;
$versions is converted to L<Chef::REST::Client::coookbook_versions> class

=cut

# move to seperate class if possible
sub versions
{ 
	my $self  = shift;
	my $param = shift;
	   $param = new Chef::REST::Client::cookbook_versions( $param )
				    unless ref $param eq 'ARRAY'
				    &&     ref $param->[0] eq 'Chef::REST::Client::cookbook_version';
				     
	$self->{'versions'} = $param if defined $param;
	return $self->{'version'};
}

1;

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/cookbook_version.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::cookbook_version                     #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::cookbook_version;

$Chef::REST::Client::cookbook_version::VERSION = 1.0;

=pod 

=head1 NAME

Chef::REST::Client::cookbook_version

=head1 VERSION

1.0

=head1 SYNOPSIS

my $obj = new Chef::REST::Client::cookbook_version
              ( 'url '    => $url
              , 'version' => $version );
   
=head1 DESCRIPTION

used internally by other classes like L<Chef::REST::Client::cookbooks>

=head1 METHODS

=head2 Constructor

returns new Chef::REST::Client::cookbook_version object

=cut

sub new 
{
	my $class = shift;
	my $param = {@_};
	my $self = {};
	
	bless $self, $class;
	
	$self->url    ( $param->{'url'    } );
	$self->version( $param->{'version'} );	
	
	return $self;
}

=pod

=head2 url( $url )

set 'url' property value if speicfied else return previous value;

=cut

sub url     { $_[0]->{'url'    } = $_[1] if defined $_[1]; return $_[0]->{'url'    }; }

=pod

=head2 versions( $versions )

set 'versions' value if speicfied else return previous value;

=cut

sub version { $_[0]->{'version'} = $_[1] if defined $_[1]; return $_[0]->{'version'}; }

1;

=pod 

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/cookbook_versions.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::cookbook_versions                    #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::cookbook_versions;

use Chef::REST::Client::cookbook_version;

$Chef::REST::Client::cookbook_versions::VERSION = 1.0;

sub new
{
    my $class = shift;
    my $list_of_cookbook_versions = shift;

	 foreach my $v (@$list_of_cookbook_versions )
	 {
	 	push @{ '___cookbook_versions___' } 
	 	   , new Chef::REST::Client::cookbook_version(
	 										'url'     => $v->{'url'    },
	 										'version' => $v->{'version'}
	 							    	);
	 }
	 return \@{'___cookbook_versions___'};
	
}
1;

=pod 

=head1 NAME

Chef::REST::Client::cookbook_versions

=head1 VERSION

1.0

=head1 SYNOPSIS

my $obj = new Chef::REST::Client::cookbook_versions
              ( @list_of_cookbook_versions);
   
=head1 DESCRIPTION

used internally by other classes like L<Chef::REST::Client::cookbook>

=head1 METHODS

=head2 Constructor

returns array of L<Chef::REST::Client::cookbook_versions> objects

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/cookbooks.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::cookbooks                            #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::cookbooks;
use parent qw { Chef::REST::Client::EndPoints };

$Chef::REST::Client::cookbooks::VERSION = 1.0;

use Chef::REST::Client::cookbook;
use Chef::REST::Client::cookbook_versions;

=pod 

=head1 NAME

Chef::REST::Client::cookbooks

=head1 VERSION

1.0

=head1 SYNOPSIS

$obj->cookbooks('yum', '_latest')->details;
$obj->cookbooks('yum', '_latest')->details->attributes;

=head1 DESCRIPTION

This class contains methods to get cookbooks from chef server.

=head1 METHODS

=head2 list 

This method list all the cookbooks available. 
$obj->cookbook()->list;

=cut

# this module will be passed tha json parsed hash 
# under ___data__() or variable.
# process it depending on the content expected.

sub list 
{
    my $self = shift;
    my $list_of_cookbooks = $self->___data___;
	 return undef if $self->___data___->{'chef_type'} eq 'cookbook';
	
    foreach my $c ( keys(%$list_of_cookbooks) ){
      my $cookbook = new Chef::REST::Client::cookbook('name' => $c);
 			$cookbook->url( $list_of_cookbooks->{$c}->{'url'});
 			$cookbook->versions( $list_of_cookbooks->{$c}->{'versions'} );
      push @{'___cookbooks_list___'} , $cookbook;
    }
    return @{'___cookbooks_list___'};
}

=head2 details

This method fetches details about a cookbook

$obj->cookbook('yum')->details;

=cut

sub details
{
  my $self = shift;
  my $data = $self->___data___;

#return $self->raw();

  return $self->raw() unless ref $data eq 'HASH';

	return new Chef::REST::Client::cookbook(
		'name'       => $data->{'cookbook_name'},
		'libraries'  => $data->{'libraries'    },
		'providers'  => $data->{'providers'    },
		'resources'  => $data->{'resources'    },
		'root_files' => $data->{'root_files'   },
		'version'    => $data->{'version'      },
		'templates'  => $data->{'templates'    },
		'files'      => $data->{'files'        },
		'attributes' => $data->{'attributes'   },
		'recipes'    => $data->{'recipes'      },
		'metadata'   => $data->{'metadata'     },
	) if defined $data->{'cookbook_name'};  
  
  my $obj =  new Chef::REST::Client::cookbook (  'name' => keys(%$data));
     $obj->url(      $data->{ $obj->name }->{'url'     } );
     $obj->versions( $data->{ $obj->name }->{'versions'} );


	return $obj;     
}
 
1;

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <bpatel10@nyit.edu>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/data.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::databag                              #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::data;
use parent qw { Chef::REST::Client::EndPoints };
use Chef::REST::Client::databag;

$Chef::REST::Client::data::VERSION = 1.0;

sub list 
{
    my $self = shift;
    my $databags = $self->___data___;
    
    foreach my $databag ( keys(%$databags) )
    {
    	push @{'___data_bags_list___'} , 
    		new Chef::REST::Client::databag( 
    					'name' => $databag,
    					'url'  => $databags->{$databag}
    		      );
    }
	 return @{'___data_bags_list___'};
}  
sub details
{
  my $self = shift;
  my $data = $self->___data___;

  return $self->raw() unless ref $data eq 'HASH';
    
  return $data;
}  
  
1;

=pod

=head1 NAME 

Chef::REST::Client::data

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::data;

$obj->data->list;
$obj->data->details;
$obj->data( 'abcusers' , 'webro' )->details;

=head1 DESCRIPTION

Chef data class. used internally contains methods to fetch data from Chef server.This will return an array of L<Chef::REST::Client::databag> objects.

=head1 METHODS

=head2 list

list all the data elements from Chef Server

$obj->data->list

=head2 details

fetch all the details about the data object saved in the Chef server.
internally calls raw() method of L<Chef::REST::Client::EndPoint>

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <mail4bhavin@yahoo.com>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/databag.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::databag                              #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::databag;
use vars qw { $AUTOLOAD };

$Chef::REST::Client::databag::VERSION = 1.0;

sub new {
   my $class = shift;
   my $param = {@_};
   
   my $self = {};
 	bless $self, $class;   

   $self->name( $param->{'name' });
   $self->url(  $param->{'url'  });
   
  return $self;
}

sub AUTOLOAD 
{
	my $self  = shift;
	my $param = shift;
	my $module =  (split ('::', $AUTOLOAD))[-1];
	$self->{ $module } = $param if defined $param;
	return $self->{ $module };
}

1;


=pod

=head1 NAME 

Chef::REST::Client::databag

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::databag;

my $obj = new Chef::REST::Client::databag( 'name' => $name , 'url' => $databag_link );

=head1 DESCRIPTION

Class representation of Chef DataBag;
 
=head1 METHODS

=head2 name

sets or gets 'name' property value 

$obj->name;

=head2 url

sets or gets 'url' property value 

$obj->url;

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <mail4bhavin@yahoo.com>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/environment.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::environment                          #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::environment;
use parent qw { Chef::REST::Client::EndPoints };

$Chef::REST::Client::environment::VERSION = 1.0;

sub new {
   my $class = shift;
   my $param = {@_};
   
   my $self = $class->SUPER::new(@_);
 	bless $self, $class;   

   $self->name(
          $param->{'name'               });
   $self->url(
          $param->{'url'                });
   $self->description(
          $param->{'description'        });
   $self->override_attributes(
          $param->{'override_attributes'});
   $self->default_attributes(
          $param->{'default_attributes' });
   $self->cookbook_versions(
          $param->{'cookbook_versions'  });

  return $self;
}

sub override_attributes { $_[0]->{'override_attributes'} = $_[1] if defined $_[1]; return $_[0]->{'override_attributes'};}
sub default_attributes  { $_[0]->{'default_attributes' } = $_[1] if defined $_[1]; return $_[0]->{'default_attributes' };}

sub url                 { $_[0]->{'url'                } = $_[1] if defined $_[1]; return $_[0]->{'url'                };}  
sub name                { $_[0]->{'name'               } = $_[1] if defined $_[1]; return $_[0]->{'name'               };}
sub description         { $_[0]->{'description'        } = $_[1] if defined $_[1]; return $_[0]->{'descripton'         };}

# move to seperate class if possible
sub cookbook_versions   { $_[0]->{'cookbook_versions'  } = $_[1] if defined $_[1]; return $_[0]->{'cookbook_versions'  };}

1;

=pod

=head1 NAME 

Chef::REST::Client::environment

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::environment;

  my $obj = new Chef::REST::Client::environment
                ( 'name'                => $name
                , 'url'                 => $url
                , 'description'         => $description
                , 'override_attributes' => $override_attributes
                , 'default_attributes'  => $default_attributes
                , 'cookbook_versions'   => $cookbook_versions
                );
     $obj->key;
     $obj->value;

=head1 DESCRIPTION

Class representation of Chef Environment.

=head1 METHODS

=head2 Constructor

returns new object of class L<Chef::REST::Client::environment> with %params

=head2 name ( $name )

get or set value for 'name'

=head2 url ( $url )

get or set value for 'url'

=head2 description ( $description )

get or set value for 'description'

=head2 override_attributes ( $override_attributes )

get or set value for 'override_attributes'

=head2 default_attributes ( $default_attributes )

get or set value for 'default_attributes'

=head2 cookbook_versions ( $cookbook_versions )

get or set value for 'cookbook_versions'

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <mail4bhavin@yahoo.com>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/environments.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::environments                         #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::environments;
use parent qw { Chef::REST::Client::EndPoints };

use Chef::REST::Client::environment;
use Chef::REST::Client::attributes;

$Chef::REST::Client::environments::VERSION = 1.0;

# this module will be passed tha json parsed hash 
# under ___data__() or variable.
# process it depending on the content expected.

sub list 
{
    my $self = shift;
    my $list_of_environments = $self->___data___;
	 return undef if $self->___data___->{'chef_type'} eq 'environment';
	
    foreach my $e ( keys(%$list_of_environments) ){
      my $environment = new Chef::REST::Client::environment
      				( 
      					'name' => $e,
                     'url'  => $list_of_environments->{$e},
                  );
                  
      push @{'___environments_list___'} , $environment;
    }
    return @{'___environments_list___'};
}

sub details
{
  my $self = shift;
  my $data = $self->___data___;

  return $self->raw() unless ref $data eq 'HASH' && $data->{'name'};
  return new Chef::REST::Client::environment (
  					'name'                => $data->{'name'       },
  					'description'         => $data->{'description'},
  					'default_attributes'  => new Chef::REST::Client::attributes( $data->{'default_attributes' } ),
  					'override_attributes' => new Chef::REST::Client::attributes( $data->{'override_attributes'} ),
					'cookbook_versions'   => $data->{'cookbook_versions'}  					
         );  
}
 
1;

=pod

=head1 NAME 

Chef::REST::Client::environments

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::environments;

$obj->environments->list;
$obj->environments('dev')->details;
  
=head1 DESCRIPTION

Class that represents collection of environments 

=head1 METHODS

=head2 list

return list of environments, array of L<Chef::REST::Client::environment> objects.

=head2 details ( $details )

retun detail about a perticular environment.

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <mail4bhavin@yahoo.com>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/envrunlist.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::envrunlist                           #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::envrunlist;

$Chef::REST::Client::envrunlist::VERSION = 1.0;

sub new
{
	my $class = shift;
	my $param = {@_};
	my $self  = {};
	bless $self, $class;
	
	$self->env_name( $param->{'env_name'} );
	$self->run_list( $param->{'run_list'} );
	
	return $self;
}

sub env_name  { $_[0]->{'env_name' } = $_[1] if defined $_[1]; return $_[0]->{'env_name' }; }
sub run_list  { $_[0]->{'run_list' } = $_[1] if defined $_[1]; return $_[0]->{'run_list' }; }


1;

=pod

=head1 NAME 

Chef::REST::Client::attribute

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::envrunlist;

  my $obj = new Chef::REST::Client::envrunlist
                ( 'env_name' => $environment_name
                , 'run_list' => $run_list
                );
     $obj->env_name;
     $obj->run_list;

=head1 DESCRIPTION

Class that reperesents Chef Environment run list.

=head1 METHODS

=head2 Constructor

returns new object of class L<Chef::REST::Client::envrunlist> with %params

=head2 env_name ( $environment_name )

get or set value for 'env_name'

=head2 run_list ($run_list )

get or set value for 'run_list'

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <mail4bhavin@yahoo.com>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/node.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::node                                 #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::node;

use vars qw { $AUTOLOAD };

use Chef::REST::Client::environment;
use Chef::REST::Client::attributes;

$Chef::REST::Client::node::VERSION = 1.0;

sub new {
   my $class = shift;
   my $param = {@_};
   
   my $self = {};
 	bless $self, $class;   

   $self->name( $param->{'name' });
   $self->url(  $param->{'url'  });
   $self->normal ( $param->{'normal'});
   $self->environment( $param->{'environment'} );
   $self->automatic( $param->{'automatic'});
   $self->override ($param->{'override'});
   $self->default ( $param->{'default'} );
   
  return $self;
}

sub environment
{
	my $self = shift;
	my $param = shift;
	$self->{'environment'} = 
		new Chef::REST::Client::environment ( 'name' => $param ) if defined $param;
 	return $self->{'environment'};		
}

sub AUTOLOAD 
{
	my $self  = shift;
	my $param = shift;
	my $module =  (split ('::', $AUTOLOAD))[-1];
	$self->{ $module } = $param if defined $param;
	return $self->{ $module };
}

1;

=pod

=head1 NAME 

Chef::REST::Client::node

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::node;

  my $obj = new Chef::REST::Client::node
                ( 'name'        => $node_name
                , 'url'         => $node_url
                , 'normal'      => $normal
                , 'environment' => $node_environment
                , 'automatic'   => $automatic
                , 'override'    => $override
                , 'default'     => $default
                );

=head1 DESCRIPTION

Class representation of Chef node.

=head1 METHODS

=head2 Constructor

returns new object of class L<Chef::REST::Client::node> with %params

=head2 name ( $name )

get or set value for 'name'

=head2 url ( $url )

get or set value for 'url'

=head2 normal ( $normal )

get or set value for 'normal'

=head2 environment ( $environment )

get or set value for 'environment'

=head2 automatic ( $automatic )

get or set value for 'automatic'

=head2 override ( $override )

get or set value for 'override'

=head2 default ( $default )

get or set value for 'default'

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <mail4bhavin@yahoo.com>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/nodes.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::nodes                                #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::nodes;
use parent qw { Chef::REST::Client::EndPoints };

use Chef::REST::Client::node;

$Chef::REST::Client::nodes::VERSION = 1.0;

sub list 
  {
    my $self = shift;
    my $list_of_nodes = $self->___data___;

    foreach my $n ( keys(%$list_of_nodes) ){
      my $node = new Chef::REST::Client::node( 
      						'name' => $n,  
                        'url'  => $list_of_nodes->{$n} 
                 );
      push @{'___nodes_list___'} , $node;
    }
    return @{'___nodes_list___'};
  }
  
sub details
{
  my $self = shift;
  my $data = $self->___data___;

  return $self->raw() unless ref $data eq 'HASH';

#  return $data;
  
  return new Chef::REST::Client::node(
  		'name' => $data->{'name'},
  		'environment' => $data->{'chef_environment'},
  		'automatic'   => $data->{'automatic'},
  		'override'    => $data->{'override' },
  		'default'     => $data->{'default'  },
  		'run_list'    => $data->{'run_list' }
  );
	
    
}  
  
1;

=pod

=head1 NAME 

Chef::REST::Client::nodes

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::nodes;

$obj->nodes->list;
$obj->nodes('server1')->details;
  
=head1 DESCRIPTION

Class that represents collection of nodes 

=head1 METHODS

=head2 list

return list of nodess, array of L<Chef::REST::Client::node> objects.

=head2 details ( $details )

retun detail about a perticular node.

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <mail4bhavin@yahoo.com>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/principals.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::principals                           #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::principals;
use parent qw { Chef::REST::Client::EndPoints };

$Chef::REST::Client::principals::VERSION = 1.0;

sub details
{
  my $self = shift;
  my $data = $self->___data___;

  return $self->raw() unless ref $data eq 'HASH';
    
  return $data;
}  
  
1;

=pod

=head1 NAME 

Chef::REST::Client::principals

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::principals;

$obj->principals( $principal_name )->details;
  
=head1 DESCRIPTION

Class that represents collection of environments 

=head1 METHODS

=head2 list

return list of environments, array of L<Chef::REST::Client::environment> objects.

=head2 details ( $details )

retun detail about a perticular environment.

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <mail4bhavin@yahoo.com>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/recipe.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::recipe                               #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::recipe;

$Chef::REST::Client::recipe::VERSION = 1.0;

sub new
{
	my $class = shift;
	my $recipe = shift;
	my $self = {};
	bless $self, $class;
	$self->parse( $recipe );
	return $self;
}

sub parse
{
	my $self = shift;
	my $recipe = shift;
	$recipe =~ s/^recipe\[(.*)\]/$1/;

	$recipe =~ /((?<cookbook>[\w-_]+)::)?(?<recipe>[\w-_]+)(@(?<version>.*))?/;
		
	$self->cookbook( $+{cookbook });
	$self->recipe(   $+{recipe   });
	$self->version(  $+{version  });
	
}

sub cookbook { $_[0]->{'cookbook'} = $_[1] if defined $_[1]; return $_[0]->{'cookbook'}; }
sub recipe   { $_[0]->{'recipe'  } = $_[1] if defined $_[1]; return $_[0]->{'recipe'  }; }
sub version  { $_[0]->{'version' } = $_[1] if defined $_[1]; return $_[0]->{'version' }; }

1;

=pod

=head1 NAME 

Chef::REST::Client::recipe

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::recipe;

my $obj = new Chef::REST::Client::recipe( $recipe);
   $obj->cookbook;
   $obj->recipe;
   $obj->version;
  
=head1 DESCRIPTION

Class that represents chef recipe 

=head1 METHODS

=head2 Constructor

return new L<Chef::REST::Client::recipe> object.

=head2 cookbook ( $cookbook )

set or get cookbook property

=head2 recipe ( $recipe )

set or get recipe property

=head2 version ( $version )

set or get version property

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <mail4bhavin@yahoo.com>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/role.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::role                                 #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::role;

use parent qw { Chef::REST::Client::EndPoints };

$Chef::REST::Client::role::VERSION = 1.0;

sub new {
   my $class = shift;
   my $param = {@_};
   
   my $self = $class->SUPER::new(@_);
 	bless $self, $class;   

   $self->name(
          $param->{'name'               });
   $self->url(
          $param->{'url'                });
   $self->run_list(
          $param->{'run_list'           });
   $self->description(
          $param->{'description'        });
   $self->override_attributes(
          $param->{'override_attributes'});
   $self->default_attributes(
          $param->{'default_attributes' });
   $self->env_run_lists(
          $param->{'env_run_lists'      });

  return $self;
}

sub override_attributes { $_[0]->{'override_attributes'} = $_[1] if defined $_[1]; return $_[0]->{'override_attributes'};}
sub default_attributes  { $_[0]->{'default_attributes' } = $_[1] if defined $_[1]; return $_[0]->{'default_attributes' };}
sub env_run_lists       { $_[0]->{'env_run_lists'      } = $_[1] if defined $_[1]; return $_[0]->{'env_run_lists'      };}
sub run_list            { $_[0]->{'run_list'           } = $_[1] if defined $_[1]; return $_[0]->{'run_list'           };}
sub url                 { $_[0]->{'url'                } = $_[1] if defined $_[1]; return $_[0]->{'url'                };}  
sub name                { $_[0]->{'name'               } = $_[1] if defined $_[1]; return $_[0]->{'name'               };}
sub description         { $_[0]->{'description'        } = $_[1] if defined $_[1]; return $_[0]->{'descripton'         };}

1;


=pod

=head1 NAME 

Chef::REST::Client::role

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::role;

my $obj = new Chef::REST::Client::role( %params );
   $obj->name
   $obj->url
   $obj->run_list
   $obj->description
   $obj->override_attributes
   $obj->default_attributes
   $obj->env_run_lists
  
=head1 DESCRIPTION

Class that represents chef role

=head1 METHODS

=head2 Constructor

return new L<Chef::REST::Client::role> object.

=head2 name ( $name )

set or get name property

=head2 url ( $url )

set or get url property

=head2 run_list ( $run_list )

set or get run_list property

=head2 description ( $description )

set or get description property

=head2 override_attributes ( $override_attributes )

set or get override_attributes property

=head2 default ( $default_attributes )

set or get default_attributes property

=head2 env_run_lists ( $env_run_lists )

set or get env_run_lists property

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <mail4bhavin@yahoo.com>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut

lib/Chef/REST/Client/roles.pm  view on Meta::CPAN

#--------------------------------------------------------------------#
# @class  : Chef::Rest::Client::roles                                #
# @author : Bhavin Patel                                             #
#--------------------------------------------------------------------#

package Chef::REST::Client::roles;

use parent qw { Chef::REST::Client::EndPoints };
use Chef::REST::Client::role;
use Chef::REST::Client::runlist;
use Chef::REST::Client::envrunlist;
use Chef::REST::Client::attributes;

$Chef::REST::Client::roles::VERSION = 1.0;

# this module will be passed tha json parsed hash 
# under ___data__() or variable.
# process it depending on the content expected.

sub list 
{
    my $self = shift;
    my $list_of_roles = $self->___data___;
	 return undef if $self->___data___->{'chef_type'};
	#return $self->___data___;
	
    foreach my $r ( keys(%$list_of_roles) ){
      my $role = new Chef::REST::Client::role
      				( 
      					'name' => $r,  
                     'url'  => $list_of_roles->{$r},
                  );
                  
      push @{'___roles_list___'} , $role;
    }
    return @{'___roles_list___'};
}

sub details
{
  my $self = shift;
  my $data = $self->___data___;

  return $self->raw() unless ref $data eq 'HASH';
  
  return new Chef::REST::Client::role(
  				'name'                => $data->{'name'},
  				'run_list'            => new Chef::REST::Client::runlist( $data->{'run_list'} ), #convert it to class
  				'env_run_lists'       => [map { 
  				                            new Chef::REST::Client::envrunlist( 
  				                                     env_name => $_,
  				                                     run_list => new Chef::REST::Client::runlist(
  				                                     					$data->{'env_run_lists'}->{$_}
  				                                     				 )	
  				                                )
  				                             } keys( %{ $data->{'env_run_lists'} } ) ], #convert it to class
  				'description'         => $data->{'description'},
  				'default_attributes'  => new Chef::REST::Client::attributes($data->{'default_attributes'}),
  				'override_attributes' => new Chef::REST::Client::attributes($data->{'override_attributes'}),
  			);

}
  
1;

=pod

=head1 NAME 

Chef::REST::Client::roles

=head1 VERSION

1.0

=head1 SYNOPSIS

use Chef::REST::Client::roles;

$obj->roles->list;
$obj->roles( 'devserver-role' )->details;
  
=head1 DESCRIPTION

Class that represents collection of roles 

=head1 METHODS

=head2 list

return list of roles, array of L<Chef::REST::Client::roles> objects.

=head2 details

return details about a particular role. or dump raw hash.

=head1 KNOWN BUGS

=head1 SUPPORT

open a github ticket or email comments to Bhavin Patel <mail4bhavin@yahoo.com>

=head1 COPYRIGHT AND LICENSE

This Software is free to use , licensed under : The Artisic License 2.0 (GPL Compatible)

=cut



( run in 0.819 second using v1.01-cache-2.11-cpan-172d661cebc )