/************************************************************************* * Copyright 2009-2015 Eucalyptus Systems, Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * * Please contact Eucalyptus Systems, Inc., 6755 Hollister Ave., Goleta * CA 93117, USA or visit http://www.eucalyptus.com/licenses/ if you need * additional information or have any questions. ************************************************************************/ package com.eucalyptus.auth.euare.persist; import java.util.ServiceLoader; import java.util.Set; import org.apache.log4j.Logger; import com.eucalyptus.auth.AuthException; import com.eucalyptus.auth.PolicyParseException; import com.eucalyptus.auth.euare.Accounts; import com.eucalyptus.auth.euare.principal.EuareAccount; import com.eucalyptus.auth.euare.principal.EuareRole; import com.eucalyptus.auth.euare.principal.EuareUser; import com.eucalyptus.auth.principal.Policy; import com.eucalyptus.auth.util.SystemAccountProvider; import com.eucalyptus.bootstrap.Bootstrap; import com.eucalyptus.bootstrap.Bootstrapper; import com.eucalyptus.bootstrap.Provides; import com.eucalyptus.bootstrap.RunDuring; import com.eucalyptus.component.ComponentIds; import com.eucalyptus.component.id.Eucalyptus; import com.eucalyptus.empyrean.Empyrean; import com.eucalyptus.util.EucalyptusCloudException; import com.google.common.collect.Sets; /** * */ @Provides( Empyrean.class ) @RunDuring( Bootstrap.Stage.SystemAccountsInit ) public class DatabaseSystemAccountBootstrapper extends Bootstrapper { private static Logger LOG = Logger.getLogger( DatabaseSystemAccountBootstrapper.class ); public boolean load( ) { return true; } /** * @see com.eucalyptus.bootstrap.Bootstrapper#enable() */ @Override public boolean enable( ) throws Exception { return true; } public boolean start( ) throws Exception { if( ComponentIds.lookup( Eucalyptus.class ).isAvailableLocally( ) ) { for ( final SystemAccountProvider systemAccountProvider : ServiceLoader.load( SystemAccountProvider.class ) ) { ensureSystemAccountExists( systemAccountProvider ); } } return true; } /** * @see com.eucalyptus.bootstrap.Bootstrapper#stop() */ @Override public boolean stop( ) throws Exception { return true; } /** * @see com.eucalyptus.bootstrap.Bootstrapper#destroy() */ @Override public void destroy( ) throws Exception { } /** * @see com.eucalyptus.bootstrap.Bootstrapper#disable() */ @Override public boolean disable( ) throws Exception { return true; } /** * @see com.eucalyptus.bootstrap.Bootstrapper#check() */ @Override public boolean check( ) throws Exception { return true; } private static void ensureSystemAccountExists( final SystemAccountProvider provider ) { try { EuareAccount account; try { account = Accounts.lookupAccountByName( provider.getAlias( ) ); } catch ( final AuthException e ) { LOG.info( "Could not find system account '" + provider.getAlias( ) + "', creating."); try { account = Accounts.addSystemAccountWithAdmin( provider.getAlias() ); } catch ( final Exception e1 ) { throw new EucalyptusCloudException( "Error creating system account " + provider.getAlias() ); } } EuareUser user = account.lookupAdmin( ); if ( provider.isCreateAdminAccessKey( ) && user.getKeys( ).isEmpty( ) ) { LOG.info( "Creating system account '"+provider.getAlias()+"', admin access key" ); account.lookupAdmin( ).createKey( ); } for ( final SystemAccountProvider.SystemAccountRole systemAccountRole : provider.getRoles( ) ) { try { final EuareRole role = account.lookupRoleByName( systemAccountRole.getName( ) ); ensureSystemRolePoliciesExist( role, systemAccountRole, account.getAccountNumber() ); } catch ( final AuthException e ) { addSystemRole( account, systemAccountRole ); } } } catch ( Exception e ) { LOG.error( "Error checking system account '" + provider.getAlias( ) + "'", e ); } } private static void addSystemRole( final EuareAccount account, final SystemAccountProvider.SystemAccountRole systemAccountRole ) { LOG.info( String.format( "Creating system role: %s", systemAccountRole.getName( ) ) ); try { final String name = systemAccountRole.getName( ); final String path = systemAccountRole.getPath( ); final String assumeRolePolicy = systemAccountRole.getAssumeRolePolicy(); final EuareRole role = account.addRole( name, path, assumeRolePolicy ); ensureSystemRolePoliciesExist( role, systemAccountRole, account.getAccountNumber() ); } catch ( Exception e ) { LOG.error( String.format( "Error adding system role: %s", systemAccountRole.getName( ) ), e ); } } private static void ensureSystemRolePoliciesExist( final EuareRole role, final SystemAccountProvider.SystemAccountRole systemAccountRole, final String accountId) throws AuthException, PolicyParseException { final Set<String> existingPolicies = Sets.newHashSet(); for ( final Policy policy : role.getPolicies( ) ) { existingPolicies.add( policy.getName( ) ); } for ( final SystemAccountProvider.AttachedPolicy policy : systemAccountRole.getPolicies( ) ) { if ( !existingPolicies.contains( policy.getName( ) ) ) { LOG.info( "Creating system role policy '"+policy.getName( )+"'" ); String p = policy.getPolicy( ); p = p != null ? p.replaceAll("<AccountNumber>", accountId) : p; role.putPolicy( policy.getName( ), p ); } } } public static class DatabaseAuthSystemAccountInitializer implements SystemAccountProvider.SystemAccountInitializer { @Override public void initialize( final SystemAccountProvider provider ) throws AuthException { ensureSystemAccountExists( provider ); } } }