kubeconfig module
This commit is contained in:
2
cpanfile
2
cpanfile
@@ -1,5 +1,6 @@
|
||||
requires 'Carp';
|
||||
requires 'JSON';
|
||||
requires 'YAML::XS';
|
||||
requires 'DateTime';
|
||||
requires 'Log::Any';
|
||||
requires 'Module::Runtime';
|
||||
@@ -8,6 +9,7 @@ requires 'Module::Find';
|
||||
requires 'LWP::UserAgent';
|
||||
requires 'LWP::Protocol::https';
|
||||
requires 'Class::Accessor';
|
||||
requires 'MIME::Base64';
|
||||
|
||||
on 'test' => sub {
|
||||
requires 'Test::Simple';
|
||||
|
||||
24
examples/load_kubeconfig.pl
Normal file
24
examples/load_kubeconfig.pl
Normal file
@@ -0,0 +1,24 @@
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
|
||||
use Kubernetes::Util::KubeConfig;
|
||||
|
||||
use Log::Any::Adapter ('Stdout');
|
||||
use Log::Any::Adapter ('Stderr');
|
||||
|
||||
use Net::SSLeay;
|
||||
$Net::SSLeay::trace = 2;
|
||||
|
||||
my $kubeconfig = Kubernetes::Util::KubeConfig->load_yaml_file();
|
||||
|
||||
my $api_factory = $kubeconfig->new_api_factory();
|
||||
|
||||
my $corev1_api = $api_factory->get_api('CoreV1');
|
||||
|
||||
my $namespaceList = $corev1_api->list_namespace();
|
||||
|
||||
printf "found %d namespaces:\n", scalar @{$namespaceList->items};
|
||||
printf "=====================\n";
|
||||
foreach my $namespace (@{$namespaceList->items}) {
|
||||
printf "%s\n", $namespace->metadata->name;
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
my $api_factory = Kubernetes::ApiFactory->new(
|
||||
'base_url' => 'https://127.0.0.1:6443',
|
||||
'ssl_opts' => {
|
||||
# Disabling server ca validation
|
||||
# SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE,
|
||||
# verify_hostname => 0,
|
||||
|
||||
SSL_use_cert => 1,
|
||||
SSL_ca_file => "/path/to/ca",
|
||||
SSL_cert_file => "/path/to/cert",
|
||||
SSL_key_file => "/path/to/key",
|
||||
},
|
||||
);
|
||||
|
||||
my $corev1_api = $api_factory->get_api('CoreV1');
|
||||
|
||||
my $namespaceList = $corev1_api->list_namespace();
|
||||
|
||||
printf "found %d namespaces:\n", scalar @{$namespaceList->items};
|
||||
printf "=====================\n", length @{$namespaceList->items};
|
||||
foreach my $namespace (@{$namespaceList->items}) {
|
||||
printf "%s\n", $namespace->metadata->name;
|
||||
}
|
||||
130
lib/Kubernetes/Util/KubeConfig.pm
Normal file
130
lib/Kubernetes/Util/KubeConfig.pm
Normal file
@@ -0,0 +1,130 @@
|
||||
package Kubernetes::Util::KubeConfig;
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use Carp;
|
||||
|
||||
use YAML::XS qw(Load LoadFile);
|
||||
use MIME::Base64;
|
||||
use Kubernetes::ApiClient;
|
||||
use Kubernetes::ApiFactory;
|
||||
use IO::Socket::SSL;
|
||||
use Log::Any qw($log);
|
||||
use IO::Socket::SSL::Utils;
|
||||
|
||||
use base 'Exporter';
|
||||
|
||||
our @EXPORT = qw(
|
||||
load_yaml_file
|
||||
load_yaml
|
||||
new_api_factory
|
||||
);
|
||||
|
||||
sub load_yaml_file {
|
||||
my ($self, $yaml_file_path) = @_;
|
||||
|
||||
if (not defined $yaml_file_path) {
|
||||
$log->debugf('Defaulting Kube-Config file path to $HOME/.kube/config');
|
||||
$yaml_file_path = $ENV{HOME} . '/.kube/config';
|
||||
}
|
||||
|
||||
die "$yaml_file_path doesn't exist!" if not -e $yaml_file_path;
|
||||
|
||||
my $kubeconfig = LoadFile($yaml_file_path);
|
||||
bless $kubeconfig => $self;
|
||||
|
||||
$kubeconfig->validate;
|
||||
|
||||
return $kubeconfig;
|
||||
}
|
||||
|
||||
sub load_yaml {
|
||||
my ($self, $yaml_str) = @_;
|
||||
|
||||
if (not defined $yaml_str) {
|
||||
return undef;
|
||||
}
|
||||
|
||||
my $kubeconfig = Load($yaml_str);
|
||||
bless $kubeconfig => $self;
|
||||
|
||||
$kubeconfig->validate;
|
||||
|
||||
return $kubeconfig;
|
||||
}
|
||||
|
||||
sub validate {
|
||||
my ($self) = @_;
|
||||
if (not defined $self->{apiVersion} || $self->{apiVersion} ne 'v1') {
|
||||
die "Invalid Kube-Config content: ('apiVersion' is not 'v1')";
|
||||
}
|
||||
if (not defined $self->{kind} || $self->{kind} ne 'Config') {
|
||||
die "Invalid Kube-Config content: ('kind' is not 'v1')";
|
||||
}
|
||||
if (not defined $self->{contexts}) {
|
||||
die "Invalid Kube-Config content: missing 'contexts' section";
|
||||
}
|
||||
if (not defined $self->{clusters}) {
|
||||
die "Invalid Kube-Config content: missing 'clusters' section";
|
||||
}
|
||||
if (not defined $self->{users}) {
|
||||
die "Invalid Kube-Config content: missing 'users' section";
|
||||
}
|
||||
if (not defined $self->{'current-context'}) {
|
||||
die "Invalid Kube-Config content: missing 'current-context' section";
|
||||
}
|
||||
}
|
||||
|
||||
sub new_api_factory {
|
||||
my ($self) = @_;
|
||||
|
||||
my $context_name = $self->{'current-context'};
|
||||
my $cluster_name;
|
||||
my $user_name;
|
||||
|
||||
foreach my $ctx (@{$self->{contexts}}) {
|
||||
if ($context_name eq $ctx->{name}) {
|
||||
$cluster_name = $ctx->{context}->{cluster};
|
||||
$user_name = $ctx->{context}->{user};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my $current_cluster;
|
||||
foreach my $cluster (@{$self->{clusters}}) {
|
||||
if ($cluster_name eq $cluster->{name}) {
|
||||
$current_cluster = $cluster;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
my $current_user;
|
||||
foreach my $user (@{$self->{users}}) {
|
||||
if ($user_name eq $user->{name}) {
|
||||
$current_user = $user;
|
||||
}
|
||||
}
|
||||
|
||||
my %ssl_opts;
|
||||
|
||||
my $skip_tls_verify = $current_cluster->{cluster}->{'insecure-skip-tls-verify'};
|
||||
|
||||
if (defined $skip_tls_verify && $skip_tls_verify == 1) {
|
||||
$ssl_opts{verify_hostname} = 0;
|
||||
$ssl_opts{SSL_verify_mode} = IO::Socket::SSL::SSL_VERIFY_NONE;
|
||||
} else {
|
||||
# print Dumper($current_cluster);
|
||||
$ssl_opts{SSL_ca} = [PEM_string2cert(decode_base64($current_cluster->{cluster}->{'certificate-authority-data'}))];
|
||||
$ssl_opts{SSL_use_cert} = 1;
|
||||
}
|
||||
|
||||
$ssl_opts{SSL_cert} = PEM_string2cert(decode_base64($current_user->{user}->{'client-certificate-data'}));
|
||||
$ssl_opts{SSL_key} = PEM_string2key(decode_base64($current_user->{user}->{'client-key-data'}));
|
||||
|
||||
return Kubernetes::ApiFactory->new(
|
||||
base_url => $current_cluster->{cluster}->{server},
|
||||
ssl_opts => \%ssl_opts,
|
||||
);
|
||||
}
|
||||
|
||||
1;
|
||||
Reference in New Issue
Block a user