From d6b9660b798969481c7cc5367cbaa4c83d2bd500 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesper=20S=C3=B8rensen?= Date: Wed, 17 Aug 2022 17:25:10 +0200 Subject: [PATCH] Allow configuring RKE ACI network provider (#912) * Add and doc rke aci network provider fields (required and sensitive) * Add fields introduced in ACI-CNI 5.2.3.2 --- docs/resources/cluster.md | 80 +++ rancher2/schema_cluster_rke_config_network.go | 324 ++++++++++++ .../structure_cluster_rke_config_network.go | 481 ++++++++++++++++++ ...ructure_cluster_rke_config_network_test.go | 236 +++++++++ 4 files changed, 1121 insertions(+) diff --git a/docs/resources/cluster.md b/docs/resources/cluster.md index 6f73be47..cdc12896 100644 --- a/docs/resources/cluster.md +++ b/docs/resources/cluster.md @@ -999,6 +999,7 @@ The following attributes are exported: ##### Arguments +* `aci_network_provider` - (Optional/Computed) ACI provider config for RKE network (list maxitems:63) * `calico_network_provider` - (Optional/Computed) Calico provider config for RKE network (list maxitems:1) * `canal_network_provider` - (Optional/Computed) Canal provider config for RKE network (list maxitems:1) * `flannel_network_provider` - (Optional/Computed) Flannel provider config for RKE network (list maxitems:1) @@ -1008,6 +1009,85 @@ The following attributes are exported: * `plugin` - (Optional/Computed) Plugin for RKE network. `canal` (default), `flannel`, `calico`, `none` and `weave` are supported. (string) * `tolerations` - (Optional) Network add-on tolerations (list) +##### `aci_network_provider` + +###### Arguments + +* `aep` - (Required) Attachable entity profile (string) +* `apic_hosts` - (Required) List of APIC hosts to connect for APIC API (list) +* `apic_refresh_ticker_adjust` - (Optional) APIC refresh ticker adjust amount (string) +* `apic_refresh_time` - (Optional) APIC refresh time in seconds (string) +* `apic_subscription_delay` - (Optional) APIC subscription delay amount (string) +* `apic_user_crt` - (Required/Sensitive) APIC user certificate (string) +* `apic_user_key` - (Required/Sensitive) APIC user key (string) +* `apic_user_name` - (Required) APIC user name (string) +* `capic` - (Optional) cAPIC cloud (string) +* `controller_log_level` - (Optional) Log level for ACI controller (string) +* `disable_periodic_snat_global_info_sync` - (Optional) Whether to disable periodic SNAT global info sync (string) +* `disable_wait_for_network` - (Optional) Whether to disable waiting for network (string) +* `drop_log_enable` - (Optional) Whether to enable drop log (string) +* `duration_wait_for_network` - (Optional) The duration to wait for network (string) +* `extern_dynamic` - (Required) Subnet to use for dynamic external IPs (string) +* `enable_endpoint_slice` - (Optional) Whether to enable endpoint slices (string) +* `encap_type` - (Required) Encap type: vxlan or vlan (string) +* `ep_registry` - (Optional) EP registry (string) +* `gbp_pod_subnet` - (Optional) GBH pod subnet (string) +* `host_agent_log_level` - (Optional) Log level for ACI host agent (string) +* `image_pull_policy` - (Optional) Image pull policy (string) +* `image_pull_secret` - (Optional) Image pull policy (string) +* `infra_vlan` - (Optional) The VLAN used by ACI infra (string) +* `install_istio` - (Optional) Whether to install Istio (string) +* `istio_profile` - (Optional) Istio profile name (string) +* `kafka_brokers` - (Optional) List of Kafka broker hosts (list) +* `kafka_client_crt` - (Optional) Kafka client certificate (string) +* `kafka_client_key` - (Optional) Kafka client key (string) +* `kube_api_vlan` - (Required) The VLAN used by the physdom for nodes (string) +* `l3out` - (Required) L3out (string) +* `l3out_external_networks` - (Required) L3out external networks (list) +* `max_nodes_svc_graph` - (Optional) Max nodes in service graph (string) +* `mcast_range_end` - (Required) End of mcast range (string) +* `mcast_range_start` - (Required) Start of mcast range (string) +* `mtu_head_room` - (Optional) MTU head room amount (string) +* `multus_disable` - (Optional) Whether to disable Multus (string) +* `no_priority_class` - (Optional) Whether to use priority class (string) +* `node_pod_if_enable` - (Optional) Whether to enable node pod interface (string) +* `node_subnet` - (Required) Subnet to use for nodes (string) +* `ovs_memory_limit` - (Optional) OVS memory limit (string) +* `opflex_log_level` - (Optional) Log level for ACI opflex (string) +* `opflex_client_ssl` - (Optional) Whether to use client SSL for Opflex (string) +* `opflex_device_delete_timeout` - (Optional) Opflex device delete timeout (string) +* `opflex_mode` - (Optional) Opflex mode (string) +* `opflex_server_port` - (Optional) Opflex server port (string) +* `overlay_vrf_name` - (Optional) Overlay VRF name (string) +* `pbr_tracking_non_snat` - (Optional) Policy-based routing tracking non snat (string) +* `pod_subnet_chunk_size` - (Optional) Pod subnet chunk size (string) +* `run_gbp_container` - (Optional) Whether to run GBP container (string) +* `run_opflex_server_container` - (Optional) Whether to run Opflex server container (string) +* `node_svc_subnet` - (Required) Subnet to use for service graph (string) +* `service_monitor_interval` - (Optional) Service monitor interval (string) +* `service_vlan` - (Required) The VLAN used by LoadBalancer services (string) +* `snat_contract_scope` - (Optional) Snat contract scope (string) +* `snat_namespace` - (Optional) Snat namespace (string) +* `snat_port_range_end` - (Optional) End of snat port range (string) +* `snat_port_range_start` - (Optional) End of snat port range (string) +* `snat_ports_per_node` - (Optional) Snat ports per node (string) +* `sriov_enable` - (Optional) Whether to enable SR-IOV (string) +* `extern_static` - (Required) Subnet to use for static external IPs (string) +* `subnet_domain_name` - (Optional) Subnet domain name (string) +* `system_id` - (Required) ACI system ID (string) +* `tenant` - (Optional) ACI tenant (string) +* `token` - (Required/Sensitive) ACI token (string) +* `use_aci_anywhere_crd` - (Optional) Whether to use ACI anywhere CRD (string) +* `use_aci_cni_priority_class` - (Optional) Whether to use ACI CNI priority class (string) +* `use_cluster_role` - (Optional) Whether to use cluster role (string) +* `use_host_netns_volume` - (Optional) Whether to use host netns volume (string) +* `use_opflex_server_volume` - (Optional) Whether use Opflex server volume (string) +* `use_privileged_container` - (Optional) Whether ACI containers should run as privileged (string) +* `vrf_name` - (Required) VRF name (string) +* `vrf_tenant` - (Required) VRF tenant (string) +* `vmm_controller` - (Optional) VMM controller configuration (string) +* `vmm_domain` - (Optional) VMM domain configuration (string) + ##### `calico_network_provider` ###### Arguments diff --git a/rancher2/schema_cluster_rke_config_network.go b/rancher2/schema_cluster_rke_config_network.go index 6c3177af..c8039a11 100644 --- a/rancher2/schema_cluster_rke_config_network.go +++ b/rancher2/schema_cluster_rke_config_network.go @@ -6,6 +6,7 @@ import ( ) const ( + networkPluginAciName = "aci" networkPluginCalicoName = "calico" networkPluginCanalName = "canal" networkPluginFlannelName = "flannel" @@ -16,6 +17,7 @@ const ( var ( networkPluginDefault = networkPluginCanalName networkPluginList = []string{ + networkPluginAciName, networkPluginCalicoName, networkPluginCanalName, networkPluginFlannelName, @@ -26,6 +28,320 @@ var ( //Schemas +func clusterRKEConfigNetworkAciFields() map[string]*schema.Schema { + s := map[string]*schema.Schema{ + "aep": { + Type: schema.TypeString, + Required: true, + }, + "apic_hosts": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "apic_refresh_ticker_adjust": { + Type: schema.TypeString, + Optional: true, + }, + "apic_refresh_time": { + Type: schema.TypeString, + Optional: true, + }, + "apic_subscription_delay": { + Type: schema.TypeString, + Optional: true, + }, + "apic_user_crt": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "apic_user_key": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "apic_user_name": { + Type: schema.TypeString, + Required: true, + }, + "capic": { + Type: schema.TypeString, + Optional: true, + }, + "controller_log_level": { + Type: schema.TypeString, + Optional: true, + }, + "disable_periodic_snat_global_info_sync": { + Type: schema.TypeString, + Optional: true, + }, + "disable_wait_for_network": { + Type: schema.TypeString, + Optional: true, + }, + "drop_log_enable": { + Type: schema.TypeString, + Optional: true, + }, + "duration_wait_for_network": { + Type: schema.TypeString, + Optional: true, + }, + "extern_dynamic": { + Type: schema.TypeString, + Required: true, + }, + "enable_endpoint_slice": { + Type: schema.TypeString, + Optional: true, + }, + "encap_type": { + Type: schema.TypeString, + Required: true, + }, + "ep_registry": { + Type: schema.TypeString, + Optional: true, + }, + "gbp_pod_subnet": { + Type: schema.TypeString, + Optional: true, + }, + "host_agent_log_level": { + Type: schema.TypeString, + Optional: true, + }, + "image_pull_policy": { + Type: schema.TypeString, + Optional: true, + }, + "image_pull_secret": { + Type: schema.TypeString, + Optional: true, + }, + "infra_vlan": { + Type: schema.TypeString, + Optional: true, + }, + "install_istio": { + Type: schema.TypeString, + Optional: true, + }, + "istio_profile": { + Type: schema.TypeString, + Optional: true, + }, + "kafka_brokers": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "kafka_client_crt": { + Type: schema.TypeString, + Optional: true, + }, + "kafka_client_key": { + Type: schema.TypeString, + Optional: true, + }, + "kube_api_vlan": { + Type: schema.TypeString, + Required: true, + }, + "l3out": { + Type: schema.TypeString, + Required: true, + }, + "l3out_external_networks": { + Type: schema.TypeList, + Required: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "max_nodes_svc_graph": { + Type: schema.TypeString, + Optional: true, + }, + "mcast_range_end": { + Type: schema.TypeString, + Required: true, + }, + "mcast_range_start": { + Type: schema.TypeString, + Required: true, + }, + "mtu_head_room": { + Type: schema.TypeString, + Optional: true, + }, + "multus_disable": { + Type: schema.TypeString, + Optional: true, + }, + "no_priority_class": { + Type: schema.TypeString, + Optional: true, + }, + "node_pod_if_enable": { + Type: schema.TypeString, + Optional: true, + }, + "node_subnet": { + Type: schema.TypeString, + Required: true, + }, + "ovs_memory_limit": { + Type: schema.TypeString, + Optional: true, + }, + "opflex_log_level": { + Type: schema.TypeString, + Optional: true, + }, + "opflex_client_ssl": { + Type: schema.TypeString, + Optional: true, + }, + "opflex_device_delete_timeout": { + Type: schema.TypeString, + Optional: true, + }, + "opflex_mode": { + Type: schema.TypeString, + Optional: true, + }, + "opflex_server_port": { + Type: schema.TypeString, + Optional: true, + }, + "overlay_vrf_name": { + Type: schema.TypeString, + Optional: true, + }, + "pbr_tracking_non_snat": { + Type: schema.TypeString, + Optional: true, + }, + "pod_subnet_chunk_size": { + Type: schema.TypeString, + Optional: true, + }, + "run_gbp_container": { + Type: schema.TypeString, + Optional: true, + }, + "run_opflex_server_container": { + Type: schema.TypeString, + Optional: true, + }, + "node_svc_subnet": { + Type: schema.TypeString, + Required: true, + }, + "service_monitor_interval": { + Type: schema.TypeString, + Optional: true, + }, + "service_vlan": { + Type: schema.TypeString, + Required: true, + }, + "snat_contract_scope": { + Type: schema.TypeString, + Optional: true, + }, + "snat_namespace": { + Type: schema.TypeString, + Optional: true, + }, + "snat_port_range_end": { + Type: schema.TypeString, + Optional: true, + }, + "snat_port_range_start": { + Type: schema.TypeString, + Optional: true, + }, + "snat_ports_per_node": { + Type: schema.TypeString, + Optional: true, + }, + "sriov_enable": { + Type: schema.TypeString, + Optional: true, + }, + "extern_static": { + Type: schema.TypeString, + Required: true, + }, + "subnet_domain_name": { + Type: schema.TypeString, + Optional: true, + }, + "system_id": { + Type: schema.TypeString, + Required: true, + }, + "tenant": { + Type: schema.TypeString, + Optional: true, + }, + "token": { + Type: schema.TypeString, + Required: true, + Sensitive: true, + }, + "use_aci_anywhere_crd": { + Type: schema.TypeString, + Optional: true, + }, + "use_aci_cni_priority_class": { + Type: schema.TypeString, + Optional: true, + }, + "use_cluster_role": { + Type: schema.TypeString, + Optional: true, + }, + "use_host_netns_volume": { + Type: schema.TypeString, + Optional: true, + }, + "use_opflex_server_volume": { + Type: schema.TypeString, + Optional: true, + }, + "use_privileged_container": { + Type: schema.TypeString, + Optional: true, + }, + "vrf_name": { + Type: schema.TypeString, + Required: true, + }, + "vrf_tenant": { + Type: schema.TypeString, + Required: true, + }, + "vmm_controller": { + Type: schema.TypeString, + Optional: true, + }, + "vmm_domain": { + Type: schema.TypeString, + Optional: true, + }, + } + return s +} + func clusterRKEConfigNetworkCalicoFields() map[string]*schema.Schema { s := map[string]*schema.Schema{ "cloud_provider": { @@ -71,6 +387,14 @@ func clusterRKEConfigNetworkWeaveFields() map[string]*schema.Schema { func clusterRKEConfigNetworkFields() map[string]*schema.Schema { s := map[string]*schema.Schema{ + "aci_network_provider": { + Type: schema.TypeList, + MaxItems: 1, + Optional: true, + Elem: &schema.Resource{ + Schema: clusterRKEConfigNetworkAciFields(), + }, + }, "calico_network_provider": { Type: schema.TypeList, MaxItems: 1, diff --git a/rancher2/structure_cluster_rke_config_network.go b/rancher2/structure_cluster_rke_config_network.go index eb55015e..f1ed871b 100644 --- a/rancher2/structure_cluster_rke_config_network.go +++ b/rancher2/structure_cluster_rke_config_network.go @@ -6,6 +6,238 @@ import ( // Flatteners +func flattenClusterRKEConfigNetworkAci(in *managementClient.AciNetworkProvider) ([]interface{}, error) { + obj := make(map[string]interface{}) + if in == nil { + return []interface{}{}, nil + } + + if len(in.AEP) > 0 { + obj["aep"] = in.AEP + } + if len(in.ApicHosts) > 0 { + obj["apic_hosts"] = toArrayInterface(in.ApicHosts) + } + if len(in.ApicRefreshTickerAdjust) > 0 { + obj["apic_refresh_ticker_adjust"] = in.ApicRefreshTickerAdjust + } + if len(in.ApicRefreshTime) > 0 { + obj["apic_refresh_time"] = in.ApicRefreshTime + } + if len(in.ApicSubscriptionDelay) > 0 { + obj["apic_subscription_delay"] = in.ApicSubscriptionDelay + } + if len(in.ApicUserCrt) > 0 { + obj["apic_user_crt"] = in.ApicUserCrt + } + if len(in.ApicUserKey) > 0 { + obj["apic_user_key"] = in.ApicUserKey + } + if len(in.ApicUserName) > 0 { + obj["apic_user_name"] = in.ApicUserName + } + if len(in.CApic) > 0 { + obj["capic"] = in.CApic + } + if len(in.ControllerLogLevel) > 0 { + obj["controller_log_level"] = in.ControllerLogLevel + } + if len(in.DisablePeriodicSnatGlobalInfoSync) > 0 { + obj["disable_periodic_snat_global_info_sync"] = in.DisablePeriodicSnatGlobalInfoSync + } + if len(in.DisableWaitForNetwork) > 0 { + obj["disable_wait_for_network"] = in.DisableWaitForNetwork + } + if len(in.DropLogEnable) > 0 { + obj["drop_log_enable"] = in.DropLogEnable + } + if len(in.DurationWaitForNetwork) > 0 { + obj["duration_wait_for_network"] = in.DurationWaitForNetwork + } + if len(in.DynamicExternalSubnet) > 0 { + obj["extern_dynamic"] = in.DynamicExternalSubnet + } + if len(in.EnableEndpointSlice) > 0 { + obj["enable_endpoint_slice"] = in.EnableEndpointSlice + } + if len(in.EncapType) > 0 { + obj["encap_type"] = in.EncapType + } + if len(in.EpRegistry) > 0 { + obj["ep_registry"] = in.EpRegistry + } + if len(in.GbpPodSubnet) > 0 { + obj["gbp_pod_subnet"] = in.GbpPodSubnet + } + if len(in.HostAgentLogLevel) > 0 { + obj["host_agent_log_level"] = in.HostAgentLogLevel + } + if len(in.ImagePullPolicy) > 0 { + obj["image_pull_policy"] = in.ImagePullPolicy + } + if len(in.ImagePullSecret) > 0 { + obj["image_pull_secret"] = in.ImagePullSecret + } + if len(in.InfraVlan) > 0 { + obj["infra_vlan"] = in.InfraVlan + } + if len(in.InstallIstio) > 0 { + obj["install_istio"] = in.InstallIstio + } + if len(in.IstioProfile) > 0 { + obj["istio_profile"] = in.IstioProfile + } + if len(in.KafkaBrokers) > 0 { + obj["kafka_brokers"] = toArrayInterface(in.KafkaBrokers) + } + if len(in.KafkaClientCrt) > 0 { + obj["kafka_client_crt"] = in.KafkaClientCrt + } + if len(in.KafkaClientKey) > 0 { + obj["kafka_client_key"] = in.KafkaClientKey + } + if len(in.KubeAPIVlan) > 0 { + obj["kube_api_vlan"] = in.KubeAPIVlan + } + if len(in.L3Out) > 0 { + obj["l3out"] = in.L3Out + } + if len(in.L3OutExternalNetworks) > 0 { + obj["l3out_external_networks"] = toArrayInterface(in.L3OutExternalNetworks) + } + if len(in.MaxNodesSvcGraph) > 0 { + obj["max_nodes_svc_graph"] = in.MaxNodesSvcGraph + } + if len(in.McastRangeEnd) > 0 { + obj["mcast_range_end"] = in.McastRangeEnd + } + if len(in.McastRangeStart) > 0 { + obj["mcast_range_start"] = in.McastRangeStart + } + if len(in.MTUHeadRoom) > 0 { + obj["mtu_head_room"] = in.MTUHeadRoom + } + if len(in.MultusDisable) > 0 { + obj["multus_disable"] = in.MultusDisable + } + if len(in.NoPriorityClass) > 0 { + obj["no_priority_class"] = in.NoPriorityClass + } + if len(in.NodePodIfEnable) > 0 { + obj["node_pod_if_enable"] = in.NodePodIfEnable + } + if len(in.NodeSubnet) > 0 { + obj["node_subnet"] = in.NodeSubnet + } + if len(in.OVSMemoryLimit) > 0 { + obj["ovs_memory_limit"] = in.OVSMemoryLimit + } + if len(in.OpflexAgentLogLevel) > 0 { + obj["opflex_log_level"] = in.OpflexAgentLogLevel + } + if len(in.OpflexClientSSL) > 0 { + obj["opflex_client_ssl"] = in.OpflexClientSSL + } + if len(in.OpflexDeviceDeleteTimeout) > 0 { + obj["opflex_device_delete_timeout"] = in.OpflexDeviceDeleteTimeout + } + if len(in.OpflexMode) > 0 { + obj["opflex_mode"] = in.OpflexMode + } + if len(in.OpflexServerPort) > 0 { + obj["opflex_server_port"] = in.OpflexServerPort + } + if len(in.OverlayVRFName) > 0 { + obj["overlay_vrf_name"] = in.OverlayVRFName + } + if len(in.PBRTrackingNonSnat) > 0 { + obj["pbr_tracking_non_snat"] = in.PBRTrackingNonSnat + } + if len(in.PodSubnetChunkSize) > 0 { + obj["pod_subnet_chunk_size"] = in.PodSubnetChunkSize + } + if len(in.RunGbpContainer) > 0 { + obj["run_gbp_container"] = in.RunGbpContainer + } + if len(in.RunOpflexServerContainer) > 0 { + obj["run_opflex_server_container"] = in.RunOpflexServerContainer + } + if len(in.ServiceGraphSubnet) > 0 { + obj["node_svc_subnet"] = in.ServiceGraphSubnet + } + if len(in.ServiceMonitorInterval) > 0 { + obj["service_monitor_interval"] = in.ServiceMonitorInterval + } + if len(in.ServiceVlan) > 0 { + obj["service_vlan"] = in.ServiceVlan + } + if len(in.SnatContractScope) > 0 { + obj["snat_contract_scope"] = in.SnatContractScope + } + if len(in.SnatNamespace) > 0 { + obj["snat_namespace"] = in.SnatNamespace + } + if len(in.SnatPortRangeEnd) > 0 { + obj["snat_port_range_end"] = in.SnatPortRangeEnd + } + if len(in.SnatPortRangeStart) > 0 { + obj["snat_port_range_start"] = in.SnatPortRangeStart + } + if len(in.SnatPortsPerNode) > 0 { + obj["snat_ports_per_node"] = in.SnatPortsPerNode + } + if len(in.SriovEnable) > 0 { + obj["sriov_enable"] = in.SriovEnable + } + if len(in.StaticExternalSubnet) > 0 { + obj["extern_static"] = in.StaticExternalSubnet + } + if len(in.SubnetDomainName) > 0 { + obj["subnet_domain_name"] = in.SubnetDomainName + } + if len(in.SystemIdentifier) > 0 { + obj["system_id"] = in.SystemIdentifier + } + if len(in.Tenant) > 0 { + obj["tenant"] = in.Tenant + } + if len(in.Token) > 0 { + obj["token"] = in.Token + } + if len(in.UseAciAnywhereCRD) > 0 { + obj["use_aci_anywhere_crd"] = in.UseAciAnywhereCRD + } + if len(in.UseAciCniPriorityClass) > 0 { + obj["use_aci_cni_priority_class"] = in.UseAciCniPriorityClass + } + if len(in.UseClusterRole) > 0 { + obj["use_cluster_role"] = in.UseClusterRole + } + if len(in.UseHostNetnsVolume) > 0 { + obj["use_host_netns_volume"] = in.UseHostNetnsVolume + } + if len(in.UseOpflexServerVolume) > 0 { + obj["use_opflex_server_volume"] = in.UseOpflexServerVolume + } + if len(in.UsePrivilegedContainer) > 0 { + obj["use_privileged_container"] = in.UsePrivilegedContainer + } + if len(in.VRFName) > 0 { + obj["vrf_name"] = in.VRFName + } + if len(in.VRFTenant) > 0 { + obj["vrf_tenant"] = in.VRFTenant + } + if len(in.VmmController) > 0 { + obj["vmm_controller"] = in.VmmController + } + if len(in.VmmDomain) > 0 { + obj["vmm_domain"] = in.VmmDomain + } + + return []interface{}{obj}, nil +} + func flattenClusterRKEConfigNetworkCalico(in *managementClient.CalicoNetworkProvider) ([]interface{}, error) { obj := make(map[string]interface{}) if in == nil { @@ -64,6 +296,14 @@ func flattenClusterRKEConfigNetwork(in *managementClient.NetworkConfig) ([]inter return []interface{}{}, nil } + if in.AciNetworkProvider != nil { + aciNetwork, err := flattenClusterRKEConfigNetworkAci(in.AciNetworkProvider) + if err != nil { + return []interface{}{obj}, err + } + obj["aci_network_provider"] = aciNetwork + } + if in.CalicoNetworkProvider != nil { calicoNetwork, err := flattenClusterRKEConfigNetworkCalico(in.CalicoNetworkProvider) if err != nil { @@ -117,6 +357,239 @@ func flattenClusterRKEConfigNetwork(in *managementClient.NetworkConfig) ([]inter // Expanders +func expandClusterRKEConfigNetworkAci(p []interface{}) (*managementClient.AciNetworkProvider, error) { + obj := &managementClient.AciNetworkProvider{} + if len(p) == 0 || p[0] == nil { + return obj, nil + } + in := p[0].(map[string]interface{}) + + if v, ok := in["aep"].(string); ok && len(v) > 0 { + obj.AEP = v + } + if v, ok := in["apic_hosts"].([]interface{}); ok && len(v) > 0 { + obj.ApicHosts = toArrayString(v) + } + if v, ok := in["apic_refresh_ticker_adjust"].(string); ok && len(v) > 0 { + obj.ApicRefreshTickerAdjust = v + } + if v, ok := in["apic_refresh_time"].(string); ok && len(v) > 0 { + obj.ApicRefreshTime = v + } + if v, ok := in["apic_subscription_delay"].(string); ok && len(v) > 0 { + obj.ApicSubscriptionDelay = v + } + if v, ok := in["apic_user_crt"].(string); ok && len(v) > 0 { + obj.ApicUserCrt = v + } + if v, ok := in["apic_user_key"].(string); ok && len(v) > 0 { + obj.ApicUserKey = v + } + if v, ok := in["apic_user_name"].(string); ok && len(v) > 0 { + obj.ApicUserName = v + } + if v, ok := in["capic"].(string); ok && len(v) > 0 { + obj.CApic = v + } + if v, ok := in["controller_log_level"].(string); ok && len(v) > 0 { + obj.ControllerLogLevel = v + } + if v, ok := in["disable_periodic_snat_global_info_sync"].(string); ok && len(v) > 0 { + obj.DisablePeriodicSnatGlobalInfoSync = v + } + if v, ok := in["disable_wait_for_network"].(string); ok && len(v) > 0 { + obj.DisableWaitForNetwork = v + } + if v, ok := in["drop_log_enable"].(string); ok && len(v) > 0 { + obj.DropLogEnable = v + } + if v, ok := in["duration_wait_for_network"].(string); ok && len(v) > 0 { + obj.DurationWaitForNetwork = v + } + if v, ok := in["extern_dynamic"].(string); ok && len(v) > 0 { + obj.DynamicExternalSubnet = v + } + if v, ok := in["enable_endpoint_slice"].(string); ok && len(v) > 0 { + obj.EnableEndpointSlice = v + } + if v, ok := in["encap_type"].(string); ok && len(v) > 0 { + obj.EncapType = v + } + if v, ok := in["ep_registry"].(string); ok && len(v) > 0 { + obj.EpRegistry = v + } + if v, ok := in["gbp_pod_subnet"].(string); ok && len(v) > 0 { + obj.GbpPodSubnet = v + } + if v, ok := in["host_agent_log_level"].(string); ok && len(v) > 0 { + obj.HostAgentLogLevel = v + } + if v, ok := in["image_pull_policy"].(string); ok && len(v) > 0 { + obj.ImagePullPolicy = v + } + if v, ok := in["image_pull_secret"].(string); ok && len(v) > 0 { + obj.ImagePullSecret = v + } + if v, ok := in["infra_vlan"].(string); ok && len(v) > 0 { + obj.InfraVlan = v + } + if v, ok := in["install_istio"].(string); ok && len(v) > 0 { + obj.InstallIstio = v + } + if v, ok := in["istio_profile"].(string); ok && len(v) > 0 { + obj.IstioProfile = v + } + if v, ok := in["kafka_brokers"].([]interface{}); ok && len(v) > 0 { + obj.KafkaBrokers = toArrayString(v) + } + if v, ok := in["kafka_client_crt"].(string); ok && len(v) > 0 { + obj.KafkaClientCrt = v + } + if v, ok := in["kafka_client_key"].(string); ok && len(v) > 0 { + obj.KafkaClientKey = v + } + if v, ok := in["kube_api_vlan"].(string); ok && len(v) > 0 { + obj.KubeAPIVlan = v + } + if v, ok := in["l3out"].(string); ok && len(v) > 0 { + obj.L3Out = v + } + if v, ok := in["l3out_external_networks"].([]interface{}); ok && len(v) > 0 { + obj.L3OutExternalNetworks = toArrayString(v) + } + if v, ok := in["max_nodes_svc_graph"].(string); ok && len(v) > 0 { + obj.MaxNodesSvcGraph = v + } + if v, ok := in["mcast_range_end"].(string); ok && len(v) > 0 { + obj.McastRangeEnd = v + } + if v, ok := in["mcast_range_start"].(string); ok && len(v) > 0 { + obj.McastRangeStart = v + } + if v, ok := in["mtu_head_room"].(string); ok && len(v) > 0 { + obj.MTUHeadRoom = v + } + if v, ok := in["multus_disable"].(string); ok && len(v) > 0 { + obj.MultusDisable = v + } + if v, ok := in["no_priority_class"].(string); ok && len(v) > 0 { + obj.NoPriorityClass = v + } + if v, ok := in["node_pod_if_enable"].(string); ok && len(v) > 0 { + obj.NodePodIfEnable = v + } + if v, ok := in["node_subnet"].(string); ok && len(v) > 0 { + obj.NodeSubnet = v + } + if v, ok := in["ovs_memory_limit"].(string); ok && len(v) > 0 { + obj.OVSMemoryLimit = v + } + if v, ok := in["opflex_log_level"].(string); ok && len(v) > 0 { + obj.OpflexAgentLogLevel = v + } + if v, ok := in["opflex_client_ssl"].(string); ok && len(v) > 0 { + obj.OpflexClientSSL = v + } + if v, ok := in["opflex_device_delete_timeout"].(string); ok && len(v) > 0 { + obj.OpflexDeviceDeleteTimeout = v + } + if v, ok := in["opflex_mode"].(string); ok && len(v) > 0 { + obj.OpflexMode = v + } + if v, ok := in["opflex_server_port"].(string); ok && len(v) > 0 { + obj.OpflexServerPort = v + } + if v, ok := in["overlay_vrf_name"].(string); ok && len(v) > 0 { + obj.OverlayVRFName = v + } + if v, ok := in["pbr_tracking_non_snat"].(string); ok && len(v) > 0 { + obj.PBRTrackingNonSnat = v + } + if v, ok := in["pod_subnet_chunk_size"].(string); ok && len(v) > 0 { + obj.PodSubnetChunkSize = v + } + if v, ok := in["run_gbp_container"].(string); ok && len(v) > 0 { + obj.RunGbpContainer = v + } + if v, ok := in["run_opflex_server_container"].(string); ok && len(v) > 0 { + obj.RunOpflexServerContainer = v + } + if v, ok := in["node_svc_subnet"].(string); ok && len(v) > 0 { + obj.ServiceGraphSubnet = v + } + if v, ok := in["service_monitor_interval"].(string); ok && len(v) > 0 { + obj.ServiceMonitorInterval = v + } + if v, ok := in["service_vlan"].(string); ok && len(v) > 0 { + obj.ServiceVlan = v + } + if v, ok := in["snat_contract_scope"].(string); ok && len(v) > 0 { + obj.SnatContractScope = v + } + if v, ok := in["snat_namespace"].(string); ok && len(v) > 0 { + obj.SnatNamespace = v + } + if v, ok := in["snat_port_range_end"].(string); ok && len(v) > 0 { + obj.SnatPortRangeEnd = v + } + if v, ok := in["snat_port_range_start"].(string); ok && len(v) > 0 { + obj.SnatPortRangeStart = v + } + if v, ok := in["snat_ports_per_node"].(string); ok && len(v) > 0 { + obj.SnatPortsPerNode = v + } + if v, ok := in["sriov_enable"].(string); ok && len(v) > 0 { + obj.SriovEnable = v + } + if v, ok := in["extern_static"].(string); ok && len(v) > 0 { + obj.StaticExternalSubnet = v + } + if v, ok := in["subnet_domain_name"].(string); ok && len(v) > 0 { + obj.SubnetDomainName = v + } + if v, ok := in["system_id"].(string); ok && len(v) > 0 { + obj.SystemIdentifier = v + } + if v, ok := in["tenant"].(string); ok && len(v) > 0 { + obj.Tenant = v + } + if v, ok := in["token"].(string); ok && len(v) > 0 { + obj.Token = v + } + if v, ok := in["use_aci_anywhere_crd"].(string); ok && len(v) > 0 { + obj.UseAciAnywhereCRD = v + } + if v, ok := in["use_aci_cni_priority_class"].(string); ok && len(v) > 0 { + obj.UseAciCniPriorityClass = v + } + if v, ok := in["use_cluster_role"].(string); ok && len(v) > 0 { + obj.UseClusterRole = v + } + if v, ok := in["use_host_netns_volume"].(string); ok && len(v) > 0 { + obj.UseHostNetnsVolume = v + } + if v, ok := in["use_opflex_server_volume"].(string); ok && len(v) > 0 { + obj.UseOpflexServerVolume = v + } + if v, ok := in["use_privileged_container"].(string); ok && len(v) > 0 { + obj.UsePrivilegedContainer = v + } + if v, ok := in["vrf_name"].(string); ok && len(v) > 0 { + obj.VRFName = v + } + if v, ok := in["vrf_tenant"].(string); ok && len(v) > 0 { + obj.VRFTenant = v + } + if v, ok := in["vmm_controller"].(string); ok && len(v) > 0 { + obj.VmmController = v + } + if v, ok := in["vmm_domain"].(string); ok && len(v) > 0 { + obj.VmmDomain = v + } + + return obj, nil +} + func expandClusterRKEConfigNetworkCalico(p []interface{}) (*managementClient.CalicoNetworkProvider, error) { obj := &managementClient.CalicoNetworkProvider{} if len(p) == 0 || p[0] == nil { @@ -181,6 +654,14 @@ func expandClusterRKEConfigNetwork(p []interface{}) (*managementClient.NetworkCo } in := p[0].(map[string]interface{}) + if v, ok := in["aci_network_provider"].([]interface{}); ok && len(v) > 0 { + aciNetwork, err := expandClusterRKEConfigNetworkAci(v) + if err != nil { + return obj, err + } + obj.AciNetworkProvider = aciNetwork + } + if v, ok := in["calico_network_provider"].([]interface{}); ok && len(v) > 0 { calicoNetwork, err := expandClusterRKEConfigNetworkCalico(v) if err != nil { diff --git a/rancher2/structure_cluster_rke_config_network_test.go b/rancher2/structure_cluster_rke_config_network_test.go index a73391b0..0b3d9fd0 100644 --- a/rancher2/structure_cluster_rke_config_network_test.go +++ b/rancher2/structure_cluster_rke_config_network_test.go @@ -10,6 +10,8 @@ import ( var ( testClusterRKEConfigNetworkTolerationsConf []managementClient.Toleration testClusterRKEConfigNetworkTolerationsInterface []interface{} + testClusterRKEConfigNetworkAciConf *managementClient.AciNetworkProvider + testClusterRKEConfigNetworkAciInterface []interface{} testClusterRKEConfigNetworkCalicoConf *managementClient.CalicoNetworkProvider testClusterRKEConfigNetworkCalicoInterface []interface{} testClusterRKEConfigNetworkCanalConf *managementClient.CanalNetworkProvider @@ -18,6 +20,8 @@ var ( testClusterRKEConfigNetworkFlannelInterface []interface{} testClusterRKEConfigNetworkWeaveConf *managementClient.WeaveNetworkProvider testClusterRKEConfigNetworkWeaveInterface []interface{} + testClusterRKEConfigNetworkConfAci *managementClient.NetworkConfig + testClusterRKEConfigNetworkInterfaceAci []interface{} testClusterRKEConfigNetworkConfCalico *managementClient.NetworkConfig testClusterRKEConfigNetworkInterfaceCalico []interface{} testClusterRKEConfigNetworkConfCanal *managementClient.NetworkConfig @@ -48,6 +52,160 @@ func init() { "seconds": 10, }, } + testClusterRKEConfigNetworkAciConf = &managementClient.AciNetworkProvider{ + AEP: "RANCHER", + ApicHosts: []string{"192.168.1.10", "192.168.1.11", "192.168.1.12"}, + ApicRefreshTickerAdjust: "150", + ApicRefreshTime: "1200", + ApicSubscriptionDelay: "100", + ApicUserCrt: "cert1", + ApicUserKey: "key1", + ApicUserName: "user1", + CApic: "capic", + ControllerLogLevel: "info", + DisablePeriodicSnatGlobalInfoSync: "false", + DisableWaitForNetwork: "false", + DropLogEnable: "false", + DurationWaitForNetwork: "300", + DynamicExternalSubnet: "172.10.2.1/24", + EnableEndpointSlice: "true", + EncapType: "vxlan", + EpRegistry: "registry", + GbpPodSubnet: "172.10.4.1/22", + HostAgentLogLevel: "info", + ImagePullPolicy: "always", + ImagePullSecret: "secret", + InfraVlan: "4093", + InstallIstio: "false", + IstioProfile: "default", + KafkaBrokers: []string{"10.0.0.10", "10.0.0.11", "10.0.0.12"}, + KafkaClientCrt: "cert2", + KafkaClientKey: "key2", + KubeAPIVlan: "4001", + L3Out: "l3out", + L3OutExternalNetworks: []string{"OUT", "LAN"}, + MaxNodesSvcGraph: "100", + McastRangeEnd: "225.20.255.255", + McastRangeStart: "225.20.1.1", + MTUHeadRoom: "100", + MultusDisable: "true", + NoPriorityClass: "false", + NodePodIfEnable: "true", + NodeSubnet: "172.10.0.1/24", + OVSMemoryLimit: "1Gi", + OpflexAgentLogLevel: "info", + OpflexClientSSL: "true", + OpflexDeviceDeleteTimeout: "600", + OpflexMode: "mode", + OpflexServerPort: "9000", + OverlayVRFName: "vrf1", + PBRTrackingNonSnat: "false", + PodSubnetChunkSize: "32", + RunGbpContainer: "false", + RunOpflexServerContainer: "false", + ServiceGraphSubnet: "172.10.3.1/24", + ServiceMonitorInterval: "5", + ServiceVlan: "4003", + SnatContractScope: "global", + SnatNamespace: "aci-containers-system", + SnatPortRangeEnd: "65000", + SnatPortRangeStart: "5000", + SnatPortsPerNode: "3000", + SriovEnable: "true", + StaticExternalSubnet: "172.10.1.1/24", + SubnetDomainName: "domain.tld", + SystemIdentifier: "id", + Tenant: "acitenant", + Token: "acitoken", + UseAciAnywhereCRD: "false", + UseAciCniPriorityClass: "true", + UseClusterRole: "true", + UseHostNetnsVolume: "false", + UseOpflexServerVolume: "false", + UsePrivilegedContainer: "false", + VRFName: "vrf", + VRFTenant: "vrf", + VmmController: "controller", + VmmDomain: "domain", + } + testClusterRKEConfigNetworkAciInterface = []interface{}{ + map[string]interface{}{ + "aep": "RANCHER", + "apic_hosts": []interface{}{"192.168.1.10", "192.168.1.11", "192.168.1.12"}, + "apic_refresh_ticker_adjust": "150", + "apic_refresh_time": "1200", + "apic_subscription_delay": "100", + "apic_user_crt": "cert1", + "apic_user_key": "key1", + "apic_user_name": "user1", + "capic": "capic", + "controller_log_level": "info", + "disable_periodic_snat_global_info_sync": "false", + "disable_wait_for_network": "false", + "drop_log_enable": "false", + "duration_wait_for_network": "300", + "extern_dynamic": "172.10.2.1/24", + "enable_endpoint_slice": "true", + "encap_type": "vxlan", + "ep_registry": "registry", + "gbp_pod_subnet": "172.10.4.1/22", + "host_agent_log_level": "info", + "image_pull_policy": "always", + "image_pull_secret": "secret", + "infra_vlan": "4093", + "install_istio": "false", + "istio_profile": "default", + "kafka_brokers": []interface{}{"10.0.0.10", "10.0.0.11", "10.0.0.12"}, + "kafka_client_crt": "cert2", + "kafka_client_key": "key2", + "kube_api_vlan": "4001", + "l3out": "l3out", + "l3out_external_networks": []interface{}{"OUT", "LAN"}, + "max_nodes_svc_graph": "100", + "mcast_range_end": "225.20.255.255", + "mcast_range_start": "225.20.1.1", + "mtu_head_room": "100", + "multus_disable": "true", + "no_priority_class": "false", + "node_pod_if_enable": "true", + "node_subnet": "172.10.0.1/24", + "ovs_memory_limit": "1Gi", + "opflex_log_level": "info", + "opflex_client_ssl": "true", + "opflex_device_delete_timeout": "600", + "opflex_mode": "mode", + "opflex_server_port": "9000", + "overlay_vrf_name": "vrf1", + "pbr_tracking_non_snat": "false", + "pod_subnet_chunk_size": "32", + "run_gbp_container": "false", + "run_opflex_server_container": "false", + "node_svc_subnet": "172.10.3.1/24", + "service_monitor_interval": "5", + "service_vlan": "4003", + "snat_contract_scope": "global", + "snat_namespace": "aci-containers-system", + "snat_port_range_end": "65000", + "snat_port_range_start": "5000", + "snat_ports_per_node": "3000", + "sriov_enable": "true", + "extern_static": "172.10.1.1/24", + "subnet_domain_name": "domain.tld", + "system_id": "id", + "tenant": "acitenant", + "token": "acitoken", + "use_aci_anywhere_crd": "false", + "use_aci_cni_priority_class": "true", + "use_cluster_role": "true", + "use_host_netns_volume": "false", + "use_opflex_server_volume": "false", + "use_privileged_container": "false", + "vrf_name": "vrf", + "vrf_tenant": "vrf", + "vmm_controller": "controller", + "vmm_domain": "domain", + }, + } testClusterRKEConfigNetworkCalicoConf = &managementClient.CalicoNetworkProvider{ CloudProvider: "aws", } @@ -80,6 +238,28 @@ func init() { "password": "password", }, } + testClusterRKEConfigNetworkConfAci = &managementClient.NetworkConfig{ + AciNetworkProvider: testClusterRKEConfigNetworkAciConf, + MTU: 1500, + Options: map[string]string{ + "option1": "value1", + "option2": "value2", + }, + Plugin: networkPluginAciName, + Tolerations: testClusterRKEConfigNetworkTolerationsConf, + } + testClusterRKEConfigNetworkInterfaceAci = []interface{}{ + map[string]interface{}{ + "aci_network_provider": testClusterRKEConfigNetworkAciInterface, + "mtu": 1500, + "options": map[string]interface{}{ + "option1": "value1", + "option2": "value2", + }, + "plugin": networkPluginAciName, + "tolerations": testClusterRKEConfigNetworkTolerationsInterface, + }, + } testClusterRKEConfigNetworkConfCalico = &managementClient.NetworkConfig{ CalicoNetworkProvider: testClusterRKEConfigNetworkCalicoConf, MTU: 1500, @@ -170,6 +350,30 @@ func init() { } } +func TestFlattenClusterRKEConfigNetworkAci(t *testing.T) { + + cases := []struct { + Input *managementClient.AciNetworkProvider + ExpectedOutput []interface{} + }{ + { + testClusterRKEConfigNetworkAciConf, + testClusterRKEConfigNetworkAciInterface, + }, + } + + for _, tc := range cases { + output, err := flattenClusterRKEConfigNetworkAci(tc.Input) + if err != nil { + t.Fatalf("[ERROR] on flattener: %#v", err) + } + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from flattener.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +} + func TestFlattenClusterRKEConfigNetworkCalico(t *testing.T) { cases := []struct { @@ -272,6 +476,10 @@ func TestFlattenClusterRKEConfigNetwork(t *testing.T) { Input *managementClient.NetworkConfig ExpectedOutput []interface{} }{ + { + testClusterRKEConfigNetworkConfAci, + testClusterRKEConfigNetworkInterfaceAci, + }, { testClusterRKEConfigNetworkConfCalico, testClusterRKEConfigNetworkInterfaceCalico, @@ -302,6 +510,30 @@ func TestFlattenClusterRKEConfigNetwork(t *testing.T) { } } +func TestExpandClusterRKEConfigNetworkAci(t *testing.T) { + + cases := []struct { + Input []interface{} + ExpectedOutput *managementClient.AciNetworkProvider + }{ + { + testClusterRKEConfigNetworkAciInterface, + testClusterRKEConfigNetworkAciConf, + }, + } + + for _, tc := range cases { + output, err := expandClusterRKEConfigNetworkAci(tc.Input) + if err != nil { + t.Fatalf("[ERROR] on expander: %#v", err) + } + if !reflect.DeepEqual(output, tc.ExpectedOutput) { + t.Fatalf("Unexpected output from expander.\nExpected: %#v\nGiven: %#v", + tc.ExpectedOutput, output) + } + } +} + func TestExpandClusterRKEConfigNetworkCalico(t *testing.T) { cases := []struct { @@ -404,6 +636,10 @@ func TestExpandClusterRKEConfigNetwork(t *testing.T) { Input []interface{} ExpectedOutput *managementClient.NetworkConfig }{ + { + testClusterRKEConfigNetworkInterfaceAci, + testClusterRKEConfigNetworkConfAci, + }, { testClusterRKEConfigNetworkInterfaceCalico, testClusterRKEConfigNetworkConfCalico,