@@ -27,6 +27,7 @@ import (
2727 "errors"
2828 "fmt"
2929 "os"
30+ "regexp"
3031 "strconv"
3132 "strings"
3233 "time"
@@ -112,16 +113,6 @@ func (d *domainCLIImpl) RegisterDomain(c *cli.Context) error {
112113 return commoncli .Problem (fmt .Sprintf ("Option %s format is invalid." , FlagIsGlobalDomain ), err )
113114 }
114115 }
115- isActiveActiveDomain := false
116- if c .IsSet (FlagIsActiveActiveDomain ) {
117- isActiveActiveDomain , err = strconv .ParseBool (c .String (FlagIsActiveActiveDomain ))
118- if err != nil {
119- return commoncli .Problem (fmt .Sprintf ("Option %s format is invalid." , FlagIsActiveActiveDomain ), err )
120- }
121-
122- // Also set isGlobalDomain to true if it is active-active domain
123- isGlobalDomain = isActiveActiveDomain
124- }
125116
126117 var domainData * flag.StringMap
127118 if c .IsSet (FlagDomainData ) {
@@ -136,17 +127,9 @@ func (d *domainCLIImpl) RegisterDomain(c *cli.Context) error {
136127
137128 activeClusterName := ""
138129 if c .IsSet (FlagActiveClusterName ) {
139- if isActiveActiveDomain {
140- return commoncli .Problem ("Option --active_cluster is not supported for active-active domain. Use --active_clusters_by_region instead." , nil )
141- }
142130 activeClusterName = c .String (FlagActiveClusterName )
143131 }
144132
145- activeClustersByRegion , err := parseActiveClustersByRegion (c , isActiveActiveDomain )
146- if err != nil {
147- return err
148- }
149-
150133 var clusters []* types.ClusterReplicationConfiguration
151134 if c .IsSet (FlagClusters ) {
152135 for _ , clusterStr := range c .StringSlice (FlagClusters ) {
@@ -165,6 +148,15 @@ func (d *domainCLIImpl) RegisterDomain(c *cli.Context) error {
165148 return fmt .Errorf ("failed to parse %s flag: %w" , FlagVisibilityArchivalStatus , err )
166149 }
167150
151+ var activeClusters * types.ActiveClusters
152+ if c .IsSet (FlagActiveClusters ) {
153+ ac , err := parseActiveClustersByClusterAttribute (c .String (FlagActiveClusters ))
154+ if err != nil {
155+ return err
156+ }
157+ activeClusters = & ac
158+ }
159+
168160 request := & types.RegisterDomainRequest {
169161 Name : domainName ,
170162 Description : description ,
@@ -173,7 +165,7 @@ func (d *domainCLIImpl) RegisterDomain(c *cli.Context) error {
173165 WorkflowExecutionRetentionPeriodInDays : int32 (retentionDays ),
174166 Clusters : clusters ,
175167 ActiveClusterName : activeClusterName ,
176- ActiveClustersByRegion : activeClustersByRegion ,
168+ ActiveClusters : activeClusters ,
177169 SecurityToken : securityToken ,
178170 HistoryArchivalStatus : has ,
179171 HistoryArchivalURI : c .String (FlagHistoryArchivalURI ),
@@ -225,23 +217,16 @@ func (d *domainCLIImpl) UpdateDomain(c *cli.Context) error {
225217 ActiveClusterName : common .StringPtr (activeCluster ),
226218 FailoverTimeoutInSeconds : failoverTimeout ,
227219 }
228- } else if c .IsSet (FlagActiveClustersByRegion ) { // active-active domain failover
229- activeClustersByRegion , err := parseActiveClustersByRegion ( c , true )
220+ } else if c .IsSet (FlagActiveClusters ) { // active-active domain failover
221+ activeClusters , err := parseActiveClustersByClusterAttribute ( c . String ( FlagActiveClusters ) )
230222 if err != nil {
231223 return err
232224 }
233225
234- acbr := make (map [string ]types.ActiveClusterInfo )
235- for region , cluster := range activeClustersByRegion {
236- acbr [region ] = types.ActiveClusterInfo {
237- ActiveClusterName : cluster ,
238- }
239- }
240-
241226 updateRequest = & types.UpdateDomainRequest {
242227 Name : domainName ,
243228 ActiveClusters : & types.ActiveClusters {
244- ActiveClustersByRegion : acbr ,
229+ AttributeScopes : activeClusters . AttributeScopes ,
245230 },
246231 }
247232 } else {
@@ -669,26 +654,27 @@ type ActiveClusterInfoRow struct {
669654}
670655
671656type DomainRow struct {
672- Name string `header:"Name"`
673- UUID string `header:"UUID"`
674- Description string
675- OwnerEmail string
676- DomainData map [string ]string `header:"Domain Data"`
677- Status types.DomainStatus `header:"Status"`
678- IsGlobal bool `header:"Is Global Domain"`
679- ActiveCluster string `header:"Active Cluster"`
680- Clusters []string `header:"Clusters"`
681- RetentionDays int32 `header:"Retention Days"`
682- EmitMetrics bool
683- HistoryArchivalStatus types.ArchivalStatus `header:"History Archival Status"`
684- HistoryArchivalURI string `header:"History Archival URI"`
685- VisibilityArchivalStatus types.ArchivalStatus `header:"Visibility Archival Status"`
686- VisibilityArchivalURI string `header:"Visibility Archival URI"`
687- BadBinaries []BadBinaryRow
688- FailoverInfo * FailoverInfoRow
689- LongRunningWorkFlowNum * int
690- IsActiveActiveDomain bool
691- ActiveClustersByRegion []ActiveClusterInfoRow
657+ Name string `header:"Name"`
658+ UUID string `header:"UUID"`
659+ Description string
660+ OwnerEmail string
661+ DomainData map [string ]string `header:"Domain Data"`
662+ Status types.DomainStatus `header:"Status"`
663+ IsGlobal bool `header:"Is Global Domain"`
664+ ActiveCluster string `header:"Active Cluster"`
665+ Clusters []string `header:"Clusters"`
666+ RetentionDays int32 `header:"Retention Days"`
667+ EmitMetrics bool
668+ HistoryArchivalStatus types.ArchivalStatus `header:"History Archival Status"`
669+ HistoryArchivalURI string `header:"History Archival URI"`
670+ VisibilityArchivalStatus types.ArchivalStatus `header:"Visibility Archival Status"`
671+ VisibilityArchivalURI string `header:"Visibility Archival URI"`
672+ BadBinaries []BadBinaryRow
673+ FailoverInfo * FailoverInfoRow
674+ LongRunningWorkFlowNum * int
675+ IsActiveActiveDomain bool
676+ ActiveClustersByRegion []ActiveClusterInfoRow // todo (david.porter) remove this as it's not in use
677+ ActiveClustersByClusterAttribute []ActiveClusterInfoRow
692678}
693679
694680type DomainMigrationRow struct {
@@ -732,7 +718,7 @@ func newDomainRow(domain *types.DescribeDomainResponse) DomainRow {
732718 VisibilityArchivalURI : domain .Configuration .GetVisibilityArchivalURI (),
733719 BadBinaries : newBadBinaryRows (domain .Configuration .BadBinaries ),
734720 FailoverInfo : newFailoverInfoRow (domain .FailoverInfo ),
735- IsActiveActiveDomain : domain .ReplicationConfiguration .GetActiveClusters () != nil ,
721+ IsActiveActiveDomain : domain .ReplicationConfiguration .IsActiveActiveDomain () ,
736722 ActiveClustersByRegion : newActiveClustersByRegion (domain .ReplicationConfiguration .GetActiveClusters ()),
737723 }
738724}
@@ -972,27 +958,42 @@ func clustersToStrings(clusters []*types.ClusterReplicationConfiguration) []stri
972958 return res
973959}
974960
975- func parseActiveClustersByRegion (c * cli.Context , isActiveActiveDomain bool ) (map [string ]string , error ) {
976- var activeClustersByRegion map [string ]string
977- if c .IsSet (FlagActiveClustersByRegion ) {
978- if ! isActiveActiveDomain {
979- return nil , commoncli .Problem ("Option --active_clusters_by_region is only supported for active-active domain. Use --active_cluster instead." , nil )
961+ func parseActiveClustersByClusterAttribute (clusters string ) (types.ActiveClusters , error ) {
962+ split := regexp .MustCompile (`(?P<attribute>[a-zA-Z0-9_]+).(?P<scope>[a-zA-Z0-9_]+):(?P<name>[a-zA-Z0-9_]+)` )
963+ matches := split .FindAllStringSubmatch (clusters , - 1 )
964+ if len (matches ) == 0 {
965+ return types.ActiveClusters {}, fmt .Errorf ("option %s format is invalid. Expected format is 'region.dca:dev2_dca,region.phx:dev2_phx'" , FlagActiveClusters )
966+ }
967+
968+ out := types.ActiveClusters {
969+ AttributeScopes : map [string ]types.ClusterAttributeScope {},
970+ }
971+
972+ for _ , match := range matches {
973+ if len (match ) != 4 {
974+ return types.ActiveClusters {}, fmt .Errorf ("option %s format is invalid. Expected format is 'region.dca:dev2_dca,region.phx:dev2_phx'" , FlagActiveClusters )
980975 }
976+ attribute := match [1 ]
977+ scope := match [2 ]
978+ name := match [3 ]
981979
982- activeClustersByRegion = make (map [string ]string )
983- for _ , regionCluster := range c .StringSlice (FlagActiveClustersByRegion ) {
984- splitted := strings .Split (regionCluster , ":" )
985- if len (splitted ) != 2 {
986- return nil , commoncli .Problem (fmt .Sprintf ("Option --%s format is invalid. Expected format is 'region1:cluster1,region2:cluster2'" , FlagActiveClustersByRegion ), nil )
980+ existing , ok := out .AttributeScopes [attribute ]
981+ if ! ok {
982+ out .AttributeScopes [attribute ] = types.ClusterAttributeScope {
983+ ClusterAttributes : map [string ]types.ActiveClusterInfo {
984+ scope : {ActiveClusterName : name },
985+ },
987986 }
988- region , cluster := strings .TrimSpace (splitted [0 ]), strings .TrimSpace (splitted [1 ])
989- activeClustersByRegion [region ] = cluster
987+ } else {
988+ if _ , ok := existing .ClusterAttributes [scope ]; ok {
989+ return types.ActiveClusters {}, fmt .Errorf ("option active_clusters format is invalid. the key %q was duplicated. This can only map to a single active cluster" , scope )
990+ }
991+ existing .ClusterAttributes [scope ] = types.ActiveClusterInfo {ActiveClusterName : name }
992+ out .AttributeScopes [attribute ] = existing
990993 }
991- }
992994
993- if isActiveActiveDomain && len (activeClustersByRegion ) == 0 {
994- return nil , commoncli .Problem ("Option --active_clusters_by_region is required for active-active domain." , nil )
995+ out .AttributeScopes [attribute ].ClusterAttributes [scope ] = types.ActiveClusterInfo {ActiveClusterName : name }
995996 }
996997
997- return activeClustersByRegion , nil
998+ return out , nil
998999}
0 commit comments