@@ -114,6 +114,9 @@ pub enum Error {
114114
115115 #[ snafu( display( "object defines no regionserver role" ) ) ]
116116 NoRegionServerRole ,
117+
118+ #[ snafu( display( "incompatible merge types" ) ) ]
119+ IncompatibleMergeTypes ,
117120}
118121
119122/// An HBase cluster stacklet. This resource is managed by the Stackable operator for Apache HBase.
@@ -285,80 +288,106 @@ impl HbaseRole {
285288 }
286289}
287290
288- fn default_regionserver_config (
289- cluster_name : & str ,
290- hdfs_discovery_cm_name : & str ,
291- ) -> RegionServerConfigFragment {
292- let resources = ResourcesFragment {
293- cpu : CpuLimitsFragment {
294- min : Some ( Quantity ( "250m" . to_owned ( ) ) ) ,
295- max : Some ( Quantity ( "1" . to_owned ( ) ) ) ,
291+ fn default_resources ( role : & HbaseRole ) -> ResourcesFragment < HbaseStorageConfig , NoRuntimeLimits > {
292+ match role {
293+ HbaseRole :: RegionServer => ResourcesFragment {
294+ cpu : CpuLimitsFragment {
295+ min : Some ( Quantity ( "250m" . to_owned ( ) ) ) ,
296+ max : Some ( Quantity ( "1" . to_owned ( ) ) ) ,
297+ } ,
298+ memory : MemoryLimitsFragment {
299+ limit : Some ( Quantity ( "1Gi" . to_owned ( ) ) ) ,
300+ runtime_limits : NoRuntimeLimitsFragment { } ,
301+ } ,
302+ storage : HbaseStorageConfigFragment { } ,
296303 } ,
297- memory : MemoryLimitsFragment {
298- limit : Some ( Quantity ( "1Gi" . to_owned ( ) ) ) ,
299- runtime_limits : NoRuntimeLimitsFragment { } ,
304+ HbaseRole :: RestServer => ResourcesFragment {
305+ cpu : CpuLimitsFragment {
306+ min : Some ( Quantity ( "100m" . to_owned ( ) ) ) ,
307+ max : Some ( Quantity ( "400m" . to_owned ( ) ) ) ,
308+ } ,
309+ memory : MemoryLimitsFragment {
310+ limit : Some ( Quantity ( "512Mi" . to_owned ( ) ) ) ,
311+ runtime_limits : NoRuntimeLimitsFragment { } ,
312+ } ,
313+ storage : HbaseStorageConfigFragment { } ,
314+ } ,
315+ HbaseRole :: Master => ResourcesFragment {
316+ cpu : CpuLimitsFragment {
317+ min : Some ( Quantity ( "250m" . to_owned ( ) ) ) ,
318+ max : Some ( Quantity ( "1" . to_owned ( ) ) ) ,
319+ } ,
320+ memory : MemoryLimitsFragment {
321+ limit : Some ( Quantity ( "1Gi" . to_owned ( ) ) ) ,
322+ runtime_limits : NoRuntimeLimitsFragment { } ,
323+ } ,
324+ storage : HbaseStorageConfigFragment { } ,
300325 } ,
301- storage : HbaseStorageConfigFragment { } ,
302- } ;
303-
304- RegionServerConfigFragment {
305- hbase_rootdir : None ,
306- hbase_opts : None ,
307- resources,
308- logging : product_logging:: spec:: default_logging ( ) ,
309- affinity : get_affinity (
310- cluster_name,
311- & HbaseRole :: RegionServer ,
312- hdfs_discovery_cm_name,
313- ) ,
314- graceful_shutdown_timeout : Some ( * DEFAULT_REGION_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT ) ,
315- region_mover : RegionMoverFragment :: default ( ) ,
316326 }
317327}
318328
319- fn default_rest_config ( cluster_name : & str , hdfs_discovery_cm_name : & str ) -> HbaseConfigFragment {
320- let resources = ResourcesFragment {
321- cpu : CpuLimitsFragment {
322- min : Some ( Quantity ( "100m" . to_owned ( ) ) ) ,
323- max : Some ( Quantity ( "400m" . to_owned ( ) ) ) ,
324- } ,
325- memory : MemoryLimitsFragment {
326- limit : Some ( Quantity ( "512Mi" . to_owned ( ) ) ) ,
327- runtime_limits : NoRuntimeLimitsFragment { } ,
328- } ,
329- storage : HbaseStorageConfigFragment { } ,
330- } ;
331-
332- HbaseConfigFragment {
333- hbase_rootdir : None ,
334- hbase_opts : None ,
335- resources,
336- logging : product_logging:: spec:: default_logging ( ) ,
337- affinity : get_affinity ( cluster_name, & HbaseRole :: RestServer , hdfs_discovery_cm_name) ,
338- graceful_shutdown_timeout : Some ( DEFAULT_REST_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT ) ,
339- }
329+ #[ derive( Debug , Clone ) ]
330+ enum AnyConfigFragment {
331+ RegionServer ( RegionServerConfigFragment ) ,
332+ RestServer ( HbaseConfigFragment ) ,
333+ Master ( HbaseConfigFragment ) ,
340334}
341335
342- fn default_master_config ( cluster_name : & str , hdfs_discovery_cm_name : & str ) -> HbaseConfigFragment {
343- let resources = ResourcesFragment {
344- cpu : CpuLimitsFragment {
345- min : Some ( Quantity ( "250m" . to_owned ( ) ) ) ,
346- max : Some ( Quantity ( "1" . to_owned ( ) ) ) ,
347- } ,
348- memory : MemoryLimitsFragment {
349- limit : Some ( Quantity ( "1Gi" . to_owned ( ) ) ) ,
350- runtime_limits : NoRuntimeLimitsFragment { } ,
351- } ,
352- storage : HbaseStorageConfigFragment { } ,
353- } ;
336+ impl AnyConfigFragment {
337+ fn merge ( self , other : & AnyConfigFragment ) -> Result < Self , Error > {
338+ match ( self , other) {
339+ ( AnyConfigFragment :: RegionServer ( mut me) , AnyConfigFragment :: RegionServer ( you) ) => {
340+ me. merge ( you) ;
341+ Ok ( AnyConfigFragment :: RegionServer ( me. clone ( ) ) )
342+ }
343+ ( AnyConfigFragment :: RestServer ( mut me) , AnyConfigFragment :: RestServer ( you) ) => {
344+ me. merge ( you) ;
345+ Ok ( AnyConfigFragment :: RestServer ( me. clone ( ) ) )
346+ }
347+ ( AnyConfigFragment :: Master ( mut me) , AnyConfigFragment :: Master ( you) ) => {
348+ me. merge ( you) ;
349+ Ok ( AnyConfigFragment :: Master ( me. clone ( ) ) )
350+ }
351+ ( _, _) => Err ( Error :: IncompatibleMergeTypes ) ,
352+ }
353+ }
354354
355- HbaseConfigFragment {
356- hbase_rootdir : None ,
357- hbase_opts : None ,
358- resources,
359- logging : product_logging:: spec:: default_logging ( ) ,
360- affinity : get_affinity ( cluster_name, & HbaseRole :: Master , hdfs_discovery_cm_name) ,
361- graceful_shutdown_timeout : Some ( DEFAULT_MASTER_GRACEFUL_SHUTDOWN_TIMEOUT ) ,
355+ fn default_for (
356+ role : & HbaseRole ,
357+ cluster_name : & str ,
358+ hdfs_discovery_cm_name : & str ,
359+ ) -> AnyConfigFragment {
360+ match role {
361+ HbaseRole :: RegionServer => {
362+ AnyConfigFragment :: RegionServer ( RegionServerConfigFragment {
363+ hbase_rootdir : None ,
364+ hbase_opts : None ,
365+ resources : default_resources ( role) ,
366+ logging : product_logging:: spec:: default_logging ( ) ,
367+ affinity : get_affinity ( cluster_name, role, hdfs_discovery_cm_name) ,
368+ graceful_shutdown_timeout : Some (
369+ * DEFAULT_REGION_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT ,
370+ ) ,
371+ region_mover : RegionMoverFragment :: default ( ) ,
372+ } )
373+ }
374+ HbaseRole :: RestServer => AnyConfigFragment :: RestServer ( HbaseConfigFragment {
375+ hbase_rootdir : None ,
376+ hbase_opts : None ,
377+ resources : default_resources ( role) ,
378+ logging : product_logging:: spec:: default_logging ( ) ,
379+ affinity : get_affinity ( cluster_name, role, hdfs_discovery_cm_name) ,
380+ graceful_shutdown_timeout : Some ( DEFAULT_REST_SERVER_GRACEFUL_SHUTDOWN_TIMEOUT ) ,
381+ } ) ,
382+ HbaseRole :: Master => AnyConfigFragment :: Master ( HbaseConfigFragment {
383+ hbase_rootdir : None ,
384+ hbase_opts : None ,
385+ resources : default_resources ( role) ,
386+ logging : product_logging:: spec:: default_logging ( ) ,
387+ affinity : get_affinity ( cluster_name, role, hdfs_discovery_cm_name) ,
388+ graceful_shutdown_timeout : Some ( DEFAULT_MASTER_GRACEFUL_SHUTDOWN_TIMEOUT ) ,
389+ } ) ,
390+ }
362391 }
363392}
364393
@@ -702,136 +731,98 @@ impl HbaseCluster {
702731 role_group : & str ,
703732 hdfs_discovery_cm_name : & str ,
704733 ) -> Result < AnyServiceConfig , Error > {
705- match role {
706- HbaseRole :: Master => {
707- let config = self . merged_master_config ( role_group, hdfs_discovery_cm_name) ?;
708- Ok ( AnyServiceConfig :: Master ( config) )
709- }
710- HbaseRole :: RegionServer => {
711- let config = self . merged_regionserver_config ( role_group, hdfs_discovery_cm_name) ?;
712- Ok ( AnyServiceConfig :: RegionServer ( config) )
713- }
714- HbaseRole :: RestServer => {
715- let config = self . merged_rest_config ( role_group, hdfs_discovery_cm_name) ?;
716- Ok ( AnyServiceConfig :: RestServer ( config) )
717- }
718- }
719- }
720-
721- fn merged_regionserver_config (
722- & self ,
723- role_group : & str ,
724- hdfs_discovery_cm_name : & str ,
725- ) -> Result < RegionServerConfig , Error > {
726- let role = HbaseRole :: RegionServer ;
727-
728734 // Initialize the result with all default values as baseline
729- let conf_defaults = default_regionserver_config ( & self . name_any ( ) , hdfs_discovery_cm_name) ;
730-
731- let role = self
732- . spec
733- . region_servers
734- . clone ( )
735- . context ( MissingHbaseRoleSnafu {
736- role : role. to_string ( ) ,
737- } ) ?;
738-
739- // Retrieve role resource config
740- let mut conf_role = role. config . config . to_owned ( ) ;
741-
742- // Retrieve rolegroup specific resource config
743- let mut conf_rolegroup = role
744- . role_groups
745- . get ( role_group)
746- . map ( |rg| rg. config . config . clone ( ) )
747- . unwrap_or_default ( ) ;
748-
749- // Merge more specific configs into default config
750- // Hierarchy is:
751- // 1. RoleGroup
752- // 2. Role
753- // 3. Default
754- conf_role. merge ( & conf_defaults) ;
755- conf_rolegroup. merge ( & conf_role) ;
735+ let defaults =
736+ AnyConfigFragment :: default_for ( role, & self . name_any ( ) , hdfs_discovery_cm_name) ;
756737
757- tracing:: debug!( "Merged config: {:?}" , conf_rolegroup) ;
758- fragment:: validate ( conf_rolegroup) . context ( FragmentValidationFailureSnafu )
759- }
760-
761- fn merged_rest_config (
762- & self ,
763- role_group : & str ,
764- hdfs_discovery_cm_name : & str ,
765- ) -> Result < HbaseConfig , Error > {
766- let role = HbaseRole :: RestServer ;
738+ let ( mut role_config, mut role_group_config) = match role {
739+ HbaseRole :: RegionServer => {
740+ let role = self
741+ . spec
742+ . region_servers
743+ . clone ( )
744+ . context ( MissingHbaseRoleSnafu {
745+ role : role. to_string ( ) ,
746+ } ) ?;
767747
768- // Initialize the result with all default values as baseline
769- let conf_defaults = default_rest_config ( & self . name_any ( ) , hdfs_discovery_cm_name) ;
770-
771- let role = self
772- . spec
773- . rest_servers
774- . clone ( )
775- . context ( MissingHbaseRoleSnafu {
776- role : role. to_string ( ) ,
777- } ) ?;
778-
779- // Retrieve role resource config
780- let mut conf_role = role. config . config . to_owned ( ) ;
781-
782- // Retrieve rolegroup specific resource config
783- let mut conf_rolegroup = role
784- . role_groups
785- . get ( role_group)
786- . map ( |rg| rg. config . config . clone ( ) )
787- . unwrap_or_default ( ) ;
748+ let role_config = role. config . config . to_owned ( ) ;
749+ let role_group_config = role
750+ . role_groups
751+ . get ( role_group)
752+ . map ( |rg| rg. config . config . clone ( ) )
753+ . unwrap_or_default ( ) ;
788754
789- // Merge more specific configs into default config
790- // Hierarchy is:
791- // 1. RoleGroup
792- // 2. Role
793- // 3. Default
794- conf_role. merge ( & conf_defaults) ;
795- conf_rolegroup. merge ( & conf_role) ;
755+ (
756+ AnyConfigFragment :: RegionServer ( role_config) ,
757+ AnyConfigFragment :: RegionServer ( role_group_config) ,
758+ )
759+ }
760+ HbaseRole :: RestServer => {
761+ let role = self
762+ . spec
763+ . rest_servers
764+ . clone ( )
765+ . context ( MissingHbaseRoleSnafu {
766+ role : role. to_string ( ) ,
767+ } ) ?;
796768
797- tracing:: debug!( "Merged config: {:?}" , conf_rolegroup) ;
798- fragment:: validate ( conf_rolegroup) . context ( FragmentValidationFailureSnafu )
799- }
769+ let role_config = role. config . config . to_owned ( ) ;
800770
801- fn merged_master_config (
802- & self ,
803- role_group : & str ,
804- hdfs_discovery_cm_name : & str ,
805- ) -> Result < HbaseConfig , Error > {
806- let role = HbaseRole :: Master ;
771+ let role_group_config = role
772+ . role_groups
773+ . get ( role_group)
774+ . map ( |rg| rg. config . config . clone ( ) )
775+ . unwrap_or_default ( ) ;
807776
808- // Initialize the result with all default values as baseline
809- let conf_defaults = default_master_config ( & self . name_any ( ) , hdfs_discovery_cm_name) ;
777+ // Retrieve role resource config
778+ (
779+ AnyConfigFragment :: RestServer ( role_config) ,
780+ AnyConfigFragment :: RestServer ( role_group_config) ,
781+ )
782+ }
783+ HbaseRole :: Master => {
784+ let role = self . spec . masters . clone ( ) . context ( MissingHbaseRoleSnafu {
785+ role : role. to_string ( ) ,
786+ } ) ?;
810787
811- let role = self . spec . masters . clone ( ) . context ( MissingHbaseRoleSnafu {
812- role : role. to_string ( ) ,
813- } ) ?;
788+ let role_config = role. config . config . to_owned ( ) ;
814789
815- // Retrieve role resource config
816- let mut conf_role = role. config . config . to_owned ( ) ;
790+ // Retrieve rolegroup specific resource config
791+ let role_group_config = role
792+ . role_groups
793+ . get ( role_group)
794+ . map ( |rg| rg. config . config . clone ( ) )
795+ . unwrap_or_default ( ) ;
817796
818- // Retrieve rolegroup specific resource config
819- let mut conf_rolegroup = role
820- . role_groups
821- . get ( role_group)
822- . map ( |rg| rg. config . config . clone ( ) )
823- . unwrap_or_default ( ) ;
797+ // Retrieve role resource config
798+ (
799+ AnyConfigFragment :: Master ( role_config) ,
800+ AnyConfigFragment :: Master ( role_group_config) ,
801+ )
802+ }
803+ } ;
824804
825805 // Merge more specific configs into default config
826806 // Hierarchy is:
827807 // 1. RoleGroup
828808 // 2. Role
829809 // 3. Default
830- conf_role . merge ( & conf_defaults ) ;
831- conf_rolegroup . merge ( & conf_role ) ;
810+ role_config = role_config . merge ( & defaults ) ? ;
811+ role_group_config = role_group_config . merge ( & role_config ) ? ;
832812
833- tracing:: debug!( "Merged config: {:?}" , conf_rolegroup) ;
834- fragment:: validate ( conf_rolegroup) . context ( FragmentValidationFailureSnafu )
813+ tracing:: debug!( "Merged config: {:?}" , role_group_config) ;
814+
815+ Ok ( match role_group_config {
816+ AnyConfigFragment :: RegionServer ( conf) => AnyServiceConfig :: RegionServer (
817+ fragment:: validate ( conf) . context ( FragmentValidationFailureSnafu ) ?,
818+ ) ,
819+ AnyConfigFragment :: RestServer ( conf) => AnyServiceConfig :: RestServer (
820+ fragment:: validate ( conf) . context ( FragmentValidationFailureSnafu ) ?,
821+ ) ,
822+ AnyConfigFragment :: Master ( conf) => AnyServiceConfig :: Master (
823+ fragment:: validate ( conf) . context ( FragmentValidationFailureSnafu ) ?,
824+ ) ,
825+ } )
835826 }
836827
837828 // The result type is only defined once, there is no value in extracting it into a type definition.
0 commit comments