/************************************************************************* * Copyright 2009-2016 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. * * This file may incorporate work covered under the following copyright * and permission notice: * * Software License Agreement (BSD License) * * Copyright (c) 2008, Regents of the University of California * All rights reserved. * * Redistribution and use of this software in source and binary forms, * with or without modification, are permitted provided that the * following conditions are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer * in the documentation and/or other materials provided with the * distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. USERS OF THIS SOFTWARE ACKNOWLEDGE * THE POSSIBLE PRESENCE OF OTHER OPEN SOURCE LICENSED MATERIAL, * COPYRIGHTED MATERIAL OR PATENTED MATERIAL IN THIS SOFTWARE, * AND IF ANY SUCH MATERIAL IS DISCOVERED THE PARTY DISCOVERING * IT MAY INFORM DR. RICH WOLSKI AT THE UNIVERSITY OF CALIFORNIA, * SANTA BARBARA WHO WILL THEN ASCERTAIN THE MOST APPROPRIATE REMEDY, * WHICH IN THE REGENTS' DISCRETION MAY INCLUDE, WITHOUT LIMITATION, * REPLACEMENT OF THE CODE SO IDENTIFIED, LICENSING OF THE CODE SO * IDENTIFIED, OR WITHDRAWAL OF THE CODE CAPABILITY TO THE EXTENT * NEEDED TO COMPLY WITH ANY SUCH LICENSES OR RIGHTS. ************************************************************************/ package com.eucalyptus.configurable; import java.util.List; import java.util.NoSuchElementException; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EntityTransaction; import javax.persistence.Lob; import javax.persistence.PersistenceContext; import javax.persistence.Table; import org.apache.log4j.Logger; import org.hibernate.annotations.Type; import com.eucalyptus.auth.principal.AccountIdentifiers; import com.eucalyptus.empyrean.Empyrean; import com.eucalyptus.entities.AbstractPersistent; import com.eucalyptus.entities.Entities; import com.eucalyptus.entities.TransactionResource; import com.eucalyptus.records.Logs; import com.eucalyptus.upgrade.Upgrades.EntityUpgrade; import com.eucalyptus.upgrade.Upgrades.Version; import com.eucalyptus.util.Exceptions; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Lists; import javaslang.Tuple; import javaslang.Tuple3; @Entity @PersistenceContext( name = "eucalyptus_config" ) @Table( name = "config_static_property" ) public class StaticDatabasePropertyEntry extends AbstractPersistent { @Column( name = "config_static_field_name", nullable = false, unique = true ) private String fieldName; @Lob @Type(type="org.hibernate.type.StringClobType") @Column( name = "config_static_field_value" ) private String value; @Column( name = "config_static_prop_name", nullable = false, unique = true ) private String propName; private StaticDatabasePropertyEntry( ) { super( ); this.fieldName = null; } private StaticDatabasePropertyEntry( String fieldName, String propName, String value ) { super( ); this.propName = propName; this.fieldName = fieldName; this.value = value; } public static StaticDatabasePropertyEntry update( final String fieldName, final String propName, final String newFieldValue ) throws Exception { final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ); try { final StaticDatabasePropertyEntry dbEntry = Entities.uniqueResult( new StaticDatabasePropertyEntry( fieldName, propName, null ) ); dbEntry.setValue( newFieldValue ); db.commit( ); return dbEntry; } catch ( final NoSuchElementException ex ) { final StaticDatabasePropertyEntry dbEntry = new StaticDatabasePropertyEntry( fieldName, propName, newFieldValue ); Entities.persist( dbEntry ); db.commit( ); return dbEntry; } finally { db.close( ); } } static StaticDatabasePropertyEntry lookup( String fieldName, String propName, String defaultFieldValue ) throws Exception { EntityTransaction db = Entities.get( StaticDatabasePropertyEntry.class ); try { StaticDatabasePropertyEntry entity = Entities.uniqueResult( new StaticDatabasePropertyEntry( fieldName, propName, null ) ); db.commit( ); return entity; } catch ( Exception ex ) { try { StaticDatabasePropertyEntry entity = Entities.persist( new StaticDatabasePropertyEntry( fieldName, propName, defaultFieldValue ) ); db.commit( ); return entity; } catch ( Exception ex1 ) { Logs.extreme( ).error( "Failed to lookup static configuration property for: " + fieldName + " with property name: " + propName ); db.rollback( ); throw ex; } } } private void setValue( String value ) { this.value = value; } private String getFieldName( ) { return this.fieldName; } public void setFieldName(String fieldName) { this.fieldName = fieldName; } public String getValue( ) { return this.value; } public String getPropName( ) { return this.propName; } private void setPropName( String propName ) { this.propName = propName; } @Override public int hashCode( ) { final int prime = 31; int result = super.hashCode( ); result = prime * result + ( ( this.propName == null ) ? 0 : this.propName.hashCode( ) ); return result; } @Override public boolean equals( Object obj ) { if ( this == obj ) { return true; } if ( !super.equals( obj ) ) { return false; } if ( getClass( ) != obj.getClass( ) ) { return false; } StaticDatabasePropertyEntry other = ( StaticDatabasePropertyEntry ) obj; if ( this.propName == null ) { if ( other.propName != null ) { return false; } } else if ( !this.propName.equals( other.propName ) ) { return false; } return true; } private static class UpgradeUtils { private static void deleteRemovedProperties( final Logger logger, final Iterable<String> propertyNames ) { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { for ( final String propertyName : propertyNames ) try { final StaticDatabasePropertyEntry property = Entities.criteriaQuery( StaticDatabasePropertyEntry.class ) .whereEqual( StaticDatabasePropertyEntry_.propName, propertyName ) .uniqueResult( ); logger.info( "Deleting cloud property: " + propertyName ); Entities.delete( property ); } catch ( NoSuchElementException e ) { logger.info( "Property not found, skipped delete for: " + propertyName ); } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } private static void updateMovedProperties( final Logger logger, final Iterable<Tuple3<String,String,String>> movedProperties ) { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { for ( final Tuple3<String,String,String> movedProperty : movedProperties ) { final String propName = movedProperty._1( ); final String oldFieldName = movedProperty._2( ); final String newFieldName = movedProperty._3( ); Entities.criteriaQuery( StaticDatabasePropertyEntry.class ) .whereEqual( StaticDatabasePropertyEntry_.propName, propName ) .uniqueResultOption( ).transform( property -> { if ( oldFieldName.equals( property.getFieldName( ) ) ) { logger.info( "Updating field for "+propName+" property" ); property.setFieldName( newFieldName ); } return property; } ); } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } private static void updatePropertyValues( final Logger logger, final Iterable<Tuple3<String,String,String>> updatedProperties ) { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { for ( final Tuple3<String,String,String> updatedProperty : updatedProperties ) { final String propName = updatedProperty._1( ); final String oldValue = updatedProperty._2( ); final String newValue = updatedProperty._3( ); Entities.criteriaQuery( StaticDatabasePropertyEntry.class ) .whereEqual( StaticDatabasePropertyEntry_.propName, propName ) .uniqueResultOption( ).transform( property -> { if ( oldValue.equals( property.getValue( ) ) ) { logger.info( "Updating value for "+propName+" property to " + newValue ); property.setValue( newValue ); } return property; } ); } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } private static void createOrOverwriteProperties( final Logger logger, final Iterable<Tuple3<String,String,String>> properties ) { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { for ( final Tuple3<String,String,String> property : properties ) { final String fieldName = property._1( ); final String propName = property._2( ); final String value = property._3( ); logger.info( "Setting value for "+propName+" property to " + value ); update( fieldName, propName, value ); } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v3_2_0, value = Empyrean.class ) public enum StaticPropertyEntryUpgrade implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( StaticPropertyEntryUpgrade.class ); @Override public boolean apply( Class arg0 ) { EntityTransaction db = Entities.get( StaticDatabasePropertyEntry.class ); try { List<StaticDatabasePropertyEntry> entities = Entities.query( new StaticDatabasePropertyEntry( ) ); for ( StaticDatabasePropertyEntry entry : entities ) { LOG.debug( "Upgrading: " + entry.getPropName( ) + "=" + entry.getValue( ) ); } db.commit( ); return true; } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v3_3_0, value = Empyrean.class ) public enum StaticPropertyEntryRenamePropertyUpgrade implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( StaticPropertyEntryRenamePropertyUpgrade.class ); @Override public boolean apply( Class arg0 ) { final String REPORTING_DEFAULT_POLL_INTERVAL_MINS_FIELD_NAME = "com.eucalyptus.reporting.modules.backend.DescribeSensorsListener.default_poll_interval_mins"; final String REPORTING_DEFAULT_POLL_INTERVAL_MINS = "reporting.default_poll_interval_mins"; final String CLOUD_MONITOR_DEFAULT_POLL_INTERVAL_MINS = "cloud.monitor.default_poll_interval_mins"; EntityTransaction db = Entities.get( StaticDatabasePropertyEntry.class ); try { List<StaticDatabasePropertyEntry> entities = Entities.query( new StaticDatabasePropertyEntry( ) ); for ( StaticDatabasePropertyEntry entry : entities ) { if (REPORTING_DEFAULT_POLL_INTERVAL_MINS_FIELD_NAME.equals(entry.getFieldName()) && REPORTING_DEFAULT_POLL_INTERVAL_MINS.equals(entry.getPropName())) { entry.setPropName(CLOUD_MONITOR_DEFAULT_POLL_INTERVAL_MINS); LOG.debug( "Upgrading: Changing property '"+REPORTING_DEFAULT_POLL_INTERVAL_MINS+"' to '"+CLOUD_MONITOR_DEFAULT_POLL_INTERVAL_MINS+"'"); } } db.commit( ); return true; } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v3_4_0, value = Empyrean.class ) public enum StaticPropertyEntryRenameExpermentalDNSPropertyUpgrade implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( StaticPropertyEntryRenameExpermentalDNSPropertyUpgrade.class ); @Override public boolean apply( Class arg0 ) { final String EXPERIMENTAL_DNS_PREFIX = "experimental.dns."; final String DNS_PREFIX = "dns."; EntityTransaction db = Entities.get( StaticDatabasePropertyEntry.class ); try { List<StaticDatabasePropertyEntry> entities = Entities.query( new StaticDatabasePropertyEntry( ) ); for ( StaticDatabasePropertyEntry entry : entities ) { if (entry.getPropName() != null && entry.getPropName().startsWith(EXPERIMENTAL_DNS_PREFIX)) { String oldPropertyName = entry.getPropName(); String newPropertyName = DNS_PREFIX + oldPropertyName.substring(EXPERIMENTAL_DNS_PREFIX.length()); LOG.debug( "Upgrading: Changing property '"+oldPropertyName+"' to '"+newPropertyName+"'"); entry.setPropName(newPropertyName); } } db.commit( ); return true; } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } finally { if (db.isActive()) db.rollback(); } } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v4_0_1, value = Empyrean.class ) public enum StaticPropertyEntryRenamePropertyCloudWatchUpgrade implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( StaticPropertyEntryRenamePropertyUpgrade.class ); @Override public boolean apply( Class arg0 ) { final String CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_OLD_FIELD_NAME = "com.eucalyptus.cloudwatch.CloudWatchService.disable_cloudwatch_service"; final String CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_NEW_FIELD_NAME = "com.eucalyptus.cloudwatch.backend.CloudWatchBackendService.disable_cloudwatch_service"; final String CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_PROP_NAME = "cloudwatch.disable_cloudwatch_service"; EntityTransaction db = Entities.get( StaticDatabasePropertyEntry.class ); try { List<StaticDatabasePropertyEntry> entities = Entities.query( new StaticDatabasePropertyEntry( ) ); for ( StaticDatabasePropertyEntry entry : entities ) { if (CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_OLD_FIELD_NAME.equals(entry.getFieldName()) && CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_PROP_NAME.equals(entry.getPropName())) { entry.setFieldName(CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_NEW_FIELD_NAME); LOG.debug( "Upgrading: Changing property " + CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_PROP_NAME + " field name'"+CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_OLD_FIELD_NAME+"' to '"+CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_NEW_FIELD_NAME+"'"); } } db.commit( ); return true; } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v4_4_0, value = Empyrean.class ) public enum StaticPropertyEntryInvertPropertyCloudWatchUpgrade implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( StaticPropertyEntryRenamePropertyUpgrade.class ); @Override public boolean apply( Class arg0 ) { final String CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_FIELD_NAME = "com.eucalyptus.cloudwatch.common.config.CloudWatchConfigProperties.disable_cloudwatch_service"; final String CLOUDWATCH_ENABLE_CLOUDWATCH_SERVICE_FIELD_NAME = "com.eucalyptus.cloudwatch.common.config.CloudWatchConfigProperties.enable_cloudwatch_service"; final String CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_PROP_NAME = "cloudwatch.disable_cloudwatch_service"; final String CLOUDWATCH_ENABLE_CLOUDWATCH_SERVICE_PROP_NAME = "cloudwatch.enable_cloudwatch_service"; try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { List<StaticDatabasePropertyEntry> entities = Entities.criteriaQuery(StaticDatabasePropertyEntry.class) .whereEqual(StaticDatabasePropertyEntry_.fieldName, CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_FIELD_NAME) .whereEqual(StaticDatabasePropertyEntry_.propName, CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_PROP_NAME) .list(); for ( StaticDatabasePropertyEntry entry : entities ) { entry.setFieldName(CLOUDWATCH_ENABLE_CLOUDWATCH_SERVICE_FIELD_NAME); entry.setPropName(CLOUDWATCH_ENABLE_CLOUDWATCH_SERVICE_PROP_NAME); entry.setValue(Boolean.toString(!Boolean.valueOf(entry.getValue()))); LOG.debug( "Upgrading: Changing property " + CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_PROP_NAME + " field name'"+CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_FIELD_NAME+"' to '"+CLOUDWATCH_ENABLE_CLOUDWATCH_SERVICE_FIELD_NAME+"'"); } db.commit( ); return true; } } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v4_0_0, value = Empyrean.class ) public enum StaticPropertyEntryUpgrade40 implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( StaticPropertyEntryUpgrade40.class ); private void configureIdentifierCanonicalizer( ) { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { try { final StaticDatabasePropertyEntry property = Entities.uniqueResult( new StaticDatabasePropertyEntry( null, "cloud.identifier_canonicalizer", null ) ); LOG.info( "Setting resource identifier canonicalizer property to 'upper' for upgraded system." ); property.setValue( "upper" ); } catch ( NoSuchElementException e ) { LOG.info( "Creating resource identifier canonicalizer property with value 'upper' for upgraded system." ); Entities.persist( new StaticDatabasePropertyEntry( "com.eucalyptus.compute.identifier.ResourceIdentifiers.identifier_canonicalizer", "cloud.identifier_canonicalizer", "upper" ) ); } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } private void deleteRemovedProperties( final Iterable<String> propertyNames ) { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { for ( final String propertyName : propertyNames ) try { final StaticDatabasePropertyEntry property = Entities.uniqueResult( new StaticDatabasePropertyEntry( null,propertyName, null ) ); LOG.info( "Deleting cloud property: " + propertyName ); Entities.delete( property ); } catch ( NoSuchElementException e ) { LOG.info( "Property not found, skipped delete for: " + propertyName ); } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } @Override public boolean apply( Class arg0 ) { configureIdentifierCanonicalizer( ); deleteRemovedProperties( Lists.newArrayList( "authentication.websession_life_in_minutes" ) ); return true; } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v4_1_0, value = Empyrean.class ) public enum StaticPropertyEntryRenameServiceVMPropertyUpgrade implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( StaticPropertyEntryRenameServiceVMPropertyUpgrade.class ); @Override public boolean apply( Class arg0 ) { ImmutableMap<String, String[]> changes = ImmutableMap.<String, String[]>builder() .put("imaging.imaging_worker_availability_zones", new String[] {"services.imaging.worker.availability_zones", "com.eucalyptus.imaging.ImagingServiceProperties.availability_zones"}) .put("imaging.imaging_worker_emi", new String[] {"services.imaging.worker.image", "com.eucalyptus.imaging.ImagingServiceProperties.image"}) .put("imaging.imaging_worker_enabled", new String[] {"services.imaging.worker.configured", "com.eucalyptus.imaging.worker.ImagingServiceLaunchers.configured"}) .put("imaging.imaging_worker_healthcheck", new String[] {"services.imaging.worker.healthcheck", "com.eucalyptus.imaging.ImagingServiceProperties.healthcheck"}) .put("imaging.imaging_worker_instance_type", new String[] {"services.imaging.worker.instance_type", "com.eucalyptus.imaging.ImagingServiceProperties.instance_type"}) .put("imaging.imaging_worker_keyname", new String[] {"services.imaging.worker.keyname", "com.eucalyptus.imaging.ImagingServiceProperties.keyname"}) .put("imaging.imaging_worker_log_server", new String[] {"services.imaging.worker.log_server", "com.eucalyptus.imaging.ImagingServiceProperties.log_server"}) .put("imaging.imaging_worker_log_server_port", new String[] {"services.imaging.worker.log_server_port", "com.eucalyptus.imaging.ImagingServiceProperties.log_server_port"}) .put("imaging.imaging_worker_ntp_server", new String[] {"services.imaging.worker.ntp_server", "com.eucalyptus.imaging.ImagingServiceProperties.ntp_server"}) .put("imaging.import_task_expiration_hours", new String[] {"services.imaging.import_task_expiration_hours", "com.eucalyptus.imaging.ImportTaskProperties.import_task_expiration_hours"}) .put("imaging.import_task_timeout_minutes", new String[] {"services.imaging.import_task_timeout_minutes", "com.eucalyptus.imaging.ImportTaskProperties.import_task_timeout_minutes"}) .put("loadbalancing.loadbalancer_app_cookie_duration", new String[] {"services.loadbalancing.worker.app_cookie_duration", "com.eucalyptus.loadbalancing.activities.LoadBalancerASGroupCreator.app_cookie_duration"}) .put("loadbalancing.loadbalancer_dns_subdomain", new String[] {"services.loadbalancing.dns_subdomain", "com.eucalyptus.loadbalancing.LoadBalancerDnsRecord.dns_subdomain"}) .put("loadbalancing.loadbalancer_dns_ttl", new String[] {"services.loadbalancing.dns_ttl", "com.eucalyptus.loadbalancing.LoadBalancerDnsRecord.dns_ttl"}) .put("loadbalancing.loadbalancer_emi", new String[] {"services.loadbalancing.worker.image", "com.eucalyptus.loadbalancing.activities.LoadBalancerASGroupCreator.image"}) .put("loadbalancing.loadbalancer_instance_type", new String[] {"services.loadbalancing.worker.instance_type", "com.eucalyptus.loadbalancing.activities.LoadBalancerASGroupCreator.instance_type"}) .put("loadbalancing.loadbalancer_num_vm", new String[] {"services.loadbalancing.vm_per_zone", "com.eucalyptus.loadbalancing.activities.EventHandlerChainNew.vm_per_zone"}) .put("loadbalancing.loadbalancer_restricted_ports", new String[] {"services.loadbalancing.restricted_ports", "com.eucalyptus.loadbalancing.LoadBalancerListener.restricted_ports"}) .put("loadbalancing.loadbalancer_vm_keyname", new String[] {"services.loadbalancing.worker.keyname", "com.eucalyptus.loadbalancing.activities.LoadBalancerASGroupCreator.keyname"}) .put("loadbalancing.loadbalancer_vm_ntp_server", new String[] {"services.loadbalancing.worker.ntp_server", "com.eucalyptus.loadbalancing.activities.LoadBalancerASGroupCreator.ntp_server"}) .build(); EntityTransaction db = Entities.get( StaticDatabasePropertyEntry.class ); LOG.info("Updating service VM properties"); try { List<StaticDatabasePropertyEntry> entities = Entities.query( new StaticDatabasePropertyEntry( ) ); for ( StaticDatabasePropertyEntry entry : entities ) { if (entry.getPropName() != null && changes.containsKey(entry.getPropName())) { String[] newProperty = changes.get(entry.getPropName()); LOG.info( "Upgrading: Copying property value of'" + entry.getPropName() + "' to '" + newProperty[0] + "'" ); StaticDatabasePropertyEntry.update(newProperty[1], newProperty[0], entry.getValue()); LOG.info( "Deleting old property from DB'" + entry.getPropName() + "'" ); Entities.delete(entry); } } db.commit( ); return true; } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } finally { if (db.isActive()) db.rollback(); } } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v4_2_0, value = Empyrean.class ) public enum StaticPropertyEntryUpgrade420 implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( StaticPropertyEntryUpgrade420.class ); private void updateLdapConfiguration( ) { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { try { final StaticDatabasePropertyEntry property = Entities.uniqueResult( new StaticDatabasePropertyEntry( null, "authentication.ldap_integration_configuration", null ) ); LOG.info( "Updating field and default value for authentication.ldap_integration_configuration" ); if ( "{ 'sync': { 'enable':'false' } }".equals( property.getValue( ) ) ) { property.setValue( "{ \"sync\": { \"enable\":\"false\" } }" ); } property.setFieldName( "com.eucalyptus.auth.euare.ldap.LdapProperties.ldap_integration_configuration" ); } catch ( NoSuchElementException e ) { LOG.info( "Creating resource identifier canonicalizer property with value 'upper' for upgraded system." ); Entities.persist( new StaticDatabasePropertyEntry( "com.eucalyptus.compute.identifier.ResourceIdentifiers.identifier_canonicalizer", "cloud.identifier_canonicalizer", "upper" ) ); } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } private void deleteRemovedProperties( final Iterable<String> propertyNames ) { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { for ( final String propertyName : propertyNames ) try { final StaticDatabasePropertyEntry property = Entities.uniqueResult( new StaticDatabasePropertyEntry( null,propertyName, null ) ); LOG.info( "Deleting cloud property: " + propertyName ); Entities.delete( property ); } catch ( NoSuchElementException e ) { LOG.info( "Property not found, skipped delete for: " + propertyName ); } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } private void updateStackConfiguration ( ) { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { try { final StaticDatabasePropertyEntry pipeline_max_query_property = Entities.uniqueResult( new StaticDatabasePropertyEntry( null, "bootstrap.webservices.pipeline_max_query_request_size", null ) ); final StaticDatabasePropertyEntry max_chunk_property = Entities.uniqueResult( new StaticDatabasePropertyEntry( null, "bootstrap.webservices.http_max_chunk_bytes", null ) ); LOG.info( " Checking to make sure default pipeline_max_query_request_size is not smaller than http_max_chunk_bytes." ); if ( Integer.parseInt(max_chunk_property.getValue()) > Integer.parseInt(pipeline_max_query_property.getValue())) { pipeline_max_query_property.setValue(max_chunk_property.getValue()); } } catch ( NoSuchElementException e ) { LOG.info( "Property not found, skipped size check for : bootstrap.webservices.pipeline_max_query_request_size" ); } try { final String expect = "RSA:DSS:ECDSA:+RC4:+3DES:TLS_EMPTY_RENEGOTIATION_INFO_SCSV:!NULL:!EXPORT:!EXPORT1024:!MD5:!DES"; final String update = "RSA:DSS:ECDSA:+3DES:TLS_EMPTY_RENEGOTIATION_INFO_SCSV:!NULL:!EXPORT:!EXPORT1024:!MD5:!DES:!RC4"; for ( final String propName : Lists.newArrayList( "bootstrap.webservices.ssl.user_ssl_ciphers", "www.https_ciphers", "bootstrap.webservices.ssl.server_ssl_ciphers" ) ) { final StaticDatabasePropertyEntry ciphersProperty = Entities.uniqueResult( new StaticDatabasePropertyEntry( null, propName, null ) ); if ( expect.equals( ciphersProperty.getValue( ) ) ) { LOG.info( "Updating ciphers property " + propName + " with value " + update ); ciphersProperty.setValue( update ); } } } catch ( Exception e ) { LOG.error( "Error updating cipher suite configuration to remove RC4", e ); } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } private void migrateEc2ClassicProtocolExtensions() { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { try { final StaticDatabasePropertyEntry property = Entities.uniqueResult( new StaticDatabasePropertyEntry( null, "cloud.network.ec2_classic_additional_protocols_allowed", null ) ); LOG.info( "Updating field and default value for cloud.network.ec2_classic_additional_protocols_allowed" ); property.setFieldName( "com.eucalyptus.compute.common.config.ExtendedNetworkingConfiguration.ec2_classic_additional_protocols_allowed" ); } catch ( NoSuchElementException e ) { //Nothing to do. } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } private void migrateDisableCloudWatchProperty() { final String CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_OLD_FIELD_NAME = "com.eucalyptus.cloudwatch.backend.CloudWatchBackendService.disable_cloudwatch_service"; final String CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_NEW_FIELD_NAME = "com.eucalyptus.cloudwatch.common.config.CloudWatchConfigProperties.disable_cloudwatch_service"; final String CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_PROP_NAME = "cloudwatch.disable_cloudwatch_service"; try (final TransactionResource db = Entities.transactionFor(StaticDatabasePropertyEntry.class)) { List<StaticDatabasePropertyEntry> entities = Entities.query(new StaticDatabasePropertyEntry()); for (StaticDatabasePropertyEntry entry : entities) { if (CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_OLD_FIELD_NAME.equals(entry.getFieldName()) && CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_PROP_NAME.equals(entry.getPropName())) { entry.setFieldName(CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_NEW_FIELD_NAME); LOG.debug("Upgrading: Changing property " + CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_PROP_NAME + " field name'" + CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_OLD_FIELD_NAME + "' to '" + CLOUDWATCH_DISABLE_CLOUDWATCH_SERVICE_NEW_FIELD_NAME + "'"); } } db.commit(); } catch (Exception ex) { throw Exceptions.toUndeclared(ex); } } @Override public boolean apply( Class arg0 ) { updateStackConfiguration( ); updateLdapConfiguration( ); deleteRemovedProperties( Lists.newArrayList( "www.httpProxyHost" , "www.httpProxyPort" ) ); //move ec2_classic network config from cluster-manager to compute-common property migrateEc2ClassicProtocolExtensions(); migrateDisableCloudWatchProperty(); return true; } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v4_2_0, value = Empyrean.class ) public enum DropServiceKeypairPropertyUpgrade implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( DropServiceKeypairPropertyUpgrade.class ); @Override public boolean apply( Class arg0 ) { try { StaticDatabasePropertyEntry.update( "com.eucalyptus.imaging.ImagingServiceProperties.keyname", "services.imaging.worker.keyname", "" ); LOG.info("Resetting services.imaging.worker.keyname property to ''. Please set it to a keypair from " + AccountIdentifiers.IMAGING_SYSTEM_ACCOUNT + " account if needed."); StaticDatabasePropertyEntry.update( "com.eucalyptus.loadbalancing.activities.LoadBalancerASGroupCreator.keyname", "services.loadbalancing.worker.keyname", "" ); LOG.info("Resetting services.loadbalancing.worker.keyname to '' . Please set it to a keypair from " + AccountIdentifiers.ELB_SYSTEM_ACCOUNT + " account if needed."); return true; } catch (Exception e) { throw Exceptions.toUndeclared( e ); } } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v4_2_1, value = Empyrean.class ) public enum StaticPropertyEntryUpgrade421 implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( StaticPropertyEntryUpgrade421.class ); private void migrateIdentifierCanonicalizerProperty() { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { try { final StaticDatabasePropertyEntry property = Entities.uniqueResult( new StaticDatabasePropertyEntry( null, "cloud.identifier_canonicalizer", null ) ); LOG.info( "Updating field for cloud.identifier_canonicalizer property" ); property.setFieldName( "com.eucalyptus.compute.common.internal.identifier.ResourceIdentifiers.identifier_canonicalizer" ); } catch ( NoSuchElementException e ) { //Nothing to do. } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } private void enableInstanceDns( ) { setPropertyValue( "dns.split_horizon.enabled", String.valueOf( true ), "Setting property dns.split_horizon.enabled property to true to enable instance dns" ); } private void enableServiceDns( ) { setPropertyValue( "dns.services.enabled", String.valueOf( true ), "Setting property dns.services.enabled property to true to enable service dns" ); } private void setPropertyValue( final String name, final String value, final String message ) { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { try { final StaticDatabasePropertyEntry property = Entities.uniqueResult( new StaticDatabasePropertyEntry( null, name, null ) ); if ( !value.equals( property.getValue( ) ) ) { LOG.info( message ); property.setValue( value ); } } catch ( NoSuchElementException e ) { //Nothing to do. } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } @Override public boolean apply( final Class entity ) { migrateIdentifierCanonicalizerProperty( ); enableInstanceDns( ); enableServiceDns( ); return true; } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v4_3_0, value = Empyrean.class ) public enum StaticPropertyEntryUpgrade430 implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( StaticPropertyEntryUpgrade430.class ); private void deleteRemovedProperties( final Iterable<String> propertyNames ) { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { for ( final String propertyName : propertyNames ) try { final StaticDatabasePropertyEntry property = Entities.uniqueResult( new StaticDatabasePropertyEntry( null,propertyName, null ) ); LOG.info( "Deleting cloud property: " + propertyName ); Entities.delete( property ); } catch ( NoSuchElementException e ) { LOG.info( "Property not found, skipped delete for: " + propertyName ); } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } @Override public boolean apply( Class arg0 ) { deleteRemovedProperties( Lists.newArrayList( "www.https_ciphers", "www.https_port", "www.https_protocols", "services.database.worker.availability_zones", "services.database.worker.configured", "services.database.worker.expiration_days", "services.database.worker.image", "services.database.worker.init_script", "services.database.worker.instance_type", "services.database.worker.keyname", "services.database.worker.ntp_server", "services.database.worker.volume", "cloud.perm_gen_memory_check_poll_time", "cloud.perm_gen_memory_check_ratio" ) ); return true; } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v4_4_0, value = Empyrean.class ) public enum StaticPropertyEntryUpgrade440 implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( StaticPropertyEntryUpgrade440.class ); private void configureCloudformationStrictResourcePropertyEnforcement( ) { try ( final TransactionResource db = Entities.transactionFor( StaticDatabasePropertyEntry.class ) ) { try { final StaticDatabasePropertyEntry property = Entities.criteriaQuery(StaticDatabasePropertyEntry.class). whereEqual(StaticDatabasePropertyEntry_.propName, "cloudformation.enforce_strict_resource_properties") .uniqueResult(); LOG.info( "Found existing 'cloudformation.enforce_strict_resource_properties' property, leaving alone."); } catch ( NoSuchElementException e ) { LOG.info( "Creating property 'cloudformation.enforce_strict_resource_properties' with value 'false')"); Entities.persist( new StaticDatabasePropertyEntry( "com.eucalyptus.cloudformation.config.CloudFormationProperties.enforce_strict_resource_properties", "cloudformation.enforce_strict_resource_properties", "false" ) ); } db.commit( ); } catch ( Exception ex ) { throw Exceptions.toUndeclared( ex ); } } @Override public boolean apply( final Class arg0 ) { UpgradeUtils.deleteRemovedProperties( LOG, ImmutableList.of( "bootstrap.servicebus.max_outstanding_messages", "bootstrap.servicebus.min_scheduler_core_size", "bootstrap.servicebus.workers_per_stage", "cloud.network.global_min_network_tag", "cloud.network.global_max_network_tag", "cloud.network.global_min_network_index", "cloud.network.global_max_network_index", "cloud.network.network_tag_pending_timeout", "services.loadbalancing.worker.backend_instance_update_interval", "services.loadbalancing.worker.cache_duration", "services.loadbalancing.worker.cw_put_interval", "services.loadbalancing.worker.lb_poll_interval" ) ); UpgradeUtils.updateMovedProperties( LOG, ImmutableList.of( Tuple.of( "dns.recursive.enabled", "com.eucalyptus.dns.resolvers.RecursiveDnsResolver.enabled", "com.eucalyptus.vm.dns.RecursiveDnsResolver.enabled" ) ) ); UpgradeUtils.updatePropertyValues( LOG, ImmutableList.of( Tuple.of( "cloudformation.swf_activity_worker_config", "{\"PollThreadCount\": 8, \"TaskExecutorThreadPoolSize\": 16, \"MaximumPollRateIntervalMilliseconds\": 50 }", "{\"PollThreadCount\": 8, \"TaskExecutorThreadPoolSize\": 16, \"MaximumPollRateIntervalMilliseconds\": 50, \"MaximumPollRatePerSecond\": 20 }" ), Tuple.of( "cloudformation.swf_workflow_worker_config", "{ \"DomainRetentionPeriodInDays\": 1, \"PollThreadCount\": 8, \"MaximumPollRateIntervalMilliseconds\": 50 }", "{ \"DomainRetentionPeriodInDays\": 1, \"PollThreadCount\": 8, \"MaximumPollRateIntervalMilliseconds\": 50, \"MaximumPollRatePerSecond\": 20 }" ), Tuple.of( "services.loadbalancing.swf_activity_worker_config", "{\"PollThreadCount\": 4, \"TaskExecutorThreadPoolSize\": 32, \"MaximumPollRateIntervalMilliseconds\": 50 }", "{\"PollThreadCount\": 4, \"TaskExecutorThreadPoolSize\": 32, \"MaximumPollRateIntervalMilliseconds\": 50, \"MaximumPollRatePerSecond\": 20 }" ), Tuple.of( "services.loadbalancing.swf_workflow_worker_config", "{ \"DomainRetentionPeriodInDays\": 1, \"PollThreadCount\": 4, \"MaximumPollRateIntervalMilliseconds\": 50 }", "{ \"DomainRetentionPeriodInDays\": 1, \"PollThreadCount\": 4, \"MaximumPollRateIntervalMilliseconds\": 50, \"MaximumPollRatePerSecond\": 20 }" ), Tuple.of( "bootstrap.webservices.ssl.server_ssl_ciphers", "RSA:DSS:ECDSA:+3DES:TLS_EMPTY_RENEGOTIATION_INFO_SCSV:!NULL:!EXPORT:!EXPORT1024:!MD5:!DES:!RC4", "RSA:DSS:ECDSA:+3DES:TLS_EMPTY_RENEGOTIATION_INFO_SCSV:!NULL:!EXPORT:!EXPORT1024:!MD5:!DES:!RC4:!ECDHE" ), Tuple.of( "bootstrap.webservices.ssl.user_ssl_ciphers", "RSA:DSS:ECDSA:+3DES:TLS_EMPTY_RENEGOTIATION_INFO_SCSV:!NULL:!EXPORT:!EXPORT1024:!MD5:!DES:!RC4", "RSA:DSS:ECDSA:+3DES:TLS_EMPTY_RENEGOTIATION_INFO_SCSV:!NULL:!EXPORT:!EXPORT1024:!MD5:!DES:!RC4:!ECDHE" ), Tuple.of( "region.region_ssl_ciphers", "RSA:DSS:ECDSA:TLS_EMPTY_RENEGOTIATION_INFO_SCSV:!NULL:!EXPORT:!EXPORT1024:!MD5:!DES:!RC4", "RSA:DSS:ECDSA:TLS_EMPTY_RENEGOTIATION_INFO_SCSV:!NULL:!EXPORT:!EXPORT1024:!MD5:!DES:!RC4:!ECDHE" ) ) ); configureCloudformationStrictResourcePropertyEnforcement(); return true; } } @EntityUpgrade( entities = StaticDatabasePropertyEntry.class, since = Version.v5_0_0, value = Empyrean.class ) public enum StaticPropertyEntryUpgrade500 implements Predicate<Class> { INSTANCE; private static Logger LOG = Logger.getLogger( StaticPropertyEntryUpgrade500.class ); @Override public boolean apply( final Class arg0 ) { UpgradeUtils.deleteRemovedProperties( LOG, ImmutableList.of( "bootstrap.webservices.client_idle_timeout_secs", "bootstrap.webservices.client_pool_max_mem_per_conn", "bootstrap.webservices.client_pool_timeout_millis", "bootstrap.webservices.client_pool_total_mem", "cloudformation.swf_client_config", "cloud.vmstate.network_metadata_refresh_time", "cloud.vmtypes.format_swap", "reporting.data_collection_enabled", "reporting.default_size_time_size_unit", "reporting.default_size_time_time_unit", "reporting.default_size_unit", "reporting.default_time_unit", "reporting.default_write_interval_mins", "services.loadbalancing.swf_client_config" ) ); UpgradeUtils.updateMovedProperties( LOG, ImmutableList.of( Tuple.of( "cloud.monitor.default_poll_interval_mins", "com.eucalyptus.reporting.modules.backend.DescribeSensorsListener.default_poll_interval_mins", "com.eucalyptus.cluster.callback.reporting.DescribeSensorsListener.default_poll_interval_mins" ), Tuple.of( "cloud.monitor.history_size", "com.eucalyptus.reporting.modules.backend.DescribeSensorsListener.history_size", "com.eucalyptus.cluster.callback.reporting.DescribeSensorsListener.history_size" ) ) ); UpgradeUtils.updatePropertyValues( LOG, ImmutableList.of( Tuple.of( "bootstrap.webservices.cluster_connect_timeout_millis", "2000", "3000" ) ) ); UpgradeUtils.createOrOverwriteProperties( LOG, ImmutableList.of( Tuple.of( "com.eucalyptus.autoscaling.config.AutoScalingConfiguration.maxtags", "autoscaling.maxtags", "10" ), Tuple.of( "com.eucalyptus.loadbalancing.LoadBalancingServiceProperties.max_tags", "services.loadbalancing.max_tags", "10" ) ) ); return true; } } }