Add remove action (#1503)
This commit is contained in:
parent
dd62d90de7
commit
1313350aec
|
@ -11,8 +11,13 @@ use XML::LibXML;
|
|||
# Get command line options
|
||||
#==============================================================================
|
||||
my %opts;
|
||||
my $result = GetOptions( \%opts, 'metadata|m=s', 'certificate|c=s', 'verbose|v',
|
||||
'help|h', 'spconfprefix|s=s', 'idpconfprefix|i=s', 'warning|w' );
|
||||
my $result = GetOptions(
|
||||
\%opts, 'metadata|m=s',
|
||||
'certificate|c=s', 'verbose|v',
|
||||
'help|h', 'spconfprefix|s=s',
|
||||
'idpconfprefix|i=s', 'warning|w',
|
||||
'remove|r'
|
||||
);
|
||||
|
||||
#==============================================================================
|
||||
# Help
|
||||
|
@ -38,7 +43,7 @@ if ( $opts{help} or !$opts{metadata} ) {
|
|||
# Default values
|
||||
#==============================================================================
|
||||
|
||||
my $spConfKeyPrefix = $opts{spconfprefix} || "sp-";
|
||||
my $spConfKeyPrefix = $opts{spconfprefix} || "sp-";
|
||||
my $idpConfKeyPrefix = $opts{idpconfprefix} || "idp-";
|
||||
|
||||
# Set here attributes that are declared for your SP in the federation
|
||||
|
@ -91,9 +96,20 @@ my $idpOptions = {
|
|||
'samlIDPMetaDataOptionsStoreSAMLToken' => 0
|
||||
};
|
||||
|
||||
my $idpCounter =
|
||||
{ 'found' => 0, 'updated' => 0, 'created' => 0, rejected => 0 };
|
||||
my $spCounter = { 'found' => 0, 'updated' => 0, 'created' => 0, rejected => 0 };
|
||||
my $idpCounter = {
|
||||
'found' => 0,
|
||||
'updated' => 0,
|
||||
'created' => 0,
|
||||
'rejected' => 0,
|
||||
'removed' => 0
|
||||
};
|
||||
my $spCounter = {
|
||||
'found' => 0,
|
||||
'updated' => 0,
|
||||
'created' => 0,
|
||||
'rejected' => 0,
|
||||
'removed' => 0
|
||||
};
|
||||
|
||||
#==============================================================================
|
||||
# Main
|
||||
|
@ -106,17 +122,18 @@ if ( $opts{verbose} ) {
|
|||
}
|
||||
|
||||
# IDP and SP lists
|
||||
my $idpList;
|
||||
my $spList;
|
||||
my ( $idpList, $spList, $mdIdpList, $mdSpList );
|
||||
|
||||
# List current SAML partners
|
||||
foreach my $spConfKey ( keys %{ $lastConf->{samlSPMetaDataXML} } ) {
|
||||
my ( $tmp, $entityID ) =
|
||||
( $lastConf->{samlSPMetaDataXML}->{$spConfKey}->{samlSPMetaDataXML} =~
|
||||
/entityID=(['"])(.+?)\1/si );
|
||||
$spList->{$entityID} = $spConfKey;
|
||||
if ( $opts{verbose} ) {
|
||||
print "Existing SAML partner found: [SP] $entityID ($spConfKey)\n";
|
||||
if ( $spConfKey =~ /^$spConfKeyPrefix/ ) {
|
||||
$spList->{$entityID} = $spConfKey;
|
||||
if ( $opts{verbose} ) {
|
||||
print "Existing SAML partner found: [SP] $entityID ($spConfKey)\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,255 +141,293 @@ foreach my $idpConfKey ( keys %{ $lastConf->{samlIDPMetaDataXML} } ) {
|
|||
my ( $tmp, $entityID ) =
|
||||
( $lastConf->{samlIDPMetaDataXML}->{$idpConfKey}->{samlIDPMetaDataXML} =~
|
||||
/entityID=(['"])(.+?)\1/si );
|
||||
$idpList->{$entityID} = $idpConfKey;
|
||||
if ( $opts{verbose} ) {
|
||||
print "Existing SAML partner found: [IDP] $entityID ($idpConfKey)\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Download metadata file
|
||||
my $ua = LWP::UserAgent->new;
|
||||
$ua->timeout(10);
|
||||
$ua->env_proxy;
|
||||
|
||||
my $metadata_file = $opts{metadata};
|
||||
|
||||
if ( $opts{verbose} ) {
|
||||
print "Try to download metadata file at $metadata_file\n";
|
||||
}
|
||||
my $response = $ua->get($metadata_file);
|
||||
|
||||
if ( $response->is_success ) {
|
||||
if ( $opts{verbose} ) {
|
||||
print "Metadata file found\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
die $response->status_line;
|
||||
}
|
||||
|
||||
my $dom = XML::LibXML->load_xml( string => $response->decoded_content );
|
||||
|
||||
# Check file signature
|
||||
if ( $opts{certificate} ) {
|
||||
my $certificate_file = $opts{certificate};
|
||||
if ( $opts{verbose} ) {
|
||||
print "Try to download certificate file at $certificate_file\n";
|
||||
}
|
||||
my $cert_response = $ua->get($certificate_file);
|
||||
|
||||
if ( $cert_response->is_success ) {
|
||||
if ( $idpConfKey =~ /^$idpConfKeyPrefix/ ) {
|
||||
$idpList->{$entityID} = $idpConfKey;
|
||||
if ( $opts{verbose} ) {
|
||||
print "Certificate file found:\n"
|
||||
. $cert_response->decoded_content . "\n";
|
||||
print
|
||||
"Existing SAML partner found: [IDP] $entityID ($idpConfKey)\n";
|
||||
}
|
||||
}
|
||||
|
||||
# Download metadata file
|
||||
my $ua = LWP::UserAgent->new;
|
||||
$ua->timeout(10);
|
||||
$ua->env_proxy;
|
||||
|
||||
my $metadata_file = $opts{metadata};
|
||||
|
||||
if ( $opts{verbose} ) {
|
||||
print "Try to download metadata file at $metadata_file\n";
|
||||
}
|
||||
my $response = $ua->get($metadata_file);
|
||||
|
||||
if ( $response->is_success ) {
|
||||
if ( $opts{verbose} ) {
|
||||
print "Metadata file found\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
die $cert_response->status_line;
|
||||
die $response->status_line;
|
||||
}
|
||||
|
||||
if ( $opts{verbose} ) {
|
||||
print "Check metadata signature with certificate";
|
||||
}
|
||||
my $dom = XML::LibXML->load_xml( string => $response->decoded_content );
|
||||
|
||||
# TODO
|
||||
print STDERR "[WARN] Signature verification not yet implemented\n"
|
||||
if $opts{warning};
|
||||
}
|
||||
# Check file signature
|
||||
if ( $opts{certificate} ) {
|
||||
my $certificate_file = $opts{certificate};
|
||||
if ( $opts{verbose} ) {
|
||||
print "Try to download certificate file at $certificate_file\n";
|
||||
}
|
||||
my $cert_response = $ua->get($certificate_file);
|
||||
|
||||
# Remove extensions
|
||||
foreach ( $dom->findnodes('//md:Extensions') ) { $_->unbindNode; }
|
||||
|
||||
# Browse all partners
|
||||
foreach
|
||||
my $partner ( $dom->findnodes('/md:EntitiesDescriptor/md:EntityDescriptor') )
|
||||
{
|
||||
my $entityID = $partner->getAttribute('entityID');
|
||||
|
||||
# Add required XML namespaces
|
||||
$partner->setNamespace( "urn:oasis:names:tc:SAML:2.0:metadata", "md", 0 );
|
||||
$partner->setNamespace( "urn:oasis:names:tc:SAML:2.0:assertion", "saml",
|
||||
0 );
|
||||
$partner->setNamespace( "http://www.w3.org/2000/09/xmldsig#", "ds", 0 );
|
||||
|
||||
# Check IDP or SP
|
||||
if ( my $idp = $partner->findnodes('./md:IDPSSODescriptor') ) {
|
||||
$idpCounter->{found}++;
|
||||
|
||||
# Check if SAML 2.0 is supported
|
||||
if (
|
||||
$partner->findnodes(
|
||||
'./md:IDPSSODescriptor/md:SingleSignOnService[contains(@Binding,"urn:oasis:names:tc:SAML:2.0:")]'
|
||||
)
|
||||
)
|
||||
{
|
||||
|
||||
# Read metadata
|
||||
my $partner_metadata = $partner->toString;
|
||||
$partner_metadata =~ s/\n//g;
|
||||
|
||||
# Check if entityID already in configuration
|
||||
if ( defined $idpList->{$entityID} ) {
|
||||
|
||||
# Update metadata
|
||||
$lastConf->{samlIDPMetaDataXML}->{ $idpList->{$entityID} }
|
||||
->{samlIDPMetaDataXML} = $partner_metadata;
|
||||
|
||||
# Update attributes
|
||||
$lastConf->{samlIDPMetaDataExportedAttributes}
|
||||
->{ $idpList->{$entityID} } = $exportedAttributes;
|
||||
|
||||
# Update options
|
||||
$lastConf->{samlIDPMetaDataOptions}->{ $idpList->{$entityID} }
|
||||
= $idpOptions;
|
||||
|
||||
if ( $opts{verbose} ) {
|
||||
print "Update IDP $entityID in configuration\n";
|
||||
}
|
||||
$idpCounter->{updated}++;
|
||||
if ( $cert_response->is_success ) {
|
||||
if ( $opts{verbose} ) {
|
||||
print "Certificate file found:\n"
|
||||
. $cert_response->decoded_content . "\n";
|
||||
}
|
||||
else {
|
||||
# Create a new partner
|
||||
my $confKey =
|
||||
$idpConfKeyPrefix . encode_base64( $entityID, '' );
|
||||
$confKey =~ s/=//g;
|
||||
|
||||
# Metadata
|
||||
$lastConf->{samlIDPMetaDataXML}->{$confKey}
|
||||
->{samlIDPMetaDataXML} = $partner_metadata;
|
||||
|
||||
# Attributes
|
||||
$lastConf->{samlIDPMetaDataExportedAttributes}->{$confKey} =
|
||||
$exportedAttributes;
|
||||
|
||||
# Options
|
||||
$lastConf->{samlIDPMetaDataOptions}->{$confKey} = $idpOptions;
|
||||
|
||||
if ( $opts{verbose} ) {
|
||||
print
|
||||
"Declare new IDP $entityID (configuration key $confKey)\n";
|
||||
}
|
||||
$idpCounter->{created}++;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
print STDERR
|
||||
"[WARN] IDP $entityID is not compatible with SAML 2.0, it will not be imported.\n"
|
||||
if $opts{warning};
|
||||
$idpCounter->{rejected}++;
|
||||
die $cert_response->status_line;
|
||||
}
|
||||
|
||||
if ( $opts{verbose} ) {
|
||||
print "Check metadata signature with certificate";
|
||||
}
|
||||
|
||||
# TODO
|
||||
print STDERR "[WARN] Signature verification not yet implemented\n"
|
||||
if $opts{warning};
|
||||
}
|
||||
if ( my $sp = $partner->findnodes('./md:SPSSODescriptor') ) {
|
||||
|
||||
$spCounter->{found}++;
|
||||
# Remove extensions
|
||||
foreach ( $dom->findnodes('//md:Extensions') ) { $_->unbindNode; }
|
||||
|
||||
# Check if SAML 2.0 is supported
|
||||
if (
|
||||
$partner->findnodes(
|
||||
'./md:SPSSODescriptor/md:AssertionConsumerService[contains(@Binding,"urn:oasis:names:tc:SAML:2.0:")]'
|
||||
)
|
||||
)
|
||||
{
|
||||
# Browse all partners
|
||||
foreach my $partner (
|
||||
$dom->findnodes('/md:EntitiesDescriptor/md:EntityDescriptor') )
|
||||
{
|
||||
my $entityID = $partner->getAttribute('entityID');
|
||||
|
||||
# Read requested attributes
|
||||
my $requestedAttributes = {};
|
||||
# Add required XML namespaces
|
||||
$partner->setNamespace( "urn:oasis:names:tc:SAML:2.0:metadata",
|
||||
"md", 0 );
|
||||
$partner->setNamespace( "urn:oasis:names:tc:SAML:2.0:assertion",
|
||||
"saml", 0 );
|
||||
$partner->setNamespace( "http://www.w3.org/2000/09/xmldsig#", "ds", 0 );
|
||||
|
||||
# Check IDP or SP
|
||||
if ( my $idp = $partner->findnodes('./md:IDPSSODescriptor') ) {
|
||||
$idpCounter->{found}++;
|
||||
$mdIdpList->{$entityID} = 1;
|
||||
|
||||
# Check if SAML 2.0 is supported
|
||||
if (
|
||||
$partner->findnodes(
|
||||
'./md:SPSSODescriptor/md:AttributeConsumingService/md:RequestedAttribute'
|
||||
'./md:IDPSSODescriptor/md:SingleSignOnService[contains(@Binding,"urn:oasis:names:tc:SAML:2.0:")]'
|
||||
)
|
||||
)
|
||||
{
|
||||
foreach my $requestedAttribute (
|
||||
|
||||
# Read metadata
|
||||
my $partner_metadata = $partner->toString;
|
||||
$partner_metadata =~ s/\n//g;
|
||||
|
||||
# Check if entityID already in configuration
|
||||
if ( defined $idpList->{$entityID} ) {
|
||||
|
||||
# Update metadata
|
||||
$lastConf->{samlIDPMetaDataXML}->{ $idpList->{$entityID} }
|
||||
->{samlIDPMetaDataXML} = $partner_metadata;
|
||||
|
||||
# Update attributes
|
||||
$lastConf->{samlIDPMetaDataExportedAttributes}
|
||||
->{ $idpList->{$entityID} } = $exportedAttributes;
|
||||
|
||||
# Update options
|
||||
$lastConf->{samlIDPMetaDataOptions}
|
||||
->{ $idpList->{$entityID} } = $idpOptions;
|
||||
|
||||
if ( $opts{verbose} ) {
|
||||
print "Update IDP $entityID in configuration\n";
|
||||
}
|
||||
$idpCounter->{updated}++;
|
||||
}
|
||||
else {
|
||||
# Create a new partner
|
||||
my $confKey =
|
||||
$idpConfKeyPrefix . encode_base64( $entityID, '' );
|
||||
$confKey =~ s/=//g;
|
||||
|
||||
# Metadata
|
||||
$lastConf->{samlIDPMetaDataXML}->{$confKey}
|
||||
->{samlIDPMetaDataXML} = $partner_metadata;
|
||||
|
||||
# Attributes
|
||||
$lastConf->{samlIDPMetaDataExportedAttributes}->{$confKey}
|
||||
= $exportedAttributes;
|
||||
|
||||
# Options
|
||||
$lastConf->{samlIDPMetaDataOptions}->{$confKey} =
|
||||
$idpOptions;
|
||||
|
||||
if ( $opts{verbose} ) {
|
||||
print
|
||||
"Declare new IDP $entityID (configuration key $confKey)\n";
|
||||
}
|
||||
$idpCounter->{created}++;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
print STDERR
|
||||
"[WARN] IDP $entityID is not compatible with SAML 2.0, it will not be imported.\n"
|
||||
if $opts{warning};
|
||||
$idpCounter->{rejected}++;
|
||||
}
|
||||
}
|
||||
if ( my $sp = $partner->findnodes('./md:SPSSODescriptor') ) {
|
||||
$spCounter->{found}++;
|
||||
$mdSpList->{$entityID} = 1;
|
||||
|
||||
# Check if SAML 2.0 is supported
|
||||
if (
|
||||
$partner->findnodes(
|
||||
'./md:SPSSODescriptor/md:AssertionConsumerService[contains(@Binding,"urn:oasis:names:tc:SAML:2.0:")]'
|
||||
)
|
||||
)
|
||||
{
|
||||
|
||||
# Read requested attributes
|
||||
my $requestedAttributes = {};
|
||||
if (
|
||||
$partner->findnodes(
|
||||
'./md:SPSSODescriptor/md:AttributeConsumingService/md:RequestedAttribute'
|
||||
)
|
||||
)
|
||||
{
|
||||
my $name = $requestedAttribute->getAttribute("Name");
|
||||
my $friendlyname =
|
||||
$requestedAttribute->getAttribute("FriendlyName");
|
||||
my $nameformat =
|
||||
$requestedAttribute->getAttribute("NameFormat");
|
||||
$requestedAttributes->{$friendlyname} =
|
||||
"1;$name;$nameformat;$friendlyname";
|
||||
if ( $opts{verbose} ) {
|
||||
print
|
||||
foreach my $requestedAttribute (
|
||||
$partner->findnodes(
|
||||
'./md:SPSSODescriptor/md:AttributeConsumingService/md:RequestedAttribute'
|
||||
)
|
||||
)
|
||||
{
|
||||
my $name = $requestedAttribute->getAttribute("Name");
|
||||
my $friendlyname =
|
||||
$requestedAttribute->getAttribute("FriendlyName");
|
||||
my $nameformat =
|
||||
$requestedAttribute->getAttribute("NameFormat");
|
||||
$requestedAttributes->{$friendlyname} =
|
||||
"1;$name;$nameformat;$friendlyname";
|
||||
if ( $opts{verbose} ) {
|
||||
print
|
||||
"Attribute $friendlyname ($name) requested by SP $entityID\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
$requestedAttributes =
|
||||
{ 'cn' => '1;cn', 'uid' => '1;uid', 'mail' => '1;mail' };
|
||||
}
|
||||
|
||||
# Remove AttributeConsumingService node
|
||||
foreach (
|
||||
$partner->findnodes(
|
||||
'./md:SPSSODescriptor/md:AttributeConsumingService')
|
||||
)
|
||||
{
|
||||
$_->unbindNode;
|
||||
}
|
||||
|
||||
# Read metadata
|
||||
my $partner_metadata = $partner->toString;
|
||||
$partner_metadata =~ s/\n//g;
|
||||
|
||||
# Check if entityID already in configuration
|
||||
if ( defined $spList->{$entityID} ) {
|
||||
|
||||
# Update metadata
|
||||
$lastConf->{samlSPMetaDataXML}->{ $spList->{$entityID} }
|
||||
->{samlSPMetaDataXML} = $partner_metadata;
|
||||
|
||||
# Update attributes
|
||||
$lastConf->{samlSPMetaDataExportedAttributes}
|
||||
->{ $spList->{$entityID} } = $requestedAttributes;
|
||||
|
||||
# Update options
|
||||
$lastConf->{samlSPMetaDataOptions}->{ $spList->{$entityID} }
|
||||
= $spOptions;
|
||||
|
||||
if ( $opts{verbose} ) {
|
||||
print "Update SP $entityID in configuration\n";
|
||||
}
|
||||
$spCounter->{updated}++;
|
||||
}
|
||||
else {
|
||||
# Create a new partner
|
||||
my $confKey =
|
||||
$spConfKeyPrefix . encode_base64( $entityID, '' );
|
||||
$confKey =~ s/=//g;
|
||||
|
||||
# Metadata
|
||||
$lastConf->{samlSPMetaDataXML}->{$confKey}
|
||||
->{samlSPMetaDataXML} = $partner_metadata;
|
||||
|
||||
# Attributes
|
||||
$lastConf->{samlSPMetaDataExportedAttributes}->{$confKey} =
|
||||
$requestedAttributes;
|
||||
|
||||
# Options
|
||||
$lastConf->{samlSPMetaDataOptions}->{$confKey} = $spOptions;
|
||||
|
||||
if ( $opts{verbose} ) {
|
||||
print
|
||||
"Declare new SP $entityID (configuration key $confKey)\n";
|
||||
}
|
||||
$spCounter->{created}++;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
$requestedAttributes =
|
||||
{ 'cn' => '1;cn', 'uid' => '1;uid', 'mail' => '1;mail' };
|
||||
}
|
||||
|
||||
# Remove AttributeConsumingService node
|
||||
foreach (
|
||||
$partner->findnodes(
|
||||
'./md:SPSSODescriptor/md:AttributeConsumingService')
|
||||
)
|
||||
{
|
||||
$_->unbindNode;
|
||||
}
|
||||
|
||||
# Read metadata
|
||||
my $partner_metadata = $partner->toString;
|
||||
$partner_metadata =~ s/\n//g;
|
||||
|
||||
# Check if entityID already in configuration
|
||||
if ( defined $spList->{$entityID} ) {
|
||||
|
||||
# Update metadata
|
||||
$lastConf->{samlSPMetaDataXML}->{ $spList->{$entityID} }
|
||||
->{samlSPMetaDataXML} = $partner_metadata;
|
||||
|
||||
# Update attributes
|
||||
$lastConf->{samlSPMetaDataExportedAttributes}
|
||||
->{ $spList->{$entityID} } = $requestedAttributes;
|
||||
|
||||
# Update options
|
||||
$lastConf->{samlSPMetaDataOptions}->{ $spList->{$entityID} } =
|
||||
$spOptions;
|
||||
|
||||
if ( $opts{verbose} ) {
|
||||
print "Update SP $entityID in configuration\n";
|
||||
}
|
||||
$spCounter->{updated}++;
|
||||
}
|
||||
else {
|
||||
# Create a new partner
|
||||
my $confKey = $spConfKeyPrefix . encode_base64( $entityID, '' );
|
||||
$confKey =~ s/=//g;
|
||||
|
||||
# Metadata
|
||||
$lastConf->{samlSPMetaDataXML}->{$confKey}->{samlSPMetaDataXML}
|
||||
= $partner_metadata;
|
||||
|
||||
# Attributes
|
||||
$lastConf->{samlSPMetaDataExportedAttributes}->{$confKey} =
|
||||
$requestedAttributes;
|
||||
|
||||
# Options
|
||||
$lastConf->{samlSPMetaDataOptions}->{$confKey} = $spOptions;
|
||||
|
||||
if ( $opts{verbose} ) {
|
||||
print
|
||||
"Declare new SP $entityID (configuration key $confKey)\n";
|
||||
}
|
||||
$spCounter->{created}++;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
print STDERR
|
||||
print STDERR
|
||||
"[WARN] SP $entityID is not compatible with SAML 2.0, it will not be imported.\n"
|
||||
if $opts{warning};
|
||||
$spCounter->{rejected}++;
|
||||
if $opts{warning};
|
||||
$spCounter->{rejected}++;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Remove partners
|
||||
if ( $opts{remove} ) {
|
||||
foreach ( keys %$idpList ) {
|
||||
my $idpConfKey = $idpList->{$_};
|
||||
unless ( defined $mdIdpList->{$_} ) {
|
||||
delete $lastConf->{samlIDPMetaDataXML}->{$idpConfKey};
|
||||
delete $lastConf->{samlIDPMetaDataExportedAttributes}
|
||||
->{$idpConfKey};
|
||||
delete $lastConf->{samlIDPMetaDataOptions}->{$idpConfKey};
|
||||
$idpCounter->{removed}++;
|
||||
if ( $opts{verbose} ) {
|
||||
print "Remove IDP $idpConfKey\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( keys %$spList ) {
|
||||
my $spConfKey = $spList->{$_};
|
||||
unless ( defined $mdSpList->{$_} ) {
|
||||
delete $lastConf->{samlSPMetaDataXML}->{$spConfKey};
|
||||
delete $lastConf->{samlSPMetaDataExportedAttributes}
|
||||
->{$spConfKey};
|
||||
delete $lastConf->{samlSPMetaDataOptions}->{$spConfKey};
|
||||
$spCounter->{removed}++;
|
||||
if ( $opts{verbose} ) {
|
||||
print "Remove SP $spConfKey\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Register configuration
|
||||
|
@ -389,6 +444,8 @@ print "[IDP]\tFound: "
|
|||
. $idpCounter->{updated}
|
||||
. "\tCreated: "
|
||||
. $idpCounter->{created}
|
||||
. "\tRemoved: "
|
||||
. $idpCounter->{removed}
|
||||
. "\tRejected: "
|
||||
. $idpCounter->{rejected} . "\n";
|
||||
print "[SP]\tFound: "
|
||||
|
@ -397,6 +454,8 @@ print "[SP]\tFound: "
|
|||
. $spCounter->{updated}
|
||||
. "\tCreated: "
|
||||
. $spCounter->{created}
|
||||
. "\tRemoved: "
|
||||
. $spCounter->{removed}
|
||||
. "\tRejected: "
|
||||
. $spCounter->{rejected} . "\n";
|
||||
print "[OK] Configuration $numConf saved\n";
|
||||
|
|
Loading…
Reference in New Issue
Block a user