<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Pkamath3</id>
	<title>Expertiza_Wiki - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.expertiza.ncsu.edu/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Pkamath3"/>
	<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=Special:Contributions/Pkamath3"/>
	<updated>2026-06-13T20:27:24Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=150256</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=150256"/>
		<updated>2023-04-28T20:41:56Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Tasks Implemented in Project 3 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented in Project 3==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ActionArguments was changed as well.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Design Plan for Final Project==&lt;br /&gt;
&lt;br /&gt;
We plan to implement the factory design pattern to further refine and DRY out our code. Our plan is to implement a DatabaseActionArgumentFactory Interface which will introduce a factory design pattern and this will handle the creation of the different types of database action arguments based on the database type.&lt;br /&gt;
&lt;br /&gt;
To achieve this, the DatabaseActionArgumentFactory which has a single method which will create the action arguments. This method will take in a string representing the database type and return action arguments based on the database type passed in as string.&lt;br /&gt;
&lt;br /&gt;
The implementation of this interface will be done by creating different factory structs for each database type, which will implement the method of the interface. These factory structures will be used to create the specific database action argument for each database type.&lt;br /&gt;
&lt;br /&gt;
By using this approach, the code will be more modular and easier to maintain in the future as new database types can be added by simply adding a new factory struct and implementing the CreateActionArguments method for that type. Additionally, the use of an interface will allow for easier testing and mocking of the database action argument creation logic.&lt;br /&gt;
&lt;br /&gt;
Class diagram:&lt;br /&gt;
[[File:design_plan.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Testing Plan for Final Project==&lt;br /&gt;
To test the implementation of the DatabaseActionArgumentFactory, we will be writing unit tests that verify that the factory is correctly creating the appropriate action arguments for each database type.&lt;br /&gt;
&lt;br /&gt;
The steps we will be following for implementation are as follows:&lt;br /&gt;
&lt;br /&gt;
#Create test cases for each of the supported database types (MySQL, Postgres, MongoDB, etc.)&lt;br /&gt;
#For each test case, create a mock of the database instance with the appropriate type.&lt;br /&gt;
#Call the createActionArguments method on the DatabaseActionArgumentFactory with the mock database instance as input.&lt;br /&gt;
#Verify that the output is a list of the correct action arguments for the corresponding database type.&lt;br /&gt;
#Repeat the above steps for all the supported database types.&lt;br /&gt;
&lt;br /&gt;
By following these steps, we will be making sure that the DatabaseActionArgumentFactory is correct and that it is creating the correct action arguments for each supported database type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additionally, we will also be able to test that the program is able to handle unsupported database types by passing in an unsupported database type and verifying that the output is nil or an empty list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The system will then be tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is similar to what we had done previously to provision a database using the steps given below:&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
A successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Checked the test drive for status of provisioning.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pull/75&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=150255</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=150255"/>
		<updated>2023-04-28T20:40:54Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Design Plan for Final Project */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented in Project 3==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Design Plan for Final Project==&lt;br /&gt;
&lt;br /&gt;
We plan to implement the factory design pattern to further refine and DRY out our code. Our plan is to implement a DatabaseActionArgumentFactory Interface which will introduce a factory design pattern and this will handle the creation of the different types of database action arguments based on the database type.&lt;br /&gt;
&lt;br /&gt;
To achieve this, the DatabaseActionArgumentFactory which has a single method which will create the action arguments. This method will take in a string representing the database type and return action arguments based on the database type passed in as string.&lt;br /&gt;
&lt;br /&gt;
The implementation of this interface will be done by creating different factory structs for each database type, which will implement the method of the interface. These factory structures will be used to create the specific database action argument for each database type.&lt;br /&gt;
&lt;br /&gt;
By using this approach, the code will be more modular and easier to maintain in the future as new database types can be added by simply adding a new factory struct and implementing the CreateActionArguments method for that type. Additionally, the use of an interface will allow for easier testing and mocking of the database action argument creation logic.&lt;br /&gt;
&lt;br /&gt;
Class diagram:&lt;br /&gt;
[[File:design_plan.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Testing Plan for Final Project==&lt;br /&gt;
To test the implementation of the DatabaseActionArgumentFactory, we will be writing unit tests that verify that the factory is correctly creating the appropriate action arguments for each database type.&lt;br /&gt;
&lt;br /&gt;
The steps we will be following for implementation are as follows:&lt;br /&gt;
&lt;br /&gt;
#Create test cases for each of the supported database types (MySQL, Postgres, MongoDB, etc.)&lt;br /&gt;
#For each test case, create a mock of the database instance with the appropriate type.&lt;br /&gt;
#Call the createActionArguments method on the DatabaseActionArgumentFactory with the mock database instance as input.&lt;br /&gt;
#Verify that the output is a list of the correct action arguments for the corresponding database type.&lt;br /&gt;
#Repeat the above steps for all the supported database types.&lt;br /&gt;
&lt;br /&gt;
By following these steps, we will be making sure that the DatabaseActionArgumentFactory is correct and that it is creating the correct action arguments for each supported database type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additionally, we will also be able to test that the program is able to handle unsupported database types by passing in an unsupported database type and verifying that the output is nil or an empty list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The system will then be tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is similar to what we had done previously to provision a database using the steps given below:&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
A successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Checked the test drive for status of provisioning.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pull/75&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=150254</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=150254"/>
		<updated>2023-04-28T20:40:34Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Testing Plan for Final Project */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented in Project 3==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Design Plan for Final Project==&lt;br /&gt;
&lt;br /&gt;
We plan to implement the factory design pattern to further refine and DRY out our code. Our plan is to implement a DatabaseActionArgumentFactory Interface which will introduce a factory design pattern and this will handle the creation of the different types of database action arguments based on the database type.&lt;br /&gt;
&lt;br /&gt;
To achieve this, the DatabaseActionArgumentFactory which has a single method which will create the action arguments. This method will take in a string representing the database type and return action arguments based on the database type passed in as string.&lt;br /&gt;
&lt;br /&gt;
The implementation of this interface will be done by creating different factory structs for each database type, which will implement the method of the interface. These factory structures will be used to create the specific database action argument for each database type.&lt;br /&gt;
&lt;br /&gt;
By using this approach, the code will be more modular and easier to maintain in the future as new database types can be added by simply adding a new factory struct and implementing the CreateActionArguments method for that type. Additionally, the use of an interface will allow for easier testing and mocking of the database action argument creation logic.&lt;br /&gt;
&lt;br /&gt;
[[File:design_plan.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Testing Plan for Final Project==&lt;br /&gt;
To test the implementation of the DatabaseActionArgumentFactory, we will be writing unit tests that verify that the factory is correctly creating the appropriate action arguments for each database type.&lt;br /&gt;
&lt;br /&gt;
The steps we will be following for implementation are as follows:&lt;br /&gt;
&lt;br /&gt;
#Create test cases for each of the supported database types (MySQL, Postgres, MongoDB, etc.)&lt;br /&gt;
#For each test case, create a mock of the database instance with the appropriate type.&lt;br /&gt;
#Call the createActionArguments method on the DatabaseActionArgumentFactory with the mock database instance as input.&lt;br /&gt;
#Verify that the output is a list of the correct action arguments for the corresponding database type.&lt;br /&gt;
#Repeat the above steps for all the supported database types.&lt;br /&gt;
&lt;br /&gt;
By following these steps, we will be making sure that the DatabaseActionArgumentFactory is correct and that it is creating the correct action arguments for each supported database type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additionally, we will also be able to test that the program is able to handle unsupported database types by passing in an unsupported database type and verifying that the output is nil or an empty list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The system will then be tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is similar to what we had done previously to provision a database using the steps given below:&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
A successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Checked the test drive for status of provisioning.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pull/75&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149287</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149287"/>
		<updated>2023-04-08T03:01:01Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Github */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented in Project 3==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Design Plan for Final Project==&lt;br /&gt;
&lt;br /&gt;
We plan to implement the factory design pattern to further refine and DRY out our code. Our plan is to implement a DatabaseActionArgumentFactory Interface which will introduce a factory design pattern and this will handle the creation of the different types of database action arguments based on the database type.&lt;br /&gt;
&lt;br /&gt;
To achieve this, the DatabaseActionArgumentFactory which has a single method which will create the action arguments. This method will take in a string representing the database type and return action arguments based on the database type passed in as string.&lt;br /&gt;
&lt;br /&gt;
The implementation of this interface will be done by creating different factory structs for each database type, which will implement the method of the interface. These factory structures will be used to create the specific database action argument for each database type.&lt;br /&gt;
&lt;br /&gt;
By using this approach, the code will be more modular and easier to maintain in the future as new database types can be added by simply adding a new factory struct and implementing the CreateActionArguments method for that type. Additionally, the use of an interface will allow for easier testing and mocking of the database action argument creation logic.&lt;br /&gt;
&lt;br /&gt;
[[File:design_plan.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Testing Plan for Final Project==&lt;br /&gt;
To test the implementation of the DatabaseActionArgumentFactory, we will be writing unit tests that verify that the factory is correctly creating the appropriate action arguments for each database type.&lt;br /&gt;
&lt;br /&gt;
The steps we will be following for implementation are as follows:&lt;br /&gt;
&lt;br /&gt;
#Create test cases for each of the supported database types (MySQL, Postgres, MongoDB, etc.)&lt;br /&gt;
#For each test case, create a mock of the database instance with the appropriate type.&lt;br /&gt;
#Call the createActionArguments method on the DatabaseActionArgumentFactory with the mock database instance as input.&lt;br /&gt;
#Verify that the output is a list of the correct action arguments for the corresponding database type.&lt;br /&gt;
#Repeat the above steps for all the supported database types.&lt;br /&gt;
&lt;br /&gt;
By following these steps, we will be making sure that the DatabaseActionArgumentFactory is correct and that it is creating the correct action arguments for each supported database type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additionally, we will also be able to test that the program is able to handle unsupported database types by passing in an unsupported database type and verifying that the output is nil or an empty list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The system will then be tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is similar to what we had done previously to provision a database using the steps given below:&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pull/75&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149285</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149285"/>
		<updated>2023-04-08T03:00:55Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Github */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented in Project 3==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Design Plan for Final Project==&lt;br /&gt;
&lt;br /&gt;
We plan to implement the factory design pattern to further refine and DRY out our code. Our plan is to implement a DatabaseActionArgumentFactory Interface which will introduce a factory design pattern and this will handle the creation of the different types of database action arguments based on the database type.&lt;br /&gt;
&lt;br /&gt;
To achieve this, the DatabaseActionArgumentFactory which has a single method which will create the action arguments. This method will take in a string representing the database type and return action arguments based on the database type passed in as string.&lt;br /&gt;
&lt;br /&gt;
The implementation of this interface will be done by creating different factory structs for each database type, which will implement the method of the interface. These factory structures will be used to create the specific database action argument for each database type.&lt;br /&gt;
&lt;br /&gt;
By using this approach, the code will be more modular and easier to maintain in the future as new database types can be added by simply adding a new factory struct and implementing the CreateActionArguments method for that type. Additionally, the use of an interface will allow for easier testing and mocking of the database action argument creation logic.&lt;br /&gt;
&lt;br /&gt;
[[File:design_plan.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Testing Plan for Final Project==&lt;br /&gt;
To test the implementation of the DatabaseActionArgumentFactory, we will be writing unit tests that verify that the factory is correctly creating the appropriate action arguments for each database type.&lt;br /&gt;
&lt;br /&gt;
The steps we will be following for implementation are as follows:&lt;br /&gt;
&lt;br /&gt;
#Create test cases for each of the supported database types (MySQL, Postgres, MongoDB, etc.)&lt;br /&gt;
#For each test case, create a mock of the database instance with the appropriate type.&lt;br /&gt;
#Call the createActionArguments method on the DatabaseActionArgumentFactory with the mock database instance as input.&lt;br /&gt;
#Verify that the output is a list of the correct action arguments for the corresponding database type.&lt;br /&gt;
#Repeat the above steps for all the supported database types.&lt;br /&gt;
&lt;br /&gt;
By following these steps, we will be making sure that the DatabaseActionArgumentFactory is correct and that it is creating the correct action arguments for each supported database type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additionally, we will also be able to test that the program is able to handle unsupported database types by passing in an unsupported database type and verifying that the output is nil or an empty list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The system will then be tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is similar to what we had done previously to provision a database using the steps given below:&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pull/75&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149283</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149283"/>
		<updated>2023-04-08T02:58:39Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented in Project 3==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Design Plan for Final Project==&lt;br /&gt;
&lt;br /&gt;
We plan to implement the factory design pattern to further refine and DRY out our code. Our plan is to implement a DatabaseActionArgumentFactory Interface which will introduce a factory design pattern and this will handle the creation of the different types of database action arguments based on the database type.&lt;br /&gt;
&lt;br /&gt;
To achieve this, the DatabaseActionArgumentFactory which has a single method which will create the action arguments. This method will take in a string representing the database type and return action arguments based on the database type passed in as string.&lt;br /&gt;
&lt;br /&gt;
The implementation of this interface will be done by creating different factory structs for each database type, which will implement the method of the interface. These factory structures will be used to create the specific database action argument for each database type.&lt;br /&gt;
&lt;br /&gt;
By using this approach, the code will be more modular and easier to maintain in the future as new database types can be added by simply adding a new factory struct and implementing the CreateActionArguments method for that type. Additionally, the use of an interface will allow for easier testing and mocking of the database action argument creation logic.&lt;br /&gt;
&lt;br /&gt;
[[File:design_plan.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Testing Plan for Final Project==&lt;br /&gt;
To test the implementation of the DatabaseActionArgumentFactory, we will be writing unit tests that verify that the factory is correctly creating the appropriate action arguments for each database type.&lt;br /&gt;
&lt;br /&gt;
The steps we will be following for implementation are as follows:&lt;br /&gt;
&lt;br /&gt;
#Create test cases for each of the supported database types (MySQL, Postgres, MongoDB, etc.)&lt;br /&gt;
#For each test case, create a mock of the database instance with the appropriate type.&lt;br /&gt;
#Call the createActionArguments method on the DatabaseActionArgumentFactory with the mock database instance as input.&lt;br /&gt;
#Verify that the output is a list of the correct action arguments for the corresponding database type.&lt;br /&gt;
#Repeat the above steps for all the supported database types.&lt;br /&gt;
&lt;br /&gt;
By following these steps, we will be making sure that the DatabaseActionArgumentFactory is correct and that it is creating the correct action arguments for each supported database type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additionally, we will also be able to test that the program is able to handle unsupported database types by passing in an unsupported database type and verifying that the output is nil or an empty list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The system will then be tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is similar to what we had done previously to provision a database using the steps given below:&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149282</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149282"/>
		<updated>2023-04-08T02:58:19Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Tasks Implemented */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented in Project 3==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Design Plan for Final Project==&lt;br /&gt;
&lt;br /&gt;
We plan to implement the factory design pattern to further refine and DRY out our code. Our plan is to implement a DatabaseActionArgumentFactory Interface which will introduce a factory design pattern and this will handle the creation of the different types of database action arguments based on the database type.&lt;br /&gt;
&lt;br /&gt;
To achieve this, the DatabaseActionArgumentFactory which has a single method which will create the action arguments. This method will take in a string representing the database type and return action arguments based on the database type passed in as string.&lt;br /&gt;
&lt;br /&gt;
The implementation of this interface will be done by creating different factory structs for each database type, which will implement the method of the interface. These factory structures will be used to create the specific database action argument for each database type.&lt;br /&gt;
&lt;br /&gt;
By using this approach, the code will be more modular and easier to maintain in the future as new database types can be added by simply adding a new factory struct and implementing the CreateActionArguments method for that type. Additionally, the use of an interface will allow for easier testing and mocking of the database action argument creation logic.&lt;br /&gt;
&lt;br /&gt;
[[File:design_plan.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
To test the implementation of the DatabaseActionArgumentFactory, we will be writing unit tests that verify that the factory is correctly creating the appropriate action arguments for each database type.&lt;br /&gt;
&lt;br /&gt;
The steps we will be following for implementation are as follows:&lt;br /&gt;
&lt;br /&gt;
#Create test cases for each of the supported database types (MySQL, Postgres, MongoDB, etc.)&lt;br /&gt;
#For each test case, create a mock of the database instance with the appropriate type.&lt;br /&gt;
#Call the createActionArguments method on the DatabaseActionArgumentFactory with the mock database instance as input.&lt;br /&gt;
#Verify that the output is a list of the correct action arguments for the corresponding database type.&lt;br /&gt;
#Repeat the above steps for all the supported database types.&lt;br /&gt;
&lt;br /&gt;
By following these steps, we will be making sure that the DatabaseActionArgumentFactory is correct and that it is creating the correct action arguments for each supported database type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additionally, we will also be able to test that the program is able to handle unsupported database types by passing in an unsupported database type and verifying that the output is nil or an empty list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The system will then be tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is similar to what we had done previously to provision a database using the steps given below:&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149280</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149280"/>
		<updated>2023-04-08T02:51:23Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Future Work */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Design Plan for Final Project==&lt;br /&gt;
&lt;br /&gt;
We plan to implement the factory design pattern to further refine and DRY out our code. Our plan is to implement a DatabaseActionArgumentFactory Interface which will introduce a factory design pattern and this will handle the creation of the different types of database action arguments based on the database type.&lt;br /&gt;
&lt;br /&gt;
To achieve this, the DatabaseActionArgumentFactory which has a single method which will create the action arguments. This method will take in a string representing the database type and return action arguments based on the database type passed in as string.&lt;br /&gt;
&lt;br /&gt;
The implementation of this interface will be done by creating different factory structs for each database type, which will implement the method of the interface. These factory structures will be used to create the specific database action argument for each database type.&lt;br /&gt;
&lt;br /&gt;
By using this approach, the code will be more modular and easier to maintain in the future as new database types can be added by simply adding a new factory struct and implementing the CreateActionArguments method for that type. Additionally, the use of an interface will allow for easier testing and mocking of the database action argument creation logic.&lt;br /&gt;
&lt;br /&gt;
[[File:design_plan.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
To test the implementation of the DatabaseActionArgumentFactory, we will be writing unit tests that verify that the factory is correctly creating the appropriate action arguments for each database type.&lt;br /&gt;
&lt;br /&gt;
The steps we will be following for implementation are as follows:&lt;br /&gt;
&lt;br /&gt;
#Create test cases for each of the supported database types (MySQL, Postgres, MongoDB, etc.)&lt;br /&gt;
#For each test case, create a mock of the database instance with the appropriate type.&lt;br /&gt;
#Call the createActionArguments method on the DatabaseActionArgumentFactory with the mock database instance as input.&lt;br /&gt;
#Verify that the output is a list of the correct action arguments for the corresponding database type.&lt;br /&gt;
#Repeat the above steps for all the supported database types.&lt;br /&gt;
&lt;br /&gt;
By following these steps, we will be making sure that the DatabaseActionArgumentFactory is correct and that it is creating the correct action arguments for each supported database type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additionally, we will also be able to test that the program is able to handle unsupported database types by passing in an unsupported database type and verifying that the output is nil or an empty list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The system will then be tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is similar to what we had done previously to provision a database using the steps given below:&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149279</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149279"/>
		<updated>2023-04-08T02:50:48Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Design Plan for Final Project==&lt;br /&gt;
&lt;br /&gt;
We plan to implement the factory design pattern to further refine and DRY out our code. Our plan is to implement a DatabaseActionArgumentFactory Interface which will introduce a factory design pattern and this will handle the creation of the different types of database action arguments based on the database type.&lt;br /&gt;
&lt;br /&gt;
To achieve this, the DatabaseActionArgumentFactory which has a single method which will create the action arguments. This method will take in a string representing the database type and return action arguments based on the database type passed in as string.&lt;br /&gt;
&lt;br /&gt;
The implementation of this interface will be done by creating different factory structs for each database type, which will implement the method of the interface. These factory structures will be used to create the specific database action argument for each database type.&lt;br /&gt;
&lt;br /&gt;
By using this approach, the code will be more modular and easier to maintain in the future as new database types can be added by simply adding a new factory struct and implementing the CreateActionArguments method for that type. Additionally, the use of an interface will allow for easier testing and mocking of the database action argument creation logic.&lt;br /&gt;
&lt;br /&gt;
[[File:design_plan.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
To test the implementation of the DatabaseActionArgumentFactory, we will be writing unit tests that verify that the factory is correctly creating the appropriate action arguments for each database type.&lt;br /&gt;
&lt;br /&gt;
The steps we will be following for implementation are as follows:&lt;br /&gt;
&lt;br /&gt;
#Create test cases for each of the supported database types (MySQL, Postgres, MongoDB, etc.)&lt;br /&gt;
#For each test case, create a mock of the database instance with the appropriate type.&lt;br /&gt;
#Call the createActionArguments method on the DatabaseActionArgumentFactory with the mock database instance as input.&lt;br /&gt;
#Verify that the output is a list of the correct action arguments for the corresponding database type.&lt;br /&gt;
#Repeat the above steps for all the supported database types.&lt;br /&gt;
&lt;br /&gt;
By following these steps, we will be making sure that the DatabaseActionArgumentFactory is correct and that it is creating the correct action arguments for each supported database type.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Additionally, we will also be able to test that the program is able to handle unsupported database types by passing in an unsupported database type and verifying that the output is nil or an empty list.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The system will then be tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This is similar to what we had done previously to provision a database using the steps given below:&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Future Work==&lt;br /&gt;
We can currently use the NDB Kubernetes Operator to provision mySQL databases. Deprovisioning the provisioned database would be the most important task for future work. This is essential for freeing up resources and lowering costs. Second, refactoring the code is required to retain the codebase's clean, maintainable, and scalable nature. Finally, it is critical to collaborate and integrate the work of each team to ensure that the project is aligned with the overall company goals and objectives.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149278</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149278"/>
		<updated>2023-04-08T02:50:28Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Design Plan for Final Project==&lt;br /&gt;
&lt;br /&gt;
We plan to implement the factory design pattern to further refine and DRY out our code. Our plan is to implement a DatabaseActionArgumentFactory Interface which will introduce a factory design pattern and this will handle the creation of the different types of database action arguments based on the database type.&lt;br /&gt;
&lt;br /&gt;
To achieve this, the DatabaseActionArgumentFactory which has a single method which will create the action arguments. This method will take in a string representing the database type and return action arguments based on the database type passed in as string.&lt;br /&gt;
&lt;br /&gt;
The implementation of this interface will be done by creating different factory structs for each database type, which will implement the method of the interface. These factory structures will be used to create the specific database action argument for each database type.&lt;br /&gt;
&lt;br /&gt;
By using this approach, the code will be more modular and easier to maintain in the future as new database types can be added by simply adding a new factory struct and implementing the CreateActionArguments method for that type. Additionally, the use of an interface will allow for easier testing and mocking of the database action argument creation logic.&lt;br /&gt;
&lt;br /&gt;
[[File:design_plan.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
To test the implementation of the DatabaseActionArgumentFactory, we will be writing unit tests that verify that the factory is correctly creating the appropriate action arguments for each database type.&lt;br /&gt;
&lt;br /&gt;
The steps we will be following for implementation are as follows:&lt;br /&gt;
&lt;br /&gt;
#Create test cases for each of the supported database types (MySQL, Postgres, MongoDB, etc.)&lt;br /&gt;
#For each test case, create a mock of the database instance with the appropriate type.&lt;br /&gt;
#Call the createActionArguments method on the DatabaseActionArgumentFactory with the mock database instance as input.&lt;br /&gt;
#Verify that the output is a list of the correct action arguments for the corresponding database type.&lt;br /&gt;
#Repeat the above steps for all the supported database types.&lt;br /&gt;
&lt;br /&gt;
By following these steps, we will be making sure that the DatabaseActionArgumentFactory is correct and that it is creating the correct action arguments for each supported database type.&lt;br /&gt;
&lt;br /&gt;
Additionally, we will also be able to test that the program is able to handle unsupported database types by passing in an unsupported database type and verifying that the output is nil or an empty list.&lt;br /&gt;
&lt;br /&gt;
The system will then be tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned. &lt;br /&gt;
&lt;br /&gt;
This is similar to what we had done previously to provision a database using the steps given below:&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Future Work==&lt;br /&gt;
We can currently use the NDB Kubernetes Operator to provision mySQL databases. Deprovisioning the provisioned database would be the most important task for future work. This is essential for freeing up resources and lowering costs. Second, refactoring the code is required to retain the codebase's clean, maintainable, and scalable nature. Finally, it is critical to collaborate and integrate the work of each team to ensure that the project is aligned with the overall company goals and objectives.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149276</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149276"/>
		<updated>2023-04-08T02:48:57Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Design Plan for Final Project */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Design Plan for Final Project==&lt;br /&gt;
&lt;br /&gt;
We plan to implement the factory design pattern to further refine and DRY out our code. Our plan is to implement a DatabaseActionArgumentFactory Interface which will introduce a factory design pattern and this will handle the creation of the different types of database action arguments based on the database type.&lt;br /&gt;
&lt;br /&gt;
To achieve this, the DatabaseActionArgumentFactory which has a single method which will create the action arguments. This method will take in a string representing the database type and return action arguments based on the database type passed in as string.&lt;br /&gt;
&lt;br /&gt;
The implementation of this interface will be done by creating different factory structs for each database type, which will implement the method of the interface. These factory structures will be used to create the specific database action argument for each database type.&lt;br /&gt;
&lt;br /&gt;
By using this approach, the code will be more modular and easier to maintain in the future as new database types can be added by simply adding a new factory struct and implementing the CreateActionArguments method for that type. Additionally, the use of an interface will allow for easier testing and mocking of the database action argument creation logic.&lt;br /&gt;
&lt;br /&gt;
[[File:design_plan.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Future Work==&lt;br /&gt;
We can currently use the NDB Kubernetes Operator to provision mySQL databases. Deprovisioning the provisioned database would be the most important task for future work. This is essential for freeing up resources and lowering costs. Second, refactoring the code is required to retain the codebase's clean, maintainable, and scalable nature. Finally, it is critical to collaborate and integrate the work of each team to ensure that the project is aligned with the overall company goals and objectives.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Design_plan.png&amp;diff=149275</id>
		<title>File:Design plan.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Design_plan.png&amp;diff=149275"/>
		<updated>2023-04-08T02:47:46Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149273</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149273"/>
		<updated>2023-04-08T02:44:03Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* D */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Design Plan for Final Project==&lt;br /&gt;
&lt;br /&gt;
We plan to implement the factory design pattern to further refine and DRY out our code. Our plan is to implement a DatabaseActionArgumentFactory Interface which will introduce a factory design pattern and this will handle the creation of the different types of database action arguments based on the database type.&lt;br /&gt;
&lt;br /&gt;
To achieve this, the DatabaseActionArgumentFactory which has a single method which will create the action arguments. This method will take in a string representing the database type and return action arguments based on the database type passed in as string.&lt;br /&gt;
&lt;br /&gt;
The implementation of this interface will be done by creating different factory structs for each database type, which will implement the method of the interface. These factory structures will be used to create the specific database action argument for each database type.&lt;br /&gt;
&lt;br /&gt;
By using this approach, the code will be more modular and easier to maintain in the future as new database types can be added by simply adding a new factory struct and implementing the CreateActionArguments method for that type. Additionally, the use of an interface will allow for easier testing and mocking of the database action argument creation logic.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Future Work==&lt;br /&gt;
We can currently use the NDB Kubernetes Operator to provision mySQL databases. Deprovisioning the provisioned database would be the most important task for future work. This is essential for freeing up resources and lowering costs. Second, refactoring the code is required to retain the codebase's clean, maintainable, and scalable nature. Finally, it is critical to collaborate and integrate the work of each team to ensure that the project is aligned with the overall company goals and objectives.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149272</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149272"/>
		<updated>2023-04-08T02:43:21Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==D==&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Future Work==&lt;br /&gt;
We can currently use the NDB Kubernetes Operator to provision mySQL databases. Deprovisioning the provisioned database would be the most important task for future work. This is essential for freeing up resources and lowering costs. Second, refactoring the code is required to retain the codebase's clean, maintainable, and scalable nature. Finally, it is critical to collaborate and integrate the work of each team to ensure that the project is aligned with the overall company goals and objectives.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149271</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=149271"/>
		<updated>2023-04-08T02:41:53Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Design Patterns */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We set up our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get databases by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Future Work==&lt;br /&gt;
We can currently use the NDB Kubernetes Operator to provision mySQL databases. Deprovisioning the provisioned database would be the most important task for future work. This is essential for freeing up resources and lowering costs. Second, refactoring the code is required to retain the codebase's clean, maintainable, and scalable nature. Finally, it is critical to collaborate and integrate the work of each team to ensure that the project is aligned with the overall company goals and objectives.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023&amp;diff=148098</id>
		<title>CSC/ECE 517 Spring 2023</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023&amp;diff=148098"/>
		<updated>2023-03-23T01:14:45Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== OSS Projects ==&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 -E2306. Refactor user_controller.rb, user.rb and its child classes]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - E2320. Reimplement the Question hierarchy]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - E2312 + E2313. Reimplement response.rb and responses_controller.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - NTNX-1. Support provisioning MongoDb via NDB Kubernetes Operator]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - E2316. Reimplement sign_up_sheet_controller.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - E2315. Reimplement signed_up_team.rb, sign_up_topic.rb, sign_up_sheet.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring_2023 - E2323. Refactor DueDate functionality from assignment.rb]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - E2314. Reimplement the response map hierarchy]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023- NTNX-4. Extend NDB operator provision postregresql aws]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - E2321. Reimplement QuestionnairesController and QuestionsController]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - E2305. Grading audit trail]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - E2309. Refactor Node model and its subclasses]]&lt;br /&gt;
&lt;br /&gt;
[[CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator]]&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148077</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148077"/>
		<updated>2023-03-23T00:44:09Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Future Work */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We setup our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get database by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Future Work==&lt;br /&gt;
We can currently use the NDB Kubernetes Operator to provision mySQL databases. Deprovisioning the provisioned database would be the most important task for future work. This is essential for freeing up resources and lowering costs. Second, refactoring the code is required to retain the codebase's clean, maintainable, and scalable nature. Finally, it is critical to collaborate and integrate the work of each team to ensure that the project is aligned with the overall company goals and objectives.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148076</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148076"/>
		<updated>2023-03-23T00:43:37Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We setup our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get database by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==Future Work==&lt;br /&gt;
We can currently use the NDB Kubernetes Operator to provision mySQL databases. Deprovisioning the provisioned database would be the most important task for future work. This is essential for freeing up resources and lowering costs. Second, refactoring the remaining code is required to retain the codebase's clean, maintainable, and scalable nature. Finally, it is critical to collaborate and integrate the work of each team to ensure that the project is aligned with the overall company goals and objectives.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148074</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148074"/>
		<updated>2023-03-23T00:30:03Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We setup our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get database by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_6.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148073</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148073"/>
		<updated>2023-03-23T00:27:34Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We setup our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get database by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:Testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Testing_plan_3.png&amp;diff=148072</id>
		<title>File:Testing plan 3.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Testing_plan_3.png&amp;diff=148072"/>
		<updated>2023-03-23T00:27:09Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: Pkamath3 uploaded a new version of File:Testing plan 3.png&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Testing_plan_3.png&amp;diff=148071</id>
		<title>File:Testing plan 3.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Testing_plan_3.png&amp;diff=148071"/>
		<updated>2023-03-23T00:25:55Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148070</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148070"/>
		<updated>2023-03-23T00:25:08Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We setup our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get database by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148069</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148069"/>
		<updated>2023-03-23T00:24:55Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We setup our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get database by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:P9_8.png&amp;diff=148068</id>
		<title>File:P9 8.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:P9_8.png&amp;diff=148068"/>
		<updated>2023-03-23T00:24:15Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148066</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148066"/>
		<updated>2023-03-23T00:14:41Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We setup our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get database by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_1.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_3.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148065</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148065"/>
		<updated>2023-03-23T00:12:51Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Testing Plan */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We setup our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get database by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:testing_plan_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Testing_plan_6.png&amp;diff=148064</id>
		<title>File:Testing plan 6.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Testing_plan_6.png&amp;diff=148064"/>
		<updated>2023-03-23T00:11:34Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Testing_plan_5.png&amp;diff=148063</id>
		<title>File:Testing plan 5.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Testing_plan_5.png&amp;diff=148063"/>
		<updated>2023-03-23T00:11:24Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Testing_plan_4.png&amp;diff=148062</id>
		<title>File:Testing plan 4.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Testing_plan_4.png&amp;diff=148062"/>
		<updated>2023-03-23T00:11:14Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:P10_3.png&amp;diff=148061</id>
		<title>File:P10 3.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:P10_3.png&amp;diff=148061"/>
		<updated>2023-03-23T00:10:09Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Testing_plan_2.png&amp;diff=148060</id>
		<title>File:Testing plan 2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Testing_plan_2.png&amp;diff=148060"/>
		<updated>2023-03-23T00:09:57Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148055</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148055"/>
		<updated>2023-03-22T23:55:43Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Tasks Implemented */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We setup our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. &lt;br /&gt;
&lt;br /&gt;
Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_2.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_3.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_4.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_5.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_6.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_7.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get database by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_7.png&amp;diff=148050</id>
		<title>File:Tasks implemented 7.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_7.png&amp;diff=148050"/>
		<updated>2023-03-22T23:46:47Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_6.png&amp;diff=148049</id>
		<title>File:Tasks implemented 6.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_6.png&amp;diff=148049"/>
		<updated>2023-03-22T23:46:33Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_5.png&amp;diff=148048</id>
		<title>File:Tasks implemented 5.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_5.png&amp;diff=148048"/>
		<updated>2023-03-22T23:46:20Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_4.png&amp;diff=148047</id>
		<title>File:Tasks implemented 4.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_4.png&amp;diff=148047"/>
		<updated>2023-03-22T23:46:07Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_3.png&amp;diff=148046</id>
		<title>File:Tasks implemented 3.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_3.png&amp;diff=148046"/>
		<updated>2023-03-22T23:45:52Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_2.png&amp;diff=148045</id>
		<title>File:Tasks implemented 2.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_2.png&amp;diff=148045"/>
		<updated>2023-03-22T23:45:25Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148044</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148044"/>
		<updated>2023-03-22T23:45:00Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: /* Tasks Implemented */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We setup our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
[[File:tasks_implemented_1.png|center|border|1000px]]&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get database by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_1.png&amp;diff=148035</id>
		<title>File:Tasks implemented 1.png</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=File:Tasks_implemented_1.png&amp;diff=148035"/>
		<updated>2023-03-22T23:37:20Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148027</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148027"/>
		<updated>2023-03-22T23:24:25Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Tasks Implemented==&lt;br /&gt;
We setup our own Kubernetes cluster using Docker Desktop and cloned the ndb-operator repository to make changes to the code.&lt;br /&gt;
&lt;br /&gt;
The manifest file used to generate the provisioning request was set up: This includes the Nutanix Database Service server that is being used as well as parameters such as database instance name, database names, credential secret (which is applied using a different manifest file), size, timezone and type of database that needs to be provisioned.&lt;br /&gt;
&lt;br /&gt;
The GenerateProvisioningRequest takes the following arguments: a context, an instance of a struct called NDBClient, an instance of a struct called DatabaseSpec, and a map containing strings as keys and interface{} types as values. The function returns a pointer to an instance of a struct called DatabaseProvisionRequest and an error. Within the function, a Time Machine Service Level Agreement (SLA) is fetched and as well as OOB profiles from the remote database client. If the function fails to do either of these things, it logs the error and returns.&lt;br /&gt;
&lt;br /&gt;
The function then joins the database instance names together into a single string, and performs type assertions on the password and SSH public key contained within the map argument. If either of these assertions fail (i.e not of type string or empty) errors are thrown.&lt;br /&gt;
&lt;br /&gt;
The GetOOBProfiles takes three parameters as input: ctx, ndbclient and dbType and returns a map of profiles and an error. Inside the function, the map of profiles is initialized and GetAllProfiles function is called.&lt;br /&gt;
&lt;br /&gt;
The function then filters out the generic and specific database engine type profiles using the &amp;quot;util.Filter&amp;quot; function. It then again filters these profiles based on the profile type such as COMPUTE, STORAGE, SOFTWARE, NETWORK, and DATABASE_PARAMETER using the same &amp;quot;util.Filter&amp;quot; function. &lt;br /&gt;
&lt;br /&gt;
The function checks if all the required profiles are present or not, and if any of the required profiles is not present, it returns an error. If all the profiles are present, it stores them in the map and returns the map of profiles.&lt;br /&gt;
&lt;br /&gt;
So, basically, this function gets OOB profiles based on the input database engine type and populates a map of profiles.&lt;br /&gt;
&lt;br /&gt;
The GetDabaseEngineName and the GetDatabasePortByType functions also returns the database type depending on the definition in the manifest file.&lt;br /&gt;
&lt;br /&gt;
The ProvisionDatabase function sends a POST request to the &amp;quot;databases/provision&amp;quot; endpoint of the Network Database service using the ndbClient's Post method. It checks and logs any errors during the POST request. If the POST request is successful and returns a status code of 200 (http.StatusOK), the HTTP response body is read and unmarshaled into the task object.&lt;br /&gt;
&lt;br /&gt;
To provision the MySQL database the ActionArguments as well as the port had to be changed.&lt;br /&gt;
&lt;br /&gt;
==Design Patterns==&lt;br /&gt;
One design pattern that can be used to improve this code is the Factory design pattern. The Factory design pattern is used to define an interface for creating an object, but let sub classes decide which class to instantiate. Based on the instance type, the database provision request can be generated and a factory interface can be defined for this. Apart from this the DRY principle has also been followed by making use of profile maps and functions to get database by name in order to have a single method to provision databases and not have different control statements to generate provisioning requests for different database instance types.&lt;br /&gt;
&lt;br /&gt;
==Testing Plan==&lt;br /&gt;
The system was tested by running the operator on a local Kubernetes cluster and then making provisioning requests to the Nutanix Database Service test drive cluster that was assigned.&lt;br /&gt;
&lt;br /&gt;
Step 1: First, the manifest for provisioning a mysql database was configured.&lt;br /&gt;
&lt;br /&gt;
Step 2: The NDB operator was then run on a local cluster to make sure that the provisioning request was being completed.&lt;br /&gt;
&lt;br /&gt;
Step 3 : The secrets were configured&lt;br /&gt;
&lt;br /&gt;
Step 4: The configuration for the database was applied and a successful response is received by the operator.&lt;br /&gt;
&lt;br /&gt;
==References==&lt;br /&gt;
# NDB Operator Document - https://docs.google.com/document/d/1-VykKyIeky3n4JciIIrNgirk-Cn4pDT1behc9Yl8Nxk/&lt;br /&gt;
# NDB Operator Github Repository - https://github.com/nutanix-cloud-native/ndboperator&lt;br /&gt;
# Go Documentation - https://go.dev/doc/&lt;br /&gt;
# Go Operator SDK Document - https://sdk.operatorframework.io/docs/buildingoperators/golang/tutorial/&lt;br /&gt;
# Overview of Kubernetes - https://kubernetes.io/docs/concepts/overview/&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148022</id>
		<title>CSC/ECE 517 Spring 2023 - NTNX-2. Support provisioning mySQL databases via NDB Kubernetes Operator</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023_-_NTNX-2._Support_provisioning_mySQL_databases_via_NDB_Kubernetes_Operator&amp;diff=148022"/>
		<updated>2023-03-22T23:06:20Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: Created page with &amp;quot;==Introduction== ===Nutanix Database Service=== Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database mana...&amp;quot;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
===Nutanix Database Service===&lt;br /&gt;
Nutanix Database Service is a unique hybrid cloud-based database solution that offers support for several popular database management systems including Microsoft SQL Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. With Nutanix Database Service, you can manage hundreds to thousands of databases with ease. It simplifies tasks like provisioning new databases, automating routine administrative tasks such as backups and patches, and selecting the right operating systems, database versions, and extensions to meet your specific application and compliance requirements. &lt;br /&gt;
&lt;br /&gt;
===Nutanix Database Service Operator===&lt;br /&gt;
The Nutanix Database Service (NDB) Operator is an innovative tool that automates and simplifies database administration, provisioning, and life-cycle management on Kubernetes. By utilizing the NDB Operator, developers can directly provision popular database management systems like PostgreSQL, MySQL, and MongoDB from their K8s cluster with ease. This results in significant time savings that could take days to weeks of effort if done manually. The NDB Operator is an open-source tool that can be accessed from your preferred Kubernetes platform, and also allows you to benefit from the full database life-cycle management that NDB provides.&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Our team's first task was to get familiar with the operator's codebase which was written in GoLang. We also had to understand basic cluster administration using Kubernetes and make ourselves familiar with the Go Operator SDK which is what is used to develop custom Kubernetes Operators. Our goal was to enhance the functionality of the Nutanix Database Service (NDB) Operator, which at the time could only support the provisioning of PostgreSQL databases. We had to extend the capabilities of the operator to include the provisioning and de-provisioning of MySQL databases. This required modifications to the existing operator to enable the provisioning of MySQL databases, as well as refactoring of the operator's code-base to support this added feature. We also had to make sure that the Operator's code was tested and that the provisioning and de-provisioning steps were tested&lt;br /&gt;
end-to-end.&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/qureshi-ali/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pulls&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Muhammad Ali Qureshi(mquresh)&lt;br /&gt;
* Prasad Vithal Kamath (pkamath3)&lt;br /&gt;
* Boscosylvester John Chittilapilly (bchitti)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023-_NTNX-4._Extend_NDB_operator_provision_postregresql_aws&amp;diff=148021</id>
		<title>CSC/ECE 517 Spring 2023- NTNX-4. Extend NDB operator provision postregresql aws</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023-_NTNX-4._Extend_NDB_operator_provision_postregresql_aws&amp;diff=148021"/>
		<updated>2023-03-22T23:05:59Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==NTNX-4. Extend Nutanix Database Service Kubernetes operator to provision Postgres Single Instance databases on AWS EC2==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Note to the reviewer==&lt;br /&gt;
A major part of the logic can only be written after we get access to the keys of an EC2 instance that we can connect to the Nutanix Database Service. This differs from other NTNX teams since we need to provision the database on AWS. Hence, we cannot use the Test Nutanix endpoint to create clusterID or Secret's name. We have added a '''Note''' section in the Implementation section to inform the parts which fall under this category. We have also added this information collectively under the '''Future Implementation''' section.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Nutanix Database Service is the only hybrid cloud database-as-a-service for Microsoft SQL&lt;br /&gt;
Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. Currently, using the NDB operator, you can only provision a database on the Nutanix Cloud Infrastructure(on-prem).This project aims to extend the Nutanix Database Service Kubernetes operator to provision Postgres Single Instance databases on cloud - specifically on AWS EC2. We aim to do this in a scalable way so that changing the cloud provider to say Azure or GCP would require changes only to the configuration file(CRD Manifest).&lt;br /&gt;
&lt;br /&gt;
==Architecture==&lt;br /&gt;
The important components here are:&lt;br /&gt;
# '''Kubernetes Cluster'''&lt;br /&gt;
# '''Kubernetes Service''' that almost acts like a gateway to the provisioned database - The application pods that want to communicate with the database do so through the K8 service and endpoint that is created as part of the last step of provisioning. The workflow is explained in detail in the next section.&lt;br /&gt;
# '''Nutanix Database Service''' - The operator pod running in the K8 cluster communicates with this service to provision, de-provision, obtain status of the database etc.&lt;br /&gt;
# '''Cloud platform''' (AWS in our case)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
[[File:Ntnx4arch.png|1000px|]]&lt;br /&gt;
&lt;br /&gt;
==Workflow==&lt;br /&gt;
* Apply the instance CRD manifest file to create an instance of NDB resource in the K8 cluster&lt;br /&gt;
&lt;br /&gt;
* The operator controller runs its logic to build a provisioning request and sends it to the Nutanix Database Service endpoint pertaining to provision in cloud(AWS in our case)&lt;br /&gt;
&lt;br /&gt;
* The reconcile function loops to take actions depending on the status of provisioning - Empty, Provisioning and Ready&lt;br /&gt;
&lt;br /&gt;
* Once the database is provisioned in AWS and the status is in Ready, we set up a Kubernetes networking service and an endpoint with the same name in the cluster. Any application pod in this cluster will communicate with this endpoint rather than communicating directly with the database. &lt;br /&gt;
&lt;br /&gt;
[[File:Workflowntnx4.png|1000px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Design==&lt;br /&gt;
===Single Responsibility Principle(SRP)===&lt;br /&gt;
SRP is adopted here to separate the business logic of the operator from the reconciliation loop.&lt;br /&gt;
&lt;br /&gt;
* The logic to handle '''remoteType''' : cloud is handled separately from the client (ndbClient) through helper methods - This ensures that the client is responsible for only making get/post requests to the specified endpoint without worrying about whether it is for on-prem or cloud. &lt;br /&gt;
&lt;br /&gt;
* The reconciliation loop is responsible for ensuring that the state of the system matches the desired state declared by the operator. It listens to events from the Kubernetes API server and performs the necessary actions to reconcile the system to the desired state. The business logic of the operator, on the other hand, is responsible for implementing the higher-level functionality of the operator, such as managing the deployment of a complex application or managing a database cluster.&lt;br /&gt;
&lt;br /&gt;
* Even within the reconciliation logic, there are clear indications of following SRP. We have a separate file utils/secret.go to implement GetDataFromSecret and GetAllDataFromSecret - logic to get data from the resource denoted by the name/namespace combination.&lt;br /&gt;
&lt;br /&gt;
===Operator Pattern===&lt;br /&gt;
The operator pattern is based on the idea of declarative configuration management. Rather than writing imperative code to perform a series of steps to reach a desired state, an operator declares the desired state of the system and uses the Kubernetes API to perform the necessary actions to reconcile the system to that desired state.&lt;br /&gt;
&lt;br /&gt;
We continue to follow this pattern for our implementation. We have a manifest file for a NDB custom resource responsible for provisioning and managing PostgreSQL in AWS and the logic for it is handled in the controller code (controllers/database_controllers.go)&lt;br /&gt;
&lt;br /&gt;
  EXAMPLE MANIFEST FILE&lt;br /&gt;
   ...&lt;br /&gt;
   &lt;br /&gt;
   apiVersion: ndb.nutanix.com/v1alpha1&lt;br /&gt;
   kind: Database&lt;br /&gt;
   metadata:&lt;br /&gt;
     name: db&lt;br /&gt;
   spec:&lt;br /&gt;
     ndb:&lt;br /&gt;
       remoteType: &amp;quot;cloud&amp;quot;&lt;br /&gt;
       clusterId: &amp;quot;Nutanix Cluster Id&amp;quot;&lt;br /&gt;
       credentialSecret : ndb-secret-name&lt;br /&gt;
       server: https://[NDB IP]:8443/era/v1.0&lt;br /&gt;
       skipCertificateVerification: true&lt;br /&gt;
     databaseInstance:&lt;br /&gt;
       databaseInstanceName: &amp;quot;Database Instance Name&amp;quot;&lt;br /&gt;
       databaseNames:&lt;br /&gt;
         - database_one&lt;br /&gt;
         - database_two&lt;br /&gt;
         - database_three&lt;br /&gt;
       credentialSecret: db-instance-secret-name&lt;br /&gt;
       size: 10&lt;br /&gt;
       timezone: &amp;quot;UTC&amp;quot;&lt;br /&gt;
       type: postgres&lt;br /&gt;
   ...&lt;br /&gt;
&lt;br /&gt;
The controller logic and related helper code will use the newly created ''''remoteType'''' field to select the NDS endpoint and construct provisionRequest appropriately. We have distinguished the configuration(Manifest file) and the logic(controller code) this way.&lt;br /&gt;
&lt;br /&gt;
==Implementation related to this project==&lt;br /&gt;
&lt;br /&gt;
This section will explain the changes that are made/to-be-made as part of this project.&lt;br /&gt;
&lt;br /&gt;
'''NOTE: MOST OF THESE CHANGES HAVE NOT BEEN MADE NOW SINCE OUR TEAM HAS NOT OBTAINED ACCESS TO CONNECT THE SERVICE WITH EC2 INSTANCE FROM THE NUTANIX TEAM'''&lt;br /&gt;
'''We will tell the changes that have not been made and they will be made in the future'''&lt;br /&gt;
&lt;br /&gt;
===Generate Secrets manifest and set name field + credentials in it===&lt;br /&gt;
This secrets.yaml manifest file is to create a Secret resource instance that is will have the data regarding the NDB instance name and database credentials.&lt;br /&gt;
&lt;br /&gt;
'''Note: We have created this file, but currently have template values. After getting access, we will fill them accordingly'''&lt;br /&gt;
&lt;br /&gt;
===Modify database_types.go to have allow remote types===&lt;br /&gt;
We have added a '''remoteType''' field to the NDB struct along with validation markers&lt;br /&gt;
...&lt;br /&gt;
   // +kubebuilder:validation:Required;Enum=cloud;on-prem&lt;br /&gt;
   RemoteType string `json:&amp;quot;remoteType&amp;quot;`&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Add helper method to figure out endpoint depending on remote type===&lt;br /&gt;
We currently have this logic as part of the ndbClient and should be moved to a separate helper method. The purpose of this function is to determine if the provisioning is for on-prem or cloud.&lt;br /&gt;
   ...&lt;br /&gt;
   type NDBClient struct {&lt;br /&gt;
	   username   string&lt;br /&gt;
	   password   string&lt;br /&gt;
	   url        string&lt;br /&gt;
	   remoteType string&lt;br /&gt;
	   client     *http.Client&lt;br /&gt;
   }&lt;br /&gt;
   ...&lt;br /&gt;
===Modify helper methods to generate request, provision database and setup connectivity===&lt;br /&gt;
Below are the functions that are core to the provisioning logic. They are written for provisioning a database in Nutanix cloud infrastructure(on-prem). These functions constitute the primary part of the provisioning workflow.&lt;br /&gt;
&lt;br /&gt;
====GenerateProvisioningRequest(database_reconciler_helpers.go)====&lt;br /&gt;
This data structure should be modified/extended to include fields that are required to be part of the JSON request for the NDS endpoint that pertains to provisioning on cloud. Adding fields with appropriate data type is required here to serialize and deserialize requests properly.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
====ProvisionDatabase(database_reconciler_helpers.go)====&lt;br /&gt;
This method takes care of posting a request to the NDS endpoint to provision database. Should be modified to allow the same on cloud. This method should take care of a helper method logic to determine the correct request data structure and endpoint to be used. We have currently implemented a part of this logic as part of the ndbClient. &lt;br /&gt;
'''Note: This can only be implemented after obtaining the access. We are still waiting on it and will implement it as soon as we obtain it.'''&lt;br /&gt;
&lt;br /&gt;
====SetupConnectivity(database_reconciler_helpers.go)====&lt;br /&gt;
This function checks and creates a new service (without label selectors) if it does not exists and also sets up the database as the owner for the created service. This also checks and creates an endpoints object for the service if it does not already exists.&lt;br /&gt;
&lt;br /&gt;
'''Note: This is the last part of the serial steps. The previous steps must be completed in order to write this logic.'''&lt;br /&gt;
&lt;br /&gt;
==Test plan==&lt;br /&gt;
===Runing tests===&lt;br /&gt;
Pull the code, cd into the directory and run:&lt;br /&gt;
 &lt;br /&gt;
   make test&lt;br /&gt;
&lt;br /&gt;
This runs all the required tests as specified in the Makefile.&lt;br /&gt;
&lt;br /&gt;
===Test Scenarios===&lt;br /&gt;
# Testing construction of provision request - All test cases for this that are currently written for on-prem must work for cloud '''remoteType''' too. &lt;br /&gt;
# Additional tests for fields that are mandatory for requests constructed for provisioning in cloud&lt;br /&gt;
# Verify that the correct API endpoints are being hit based on the remote type specified - On-Prem should hit 0.9 API and cloud should hit 1.0 API&lt;br /&gt;
# Test the connectivity between the K8 service and the deployed DB on EC2. &lt;br /&gt;
&lt;br /&gt;
===Actions to be taken before Manual testing===&lt;br /&gt;
Manual testing would require you to get access to the Nutanix Database Service&lt;br /&gt;
&lt;br /&gt;
# Obtain access to Nutanix Database Service SASS and access keys for the AWS EC2 instance.&lt;br /&gt;
&lt;br /&gt;
# Add the appropriate credentials to the secrets.yaml file.&lt;br /&gt;
&lt;br /&gt;
# Apply your manifest instance using :&lt;br /&gt;
   kubectl apply -f &amp;lt;your manifest instance file&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can verify the status of provisioning in your NDB dashboard.&lt;br /&gt;
&lt;br /&gt;
==Future Implementation==&lt;br /&gt;
* Obtain EC2 keys and connect NDS to the EC2 instance&lt;br /&gt;
* Construct provision request for provisioning DB in cloud&lt;br /&gt;
* Add logic to select proper endpoint and request based on the '''remoteType'''&lt;br /&gt;
* Add logic to de-provision the database.&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/arvindsrinivas1/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pull/73&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Arvind Srinivas Subramanian (asubram9)&lt;br /&gt;
* Dhanya Sri Dasari (ddasari)&lt;br /&gt;
* Zhihao Wang (zwang238@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
	<entry>
		<id>https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023-_NTNX-4._Extend_NDB_operator_provision_postregresql_aws&amp;diff=148019</id>
		<title>CSC/ECE 517 Spring 2023- NTNX-4. Extend NDB operator provision postregresql aws</title>
		<link rel="alternate" type="text/html" href="https://wiki.expertiza.ncsu.edu/index.php?title=CSC/ECE_517_Spring_2023-_NTNX-4._Extend_NDB_operator_provision_postregresql_aws&amp;diff=148019"/>
		<updated>2023-03-22T23:05:09Z</updated>

		<summary type="html">&lt;p&gt;Pkamath3: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==NTNX-4. Extend Nutanix Database Service Kubernetes operator to provision Postgres Single Instance databases on AWS EC2==&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Note to the reviewer==&lt;br /&gt;
A major part of the logic can only be written after we get access to the keys of an EC2 instance that we can connect to the Nutanix Database Service. This differs from other NTNX teams since we need to provision the database on AWS. Hence, we cannot use the Test Nutanix endpoint to create clusterID or Secret's name. We have added a '''Note''' section in the Implementation section to inform the parts which fall under this category. We have also added this information collectively under the '''Future Implementation''' section.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Problem Statement==&lt;br /&gt;
Nutanix Database Service is the only hybrid cloud database-as-a-service for Microsoft SQL&lt;br /&gt;
Server, Oracle Database, PostgreSQL, MongoDB, and MySQL. Currently, using the NDB operator, you can only provision a database on the Nutanix Cloud Infrastructure(on-prem).This project aims to extend the Nutanix Database Service Kubernetes operator to provision Postgres Single Instance databases on cloud - specifically on AWS EC2. We aim to do this in a scalable way so that changing the cloud provider to say Azure or GCP would require changes only to the configuration file(CRD Manifest).&lt;br /&gt;
&lt;br /&gt;
==Github==&lt;br /&gt;
Repo(Public): https://github.com/arvindsrinivas1/ndb-operator&lt;br /&gt;
Pull Request: https://github.com/nutanix-cloud-native/ndb-operator/pull/73&lt;br /&gt;
&lt;br /&gt;
==Mentors==&lt;br /&gt;
* Prof. Edward F. Gehringer&lt;br /&gt;
* Krunal Jhaveri&lt;br /&gt;
* Manav Rajvanshi&lt;br /&gt;
* Krishna Saurabh Vankadaru&lt;br /&gt;
&lt;br /&gt;
==Contributors==&lt;br /&gt;
* Arvind Srinivas Subramanian (asubram9)&lt;br /&gt;
* Dhanya Sri Dasari (ddasari)&lt;br /&gt;
* Zhihao Wang (zwang238@ncsu.edu)&lt;/div&gt;</summary>
		<author><name>Pkamath3</name></author>
	</entry>
</feed>