@@ -69,6 +69,10 @@ var args struct {
69
69
allowedRegistriesForImport string
70
70
platformAllowlist string
71
71
additionalTrustedCa string
72
+
73
+ // SDN -> OVN Migration
74
+ networkType string
75
+ ovnInternalSubnets string
72
76
}
73
77
74
78
var clusterRegistryConfigArgs * clusterregistryconfig.ClusterRegistryConfigArgs
@@ -186,6 +190,23 @@ func init() {
186
190
"" ,
187
191
"Account ID used for billing subscriptions purchased through the AWS console for ROSA" ,
188
192
)
193
+
194
+ flags .StringVar (
195
+ & args .networkType ,
196
+ "network-type" ,
197
+ "" ,
198
+ "Migrate a cluster's network type from OpenShiftSDN to OVN-Kubernetes" ,
199
+ )
200
+
201
+ flags .StringVar (
202
+ & args .ovnInternalSubnets ,
203
+ ocm .OvnInternalSubnetsFlagName ,
204
+ "" ,
205
+ "OVN-Kubernetes internal subnet configuration for migrating 'network-type' from OpenShiftSDN -> " +
206
+ "OVN-Kubernetes. Must be supplied as a string=value pair with any of 'join', 'transit', 'masquerade' " +
207
+ "followed by a CIDR. \n Example: '--ovn-internal-subnets=\" join=192.168.255.0/24,transit=192.168.255.0/24," +
208
+ "masquerade=192.168.255.0/24\" '" ,
209
+ )
189
210
}
190
211
191
212
func run (cmd * cobra.Command , _ []string ) {
@@ -223,6 +244,18 @@ func run(cmd *cobra.Command, _ []string) {
223
244
os .Exit (1 )
224
245
}
225
246
247
+ ovnInternalSubnets , err := validateOvnInternalSubnetConfiguration ()
248
+ if err != nil {
249
+ r .Reporter .Errorf (fmt .Sprintf ("%s" , err ))
250
+ os .Exit (1 )
251
+ }
252
+
253
+ networkType , err := validateNetworkType ()
254
+ if err != nil {
255
+ r .Reporter .Errorf (fmt .Sprintf ("%s" , err ))
256
+ os .Exit (1 )
257
+ }
258
+
226
259
if interactive .Enabled () {
227
260
r .Reporter .Infof ("Interactive mode enabled.\n " +
228
261
"Any optional fields can be ignored and will not be updated." )
@@ -702,6 +735,93 @@ func run(cmd *cobra.Command, _ []string) {
702
735
}
703
736
}
704
737
738
+ // SDN -> OVN Migration
739
+ var clusterNetworkType string
740
+ if ! cmd .Flags ().Changed (ocm .NetworkTypeFlagName ) {
741
+ var ok bool
742
+ if cluster .Network () == nil {
743
+ ok = false
744
+ } else {
745
+ networkType , ok = cluster .Network ().GetType ()
746
+ clusterNetworkType = networkType // Store the cluster's current network type for interactive usage
747
+ }
748
+ if ! ok {
749
+ r .Reporter .Errorf ("Unable to get cluster's network type" )
750
+ os .Exit (1 )
751
+ }
752
+ }
753
+
754
+ var migrateNetworkType bool
755
+ // Only prompt user with migrating the cluster's network type when it is not OVN-Kubernetes
756
+ if interactive .Enabled () && clusterNetworkType != "" && clusterNetworkType != ocm .NetworkTypeOvn &&
757
+ clusterNetworkType != ocm .NetworkTypeOvnAlias {
758
+
759
+ migrateNetworkType , err = interactive .GetBool (interactive.Input {
760
+ Question : "Migrate cluster network type from OpenShiftSDN -> OVN-Kubernetes" ,
761
+ Help : "Clusters are required to migrate from network type 'OpenShiftSDN' to 'OVN-Kubernetes', this allows " +
762
+ "you to do this along with your cluster changes" ,
763
+ Default : false ,
764
+ })
765
+
766
+ if err != nil {
767
+ r .Reporter .Errorf ("%s" , err )
768
+ os .Exit (1 )
769
+ }
770
+
771
+ if migrateNetworkType {
772
+ migrateNetworkType , err = confirmMigration ()
773
+
774
+ if err != nil {
775
+ r .Reporter .Errorf ("%s" , err )
776
+ os .Exit (1 )
777
+ }
778
+ }
779
+
780
+ if migrateNetworkType && interactive .Enabled () {
781
+ networkType , err = interactive .GetString (interactive.Input {
782
+ Question : "Network type for cluster" ,
783
+ Help : cmd .Flags ().Lookup (ocm .NetworkTypeFlagName ).Usage ,
784
+ Default : ocm .NetworkTypeOvn ,
785
+ })
786
+ if err != nil {
787
+ r .Reporter .Errorf ("Expected a valid value: %v" , err )
788
+ os .Exit (1 )
789
+ }
790
+
791
+ ovnSubnets , err := interactive .GetString (interactive.Input {
792
+ Question : "OVN-Kubernetes internal subnet configuration for cluster" ,
793
+ Help : cmd .Flags ().Lookup (ocm .OvnInternalSubnetsFlagName ).Usage ,
794
+ Default : ovnInternalSubnets ,
795
+ Options : []string {ocm .SubnetConfigTransit , ocm .SubnetConfigJoin , ocm .SubnetConfigMasquerade },
796
+ Required : false ,
797
+ })
798
+ if err != nil {
799
+ r .Reporter .Errorf ("Expected a valid value: %v" , err )
800
+ }
801
+ ovnInternalSubnets , err = ocm .ParseAndValidateOvnInternalSubnets (ovnSubnets )
802
+ if err != nil {
803
+ r .Reporter .Errorf ("Failed to parse '%s': %s" , ocm .OvnInternalSubnetsFlagName , err )
804
+ }
805
+ }
806
+ }
807
+
808
+ if cmd .Flags ().Changed (ocm .NetworkTypeFlagName ) && networkType == ocm .NetworkTypeOvn {
809
+
810
+ migrateNetworkType , err = confirmMigration ()
811
+
812
+ if err != nil {
813
+ r .Reporter .Errorf ("%s" , err )
814
+ os .Exit (1 )
815
+ }
816
+ }
817
+
818
+ if networkType == ocm .NetworkTypeOvn && migrateNetworkType {
819
+ clusterConfig .NetworkType = networkType
820
+ if len (ovnInternalSubnets ) > 0 {
821
+ clusterConfig .OvnInternalSubnetConfiguration = ovnInternalSubnets
822
+ }
823
+ }
824
+
705
825
var billingAccount string
706
826
if cmd .Flags ().Changed ("billing-account" ) {
707
827
billingAccount = args .billingAccount
@@ -841,6 +961,32 @@ func validateExpiration() (expiration time.Time, err error) {
841
961
return
842
962
}
843
963
964
+ // SDN -> OVN migration subnet configuration validator
965
+ func validateOvnInternalSubnetConfiguration () (ovnInternalSubnets map [string ]string , err error ) {
966
+ if len (args .ovnInternalSubnets ) > 0 {
967
+ if args .networkType == "" {
968
+ err = fmt .Errorf ("Expected a value for %s when supplying the flag %s" , ocm .NetworkTypeFlagName ,
969
+ ocm .OvnInternalSubnetsFlagName )
970
+ return
971
+ }
972
+ ovnInternalSubnets , err = ocm .ParseAndValidateOvnInternalSubnets (args .ovnInternalSubnets )
973
+ }
974
+ return
975
+ }
976
+
977
+ // SDN -> OVN migration network type validator (one option)
978
+ func validateNetworkType () (networkConfig string , err error ) {
979
+ if len (args .networkType ) > 0 {
980
+ if args .networkType != ocm .NetworkTypeOvn && args .networkType != ocm .NetworkTypeOvnAlias {
981
+ err = fmt .Errorf ("Incorrect network type '%s', please use '%s' or remove the flag" ,
982
+ args .networkType , ocm .NetworkTypeOvn )
983
+ } else {
984
+ networkConfig = ocm .NetworkTypeOvn // allows use of alias (OVN-Kubernetes)- but sets it to correct value for API
985
+ }
986
+ }
987
+ return
988
+ }
989
+
844
990
// parseRFC3339 parses an RFC3339 date in either RFC3339Nano or RFC3339 format.
845
991
func parseRFC3339 (s string ) (time.Time , error ) {
846
992
if t , timeErr := time .Parse (time .RFC3339Nano , s ); timeErr == nil {
@@ -979,3 +1125,14 @@ func BuildClusterConfigWithRegistry(clusterConfig ocm.Spec, allowedRegistries []
979
1125
clusterConfig .AllowedRegistriesForImport = allowedRegistriesForImport
980
1126
return clusterConfig , nil
981
1127
}
1128
+
1129
+ func confirmMigration () (bool , error ) {
1130
+ return interactive .GetBool (interactive.Input {
1131
+ Question : "Changing the network plugin will reboot cluster nodes, can not be interrupted or rolled " +
1132
+ "back, and can not be combined with other operations such as cluster upgrades. \n \n Confirm that " +
1133
+ "you want to proceed with migrating from 'OpenShiftSDN' to 'OVN-Kubernetes" ,
1134
+ Help : "Confirm that you are wanting to migrate your cluster's network type, it may be safer to do " +
1135
+ "this migration with no other changes" ,
1136
+ Default : false ,
1137
+ })
1138
+ }
0 commit comments