package RackMan::Format::LDAP;

use strict;
use Carp;
use NetAddr::IP;
use RackMan::File;


use constant {
    CONFIG_SECTION  => "format:ldap",
    DEFAULT_PATH    => "/etc/ldap/hosts",
};


#
# write()
# -----
sub write {
    my ($class, $args) = @_;

    my $rackdev = $args->{rackdev};
    my $rackman = $args->{rackman};
    my $config  = RackMan::File->new;
    my $name    = $rackdev->object_name;

    # generate the config
    $config->add_content(make_ldif($rackdev));

    # write the configuration on disk
    $config->name("$name.ldif");
    $config->path($rackman->config->val(CONFIG_SECTION, "path", DEFAULT_PATH));
    print "  + writing ", $config->fullpath, $/ if $args->{verbose};
    my $scm = $rackman->get_scm({ path => $config->path });
    $scm->update;
    $config->write;
    $scm->add($config->name);
    $scm->commit($config->name, "generated by $class / $::PROGRAM v$::VERSION");
}


#
# make_ldif()
# ---------
sub make_ldif {
    my ($rackdev) = @_;

    my $name    = $rackdev->object_name;

    # find the first MAC address of the device, excluding the iLO
    my @mac_addrs = $rackdev->regular_mac_addrs;
    RackMan->error("RackObject '$name' lacks a MAC address") unless @mac_addrs;

    # find the first IP address of the device, excluding the iLO
    my @ip_addrs = $rackdev->regular_ipv4addrs;
    RackMan->error("RackObject '$name' lacks an IPv4 address") unless @ip_addrs;

    # find the defaut IPv4 gateway
    my $gateway = $rackdev->default_ipv4_gateway;

    # determine the network mask
    my $addr = NetAddr::IP->new($ip_addrs[0]{addr}, $gateway->{masklen});
    my $netmask = $addr->mask;

    # fetch the base DN
    my $base_dn = $rackdev->rackman->config->val(CONFIG_SECTION, "base_dn", "");
    $base_dn = ",$base_dn" if $base_dn;

    # construct the LDIF
    my $ldif = join "",
        "dn: cn=$name$base_dn\n",
        "cn: $name\n",
        "macAddress: $mac_addrs[0]{l2address_text}\n",
        "ipHostNumber: $ip_addrs[0]{addr}\n",
        "ipNetmaskNumber: $netmask\n",
        "description: " . lc($rackdev->object_type) . " "
            . $rackdev->attributes->{"HW type"} . "\n",
        "objectClass: top\n",
        "objectClass: goServer\n";

    return $ldif
}


__PACKAGE__

__END__

=pod

=head1 NAME

RackMan::Format::LDAP - Generate the LDAP definition for a given RackObject

=head1 SYNOPSIS

    use RackMan::Format::LDAP;

    RackMan::Format::LDAP->write({
        rackdev => $rackdev,  # a RackMan::Device instance
        rackman => $rackman,  # a RackMan instance
    });


=head1 DESCRIPTION

This module generates a LDAP definition file (LDIF) to import basic
information about the given RackObject in GOsa2.


=head1 METHODS

=head2 write

Generate the file.

B<Arguments>

Arguments are expected as a hashref with the following keys:

=over

=item *

C<rackdev> - I<(mandatory)> a RackMan::Device instance

=item *

C<rackman> - I<(mandatory)> a RackMan instance

=item *

C<verbose> - I<(optional)> boolean, set to true to be verbose

=back


=head1 FUNCTIONS

=head2 make_ldif

Generate the LDIF content of the given C<RackMan::Device>

B<Arguments>

=over

=item 1. a C<RackMan::Device> object

=back

B<Example:>

    my $ldif = make_ldif($rackdev);


=head1 CONFIGURATION

This module gets its configuration from the C<[format:ldap]> section
of the main F<rack.conf>, with the following parameters:

=head2 path

Path of the directory to store the generated files.


=head2 base_dn

Base DN to create the canonical name of the object

    base_dn = ou=servers,ou=systems,dc=company,dc=com


=head2 scm

Specify the SCM tool to use for versionning generated files.


=head1 AUTHOR

Sebastien Aperghis-Tramoni

=cut

