Add heat templates for HCO

Added base heat template to deploy VMs for
HCO with MKE4

Related-PROD: KUBV-57
Change-Id: I4f5246d06a265971544f776362db6f0cac058f90
diff --git a/hco/env/ctrl1-wrkr3.yaml b/hco/env/ctrl1-wrkr3.yaml
new file mode 100644
index 0000000..b11a8cc
--- /dev/null
+++ b/hco/env/ctrl1-wrkr3.yaml
@@ -0,0 +1,9 @@
+resource_registry:
+  "VMInstances": ../fragments/VMInstance.yaml
+
+parameters:
+  controllers_size: 1
+  workers_size: 3
+  image: jammy-server-cloudimg-amd64-20240417
+  public_net_id: c3799996-dc8e-4477-a309-09ea6dd71946
+  cluster_public_key: ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCp0evjOaK8c8SKYK4r2+0BN7g+8YSvQ2n8nFgOURCyvkJqOHi1qPGZmuN0CclYVdVuZiXbWw3VxRbSW3EH736VzgY1U0JmoTiSamzLHaWsXvEIW8VCi7boli539QJP0ikJiBaNAgZILyCrVPN+A6mfqtacs1KXdZ0zlMq1BPtFciR1JTCRcVs5vP2Wwz5QtY2jMIh3aiwkePjMTQPcfmh1TkOlxYu5IbQyZ3G1ahA0mNKI9a0dtF282av/F6pwB/N1R1nEZ/9VtcN2I1mf1NW/tTHEEcTzXYo1R/8K9vlqAN8QvvGLZtZduGviNVNoNWvoxaXxDt8CPv2B2NCdQFZp
diff --git a/hco/fragments/VMInstance.yaml b/hco/fragments/VMInstance.yaml
new file mode 100644
index 0000000..b4115f3
--- /dev/null
+++ b/hco/fragments/VMInstance.yaml
@@ -0,0 +1,58 @@
+heat_template_version: queens
+
+parameters:
+
+  node_type:
+    type: string
+  k8s_network:
+    type: string
+  k8s_subnet_id:
+    type: string
+  public_net_id:
+    type: string
+  data_network:
+    type: string
+  availability_zone:
+    type: string
+    default: nova
+  image:
+    type: string
+    description: Name of image to use for servers
+  flavor:
+    type: string
+    description: Flavor to use for servers
+  key_name:
+    type: string
+    description: Name of keypair to assign to servers
+
+resources:
+
+  k8s_network_port:
+    type: OS::Neutron::Port
+    properties:
+      network: { get_param: k8s_network }
+      port_security_enabled: false
+      fixed_ips:
+        - subnet: { get_param: k8s_subnet_id }
+
+  floating_ip_k8s_net:
+    type: OS::Neutron::FloatingIP
+    properties:
+      floating_network_id: { get_param: public_net_id }
+      port_id: { get_resource: k8s_network_port }
+
+  vm_server:
+    type: OS::Nova::Server
+    properties:
+      availability_zone: { get_param: availability_zone }
+      image: { get_param: image }
+      flavor: { get_param: flavor }
+      key_name: { get_param: key_name }
+      networks:
+        - port: { get_resource: k8s_network_port }
+        - network: { get_param : data_network }
+
+outputs:
+  server_public_ip:
+    description: Floating IP address of server in public network
+    value: { get_attr: [ floating_ip_k8s_net, floating_ip_address ] }
diff --git a/hco/top.yaml b/hco/top.yaml
new file mode 100644
index 0000000..6998956
--- /dev/null
+++ b/hco/top.yaml
@@ -0,0 +1,135 @@
+heat_template_version: queens
+
+parameters:
+  controllers_size:
+    type: number
+    description: Number of masters instances to deploy
+    default: 1
+  workers_size:
+    type: number
+    description: Number of workers to deploy
+    default: 3
+  image:
+    type: string
+    description: Name of image to use for servers
+  availability_zone:
+    type: string
+    default: "nova"
+  masters_flavor:
+    type: string
+    default: 'system.compact.openstack.control'
+  workers_flavor:
+    type: string
+    default: 'system.compact.openstack.control'
+  cluster_public_key:
+    type: string
+  public_net_id:
+    type: string
+    default: ''
+    description: >
+      UUID of public network
+  k8s_network_cidr:
+    type: string
+    description: The CIDR of k8s network
+    default: '10.10.0.0/24'
+  data_network_cidr:
+    type: string
+    description: The CIDR of k8s network
+    default: '10.11.0.0/24'
+  dns_nameservers:
+    type: json
+    default: []
+
+resources:
+
+  keypair_name:
+    type: OS::Heat::RandomString
+    properties:
+      character_classes: [{"class": "hexdigits", "min": 1}]
+      length: 128
+      salt: constant
+  key_pair:
+    type: OS::Nova::KeyPair
+    properties:
+      name: { get_attr: [keypair_name, value] }
+      public_key: { get_param: cluster_public_key }
+      save_private_key: false
+
+  k8s_network:
+    type: OS::Neutron::Net
+  k8s_subnet:
+    type: OS::Neutron::Subnet
+    properties:
+      network: { get_resource: k8s_network }
+      enable_dhcp: false
+      cidr: { get_param: k8s_network_cidr }
+      dns_nameservers: { get_param: dns_nameservers }
+  router:
+    type: OS::Neutron::Router
+    properties:
+      external_gateway_info:
+        network: { get_param: public_net_id }
+  public_router_iface:
+    type: OS::Neutron::RouterInterface
+    properties:
+      router: { get_resource: router }
+      subnet: { get_resource: k8s_subnet }
+
+  data_network:
+    type: OS::Neutron::Net
+  data_subnet:
+    type: OS::Neutron::Subnet
+    properties:
+      network: { get_resource: data_network }
+      enable_dhcp: false
+      cidr: { get_param: data_network_cidr }
+
+  masters:
+    type: OS::Heat::ResourceGroup
+    depends_on:
+      - k8s_network
+      - data_network
+      - public_router_iface
+    properties:
+      count: { get_param: controllers_size }
+      resource_def:
+        type: VMInstances
+        properties:
+          node_type: "controller"
+          k8s_network: { get_resource: k8s_network }
+          k8s_subnet_id: { get_resource: k8s_subnet }
+          public_net_id: { get_param: public_net_id }
+          data_network: { get_resource: data_network }
+          availability_zone: { get_param: availability_zone }
+          image: { get_param: image }
+          flavor: { get_param: masters_flavor }
+          key_name: { get_attr: [keypair_name, value] }
+
+  workers:
+    type: OS::Heat::ResourceGroup
+    depends_on:
+      - k8s_network
+      - data_network
+      - public_router_iface
+    properties:
+      count: { get_param: workers_size }
+      resource_def:
+        type: VMInstances
+        properties:
+          node_type: "worker"
+          k8s_network: { get_resource: k8s_network }
+          k8s_subnet_id: { get_resource: k8s_subnet }
+          public_net_id: { get_param: public_net_id }
+          data_network: { get_resource: data_network }
+          availability_zone: { get_param: availability_zone }
+          image: { get_param: image }
+          flavor: { get_param: workers_flavor }
+          key_name: { get_attr: [keypair_name, value] }
+
+outputs:
+  masters_ips:
+    description: Public IP addresses of the deployed masters instances
+    value: { get_attr: [masters, server_public_ip] }
+  workers_ips:
+    description: Public IP addresses of the deployed worker instances
+    value: { get_attr: [workers, server_public_ip] }