API-Docker

 view release on metacpan or  search on metacpan

lib/API/Docker.pm  view on Meta::CPAN

use API::Docker::API::Secrets;
use API::Docker::API::Configs;
use API::Docker::API::Plugins;
use namespace::clean;


has host => (
  is      => 'ro',
  default => sub { $ENV{DOCKER_HOST} // 'unix:///var/run/docker.sock' },
);


has api_version => (
  is      => 'rwp',
  default => undef,
);


has tls => (
  is => 'lazy',
);

sub _build_tls {
  my ($self) = @_;

  # The docker CLI's own rule, read off cli/flags/options.go:
  #   dockerTLSVerify = os.Getenv(client.EnvTLSVerify) != ""
  # Every non-empty value turns TLS on, DOCKER_TLS_VERIFY=0 included. Perl
  # truthiness would read that '0' as off and disagree with the CLI on exactly
  # the value a user is most likely to type for "off", so the test is
  # defined-and-not-empty rather than a boolean one.
  return 0 unless defined $ENV{DOCKER_TLS_VERIFY}
    && $ENV{DOCKER_TLS_VERIFY} ne '';

  # And the CLI ignores TLS on a socket host without saying so
  # (cli/context/docker/load.go, "there's no need to configure TLS for a
  # socket connection"). Ignoring it here is not politeness: BUILD croaks on
  # tls => 1 with a non-tcp:// host, so a host-blind default would make a bare
  # API::Docker->new die on every unix:// machine that exports the variable.
  return $self->host =~ m{^tcp://} ? 1 : 0;
}


has cert_path => (
  is      => 'ro',
  default => sub { $ENV{DOCKER_CERT_PATH} },
);


has tls_insecure => (
  is      => 'ro',
  default => 0,
);


sub BUILD {
  my ($self) = @_;

  # Both checks are here rather than at connect time so that a request for
  # encryption that cannot be honoured is refused before the caller has a
  # client to hand credentials to.
  croak __PACKAGE__ . '->new tls_insecure => 1 without tls => 1 does '
    . 'nothing: verification is only reachable on a connection that has TLS '
    . 'to verify. Set tls => 1 as well, or drop the option'
    if $self->tls_insecure && !$self->tls;

  return unless $self->tls;

  my $host = $self->host;
  croak __PACKAGE__ . '->new tls => 1 is only meaningful for a tcp:// host, '
    . 'and this one is ' . $host . '. A Unix socket is a file rather than a '
    . 'wire and carries nothing to encrypt, so honouring the option is not '
    . 'possible and ignoring it would answer a request for an encrypted '
    . 'transport with an unencrypted one'
    unless $host =~ m{^tcp://};
}

has _version_negotiated => (
  is      => 'rw',
  default => 0,
);

with 'API::Docker::Role::HTTP';

has system => (
  is      => 'lazy',
  builder => sub { API::Docker::API::System->new(client => $_[0]) },
);


has containers => (
  is      => 'lazy',
  builder => sub { API::Docker::API::Containers->new(client => $_[0]) },
);


has images => (
  is      => 'lazy',
  builder => sub { API::Docker::API::Images->new(client => $_[0]) },
);


has networks => (
  is      => 'lazy',
  builder => sub { API::Docker::API::Networks->new(client => $_[0]) },
);


has volumes => (
  is      => 'lazy',
  builder => sub { API::Docker::API::Volumes->new(client => $_[0]) },
);


has exec => (
  is      => 'lazy',
  builder => sub { API::Docker::API::Exec->new(client => $_[0]) },
);


has distribution => (

lib/API/Docker.pm  view on Meta::CPAN

passed to the constructor outranks the variable in both directions.

The variable is B<ignored on a socket host>, as the CLI ignores it -- a
C<unix://>, C<npipe://> or C<fd://> connection carries nothing to encrypt.
Without that exception a shell exporting C<DOCKER_TLS_VERIFY> would make a bare
C<< API::Docker->new >> croak on every machine talking to a local socket, since
C<< tls => 1 >> on a non-C<tcp://> host is a construction error (below).

C<DOCKER_TLS_VERIFY> with no L</cert_path> and no C<DOCKER_CERT_PATH> beside it
is TLS against the system trust store, not an error; the CLI asks for no
certificates either, and non-empty there means encrypt B<and> verify.

With C<< tls => 1 >> the transport opens an L<IO::Socket::SSL> connection
instead of an L<IO::Socket::INET> one and nothing above the socket changes.
The daemon's certificate is B<verified>, and so is its hostname; L</cert_path>
supplies the trust anchor and this client's own certificate.

With no certificates at all it still means encrypt and verify, against the
system trust store -- see
L<API::Docker::Role::HTTP/"TLS with no certificates at all">
for why that rather than an error. To switch verification off, and to read
what that gives away, see L</tls_insecure>.

C<< tls => 1 >> on a C<unix://> host croaks at construction. A Unix socket is
a file, not a wire; there is nothing on it to encrypt, and accepting the
option would mean answering a request for an encrypted transport with an
unencrypted one -- which is the failure this attribute previously had.

L<IO::Socket::SSL> is a recommended rather than a required dependency, loaded
when the first TLS connection is opened; C<< tls => 1 >> without it installed
croaks naming it. See
L<API::Docker::Role::HTTP/"TLS on a tcp:// connection"> for the whole of the
policy.

=head2 cert_path

Directory holding the TLS certificates, in the layout the C<docker> CLI
writes: F<ca.pem> as the trust anchor, F<cert.pem> and F<key.pem> as this
client's certificate and key. Defaults to C<$ENV{DOCKER_CERT_PATH}>.

Each file is used if it is there. F<ca.pem> alone is a daemon this client
verifies but does not authenticate to; F<cert.pem> without F<key.pem> or the
reverse is a croak, since half a client certificate is an accident rather than
a mode. A C<cert_path> naming something that is not a directory croaks too.

B<Read only when L</tls> is set.> The default comes from the environment, and
C<DOCKER_CERT_PATH> is exported on plenty of machines that run the C<docker>
CLI, so a client that never asked for TLS is unaffected by having it set. A
TLS client that wants the system trust store rather than the CLI's private one
on such a machine passes C<< cert_path => undef >> explicitly.

=head2 tls_insecure

Turn certificate verification off. Default C<0>. Only read when L</tls> is
set, and named for what it does.

C<< tls_insecure => 1 >> sets C<SSL_VERIFY_NONE> and drops the hostname check,
which leaves a connection encrypted against a passive listener and against
nothing else: whoever answers it chooses the certificate, so anyone able to
redirect the connection reads and rewrites everything on it -- registry
credentials, image contents, the commands containers are started with.

It exists for a self-signed daemon certificate whose CA is not to hand. The
better answer is nearly always L</cert_path>: a self-signed certificate is its
own CA and works as F<ca.pem> directly.

Setting it without L</tls> croaks, rather than being accepted and doing
nothing.

=head2 system

Returns L<API::Docker::API::System> instance for system operations like
C<info>, C<version>, C<ping>, and C<events>.

=head2 containers

Returns L<API::Docker::API::Containers> instance for container operations like
C<list>, C<create>, C<start>, C<stop>, and C<remove>.

=head2 images

Returns L<API::Docker::API::Images> instance for image operations like
C<list>, C<pull>, C<push>, and C<remove>.

=head2 networks

Returns L<API::Docker::API::Networks> instance for network operations like
C<list>, C<create>, C<connect>, and C<disconnect>.

=head2 volumes

Returns L<API::Docker::API::Volumes> instance for volume operations like
C<list>, C<create>, and C<remove>.

=head2 exec

Returns L<API::Docker::API::Exec> instance for executing commands in containers.

=head2 distribution

Returns L<API::Docker::API::Distribution> instance for registry manifest
lookups: C<inspect> and C<exists>.

=head2 secrets

Returns L<API::Docker::API::Secrets> instance for secret operations: C<list>,
C<create>, C<inspect>, C<update> and C<remove>.

=head2 configs

Returns L<API::Docker::API::Configs> instance for config operations: C<list>,
C<create>, C<inspect>, C<update> and C<remove>.

=head2 plugins

Returns L<API::Docker::API::Plugins> instance for managed-plugin operations:
C<list>, C<privileges>, C<install>, C<inspect>, C<remove>, C<enable>,
C<disable>, C<upgrade>, C<push> and C<configure>.

=head2 negotiate_version



( run in 0.986 second using v1.01-cache-2.11-cpan-007c89162af )