Repository: chef/automate
Pull request #7860 (2023-05-04 10:53:22)

Chef 2602 Batch-Check API 
### :nut_and_bolt: Description: What code changed, and why?

<!-- /!\ Please ensure that you are NOT disclosing any customer information without their consent /!\ -->

### :chains: Related Resources

### :+1: Definition of Done

### :athletic_shoe: How to Build and Test the Change

### :white_check_mark: Checklist

**All PRs** must tick these:

- [ ] I have read the [CONTRIBUTING document](https://github.com/chef/automate/blob/master/CONTRIBUTING.md).
- [ ] All commits signed-off for the [Developer Certification of Origin](https://github.com/chef/chef/blob/master/CONTRIBUTING.md#developer-certification-of-origin-dco).

With occasional exceptions, all PRs **from Progress employees** must tick these:

- [ ] Is the code clear? *(complicated code or lots of comments--subdivide and use well-named methods, meaningful variable names, etc.)*
- [ ] Consistency checked? *(user notifications, user prompts, visual patterns, code patterns, variable names)*
- [ ] Repeated code blocks eliminated? *(adapt and reuse existing components, blocks, functions, etc.)*
- [ ] Spelling, grammar, typos checked? *(at a minimum use `make spell` in any component directory)*
- [ ] Code well-formatted? *(indents, line breaks, etc. improve rather than hinder readability)*

All PRs **from Progress employees** should tick these if appropriate:

- [ ] Tests added/updated? (all new code needs new tests)
- [ ] Docs added/updated? (all customer-facing changes)

*Please add a note next to any checkbox above if you are NOT ticking it.*

### :camera: Screenshots, if applicable


netlify[bot]: ### <span aria-hidden="true">👷</span> Deploy Preview for *chef-automate* processing.


|  Name | Link |
|:-:|------------------------|
|<span aria-hidden="true">🔨</span> Latest commit | 643ae5b24d270206ab3a95e91d3ab19a5a6f99e7 |
|<span aria-hidden="true">🔍</span> Latest deploy log | https://app.netlify.com/sites/chef-automate/deploys/64538ea53a839100087c038e |
sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Coverage on New Code (is less than 80%)  
[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![14.9%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/Duplications/20-16px.png '14.9%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 14.88% Duplicated Lines (%) on New Code (is greater than 3%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Coverage on New Code (is less than 80%)  
[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![26.7%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/Duplications/20plus-16px.png '26.7%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 26.72% Duplicated Lines (%) on New Code (is greater than 3%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![62.1%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '62.1%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 62.11% Coverage on New Code (is less than 80%)  
[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![13.5%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/Duplications/20-16px.png '13.5%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 13.54% Duplicated Lines (%) on New Code (is greater than 3%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![65.1%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '65.1%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 65.07% Coverage on New Code (is less than 80%)  
[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![14.8%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/Duplications/20-16px.png '14.8%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 14.81% Duplicated Lines (%) on New Code (is greater than 3%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![66.1%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '66.1%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 66.07% Coverage on New Code (is less than 80%)  
[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![13.3%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/Duplications/20-16px.png '13.3%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 13.28% Duplicated Lines (%) on New Code (is greater than 3%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![64.5%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '64.5%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 64.55% Coverage on New Code (is less than 80%)  
[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![12.9%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/Duplications/20-16px.png '12.9%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 12.91% Duplicated Lines (%) on New Code (is greater than 3%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![64.5%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '64.5%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 64.55% Coverage on New Code (is less than 80%)  
[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![12.9%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/Duplications/20-16px.png '12.9%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 12.91% Duplicated Lines (%) on New Code (is greater than 3%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![66.8%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '66.8%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 66.77% Coverage on New Code (is less than 80%)  
[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![12.8%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/Duplications/20-16px.png '12.8%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 12.76% Duplicated Lines (%) on New Code (is greater than 3%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![73.8%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '73.8%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 73.77% Coverage on New Code (is less than 80%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![20.6%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '20.6%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 20.59% Coverage on New Code (is less than 80%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![74.6%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '74.6%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 74.59% Coverage on New Code (is less than 80%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![74.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '74.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 74.04% Coverage on New Code (is less than 80%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![75.2%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '75.2%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 75.22% Coverage on New Code (is less than 80%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![74.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '74.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 74.04% Coverage on New Code (is less than 80%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![74.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '74.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 74.04% Coverage on New Code (is less than 80%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![75.2%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '75.2%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 75.22% Coverage on New Code (is less than 80%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![77.5%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '77.5%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 77.46% Coverage on New Code (is less than 80%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![77.5%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/60-16px.png '77.5%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 77.46% Coverage on New Code (is less than 80%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)


sonarqube-for-infrastructure-prod[bot]: **SonarQube Quality Gate**

[![Quality Gate failed](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/QualityGateBadge/failed-16px.png 'Quality Gate failed')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)

[![Failed condition](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/FailedConditionIcon-16px.png 'Failed condition')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) [![16.7%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '16.7%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 16.67% Coverage on New Code (is less than 80%)  
[![0.0%](https://raw.githubusercontent.com/SonarSource/sonarqube-static-resources/master/v97/checks/CoverageChart/0-16px.png '0.0%')](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860) 0.0% Security Hotspots Reviewed on New Code (is less than 100%)  

[See analysis details on SonarQube](https://sonar.progress.com/dashboard?id=chef_automate_AYeOVEbqJ4YHsO5MtKWC&pullRequest=7860)



Patch:
diff --git a/components/automate-cli/pkg/verifyserver/constants/checkconstant.go b/components/automate-cli/pkg/verifyserver/constants/checkconstant.go
new file mode 100644
index 000000000..2c0b94585
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/constants/checkconstant.go
@@ -0,0 +1,40 @@
+package constants
+
+const HARDWARE_RESOURCE_COUNT = "hardware-resource-count"
+const CERTIFICATE = "certificate"
+const SSH_USER = "ssh-user"
+const SYSTEM_RESOURCES = "system-resources"
+const SOFTWARE_VERSIONS = "software-versions"
+const SYSTEM_USER = "system-user"
+const S3_BACKUP_CONFIG = "s3-backup-config"
+const FQDN = "fqdn"
+const FIREWALL = "firewall"
+const EXTERNAL_OPENSEARCH = "external-opensearch"
+const AWS_OPENSEARCH_S3_BUCKET_ACCESS = "aws-opensearch-s3-bucket-access"
+const EXTERNAL_POSTGRESQL = "external-postgresql"
+const NFS_BACKUP_CONFIG = "nfs-backup-config"
+
+func GetBastionChecks() []string {
+	var checks = []string{
+		HARDWARE_RESOURCE_COUNT,
+		CERTIFICATE,
+		SSH_USER,
+	}
+	return checks
+}
+
+func GetRemoteChecks() []string {
+	var checks = []string{
+		SYSTEM_RESOURCES,
+		SOFTWARE_VERSIONS,
+		SYSTEM_USER,
+		S3_BACKUP_CONFIG,
+		FQDN,
+		FIREWALL,
+		EXTERNAL_OPENSEARCH,
+		AWS_OPENSEARCH_S3_BUCKET_ACCESS,
+		EXTERNAL_POSTGRESQL,
+		NFS_BACKUP_CONFIG,
+	}
+	return checks
+}
diff --git a/components/automate-cli/pkg/verifyserver/models/batchcheck.go b/components/automate-cli/pkg/verifyserver/models/batchcheck.go
new file mode 100644
index 000000000..7b878b9f3
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/models/batchcheck.go
@@ -0,0 +1,107 @@
+package models
+
+type BatchCheckRequest struct {
+	Checks []string `json:"checks"`
+	Config Config   `json:"config"`
+}
+
+type Hardware struct {
+	AutomateNodeCount        int      `json:"automate_node_count"`
+	AutomateNodeIps          []string `json:"automate_node_ips"`
+	ChefInfraServerNodeCount int      `json:"chef_infra_server_node_count"`
+	ChefInfraServerNodeIps   []string `json:"chef_infra_server_node_ips"`
+	PostgresqlNodeCount      int      `json:"postgresql_node_count"`
+	PostgresqlNodeIps        []string `json:"postgresql_node_ips"`
+	OpenSearchNodeCount      int      `json:"opensearch_node_count"`
+	OpenSearchNodeIps        []string `json:"opensearch_node_ips"`
+}
+type SSHUser struct {
+	Username     string `json:"user_name"`
+	PrivateKey   string `json:"private_key"`
+	SudoPassword string `json:"sudo_password"`
+}
+
+type FileSystem struct {
+	MountLocation string `json:"mount_location"`
+}
+type ObjectStorage struct {
+	Endpoint   string `json:"endpoint"`
+	BucketName string `json:"bucket_name"`
+	BasePath   string `json:"base_path"`
+	AccessKey  string `json:"access_key"`
+	SecretKey  string `json:"secret_key"`
+}
+type Backup struct {
+	FileSystem    FileSystem    `json:"file_system"`
+	ObjectStorage ObjectStorage `json:"object_storage"`
+}
+
+type Certificate struct {
+	Fqdn     string     `json:"fqdn"`
+	RootCert string     `json:"root_cert"`
+	Nodes    []NodeCert `json:"nodes"`
+}
+
+type ExternalOS struct {
+	OSDomainName   string `json:"opensearch_domain_name"`
+	OSDomainURL    string `json:"opensearch_domain_url"`
+	OSUsername     string `json:"opensearch_usename"`
+	OSUserPassword string `json:"opensearch_user_password"`
+	OSCert         string `json:"opensearch_cert"`
+}
+
+type ExternalPG struct {
+	PGInstanceURL       string `json:"postgresql_instance_url"`
+	PGSuperuserName     string `json:"postgresql_superuser_username"`
+	PGSuperuserPassword string `json:"postgresql_superuser_password"`
+	PGDbUserName        string `json:"postgresql_dbuser_username"`
+	PGDbUserPassword    string `json:"postgresql_dbuser_password"`
+	PGRootCert          string `json:"postgresql_root_cert"`
+}
+
+type Config struct {
+	SSHUser     SSHUser     `json:"ssh_user"`
+	Arch        string      `json:"arch"`
+	Backup      Backup      `json:"backup"`
+	Hardware    Hardware    `json:"hardware"`
+	Certificate Certificate `json:"certificate"`
+	ExternalOS  ExternalOS  `json:"external_opensearch"`
+	ExternalPG  ExternalPG  `json:"external_postgresql"`
+}
+
+type BatchCheckResponse struct {
+	Status string             `json:"status"`
+	Result []BatchCheckResult `json:"result"`
+}
+type BatchCheckResult struct {
+	NodeType string      `json:"node_type"`
+	Ip       string      `json:"ip"`
+	Tests    []ApiResult `json:"tests"`
+}
+
+type CheckTriggerResponse struct {
+	Status string    `json:"status"`
+	Result ApiResult `json:"result"`
+}
+type ApiResult struct {
+	Passed  bool     `json:"passed"`
+	Message string   `json:"msg"`
+	Check   string   `json:"check"`
+	Checks  []Checks `json:"checks"`
+}
+
+type Checks struct {
+	Title         string `json:"title"`
+	Passed        bool   `json:"passed"`
+	SuccessMsg    string `json:"success_msg"`
+	ErrorMsg      string `json:"error_msg"`
+	ResolutionMsg string `json:"resolution_msg"`
+}
+
+type NodeCert struct {
+	IP        string `json:"ip"`
+	Cert      string `json:"cert"`
+	Key       string `json:"key"`
+	AdminKey  string `json:"admin_key"`
+	AdminCert string `json:"admin_cert"`
+}
diff --git a/components/automate-cli/pkg/verifyserver/server/api/v1/batchcheck.go b/components/automate-cli/pkg/verifyserver/server/api/v1/batchcheck.go
new file mode 100644
index 000000000..1d877603e
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/server/api/v1/batchcheck.go
@@ -0,0 +1,43 @@
+package v1
+
+import (
+	"errors"
+	"fmt"
+
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/constants"
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+	"github.com/chef/automate/lib/stringutils"
+	"github.com/gofiber/fiber"
+)
+
+func (h *Handler) BatchCheck(c *fiber.Ctx) {
+	req := new(models.BatchCheckRequest)
+	if err := c.BodyParser(req); err != nil {
+		errString := fmt.Sprintf("batch check request body parsing failed: %v", err.Error())
+		h.Logger.Error(fmt.Errorf(errString))
+		c.Status(fiber.StatusBadRequest).JSON(errString)
+		return
+	}
+	err := validateChecks(req.Checks)
+	if err != nil {
+		c.Status(fiber.StatusBadRequest).JSON(err.Error())
+		return
+	}
+
+	resp := h.BatchCheckService.BatchCheck(req.Checks, req.Config)
+	c.Status(fiber.StatusOK).JSON(resp)
+}
+
+func validateChecks(checks []string) error {
+	if len(checks) == 0 {
+		err := errors.New("check cannot be empty")
+		return err
+	}
+	allChecks := append(constants.GetBastionChecks(), constants.GetRemoteChecks()...)
+	diff := stringutils.SliceDifference(checks, allChecks)
+	if len(diff) > 0 {
+		err := fmt.Errorf("following checks are not supported %v", diff)
+		return err
+	}
+	return nil
+}
diff --git a/components/automate-cli/pkg/verifyserver/server/api/v1/handler.go b/components/automate-cli/pkg/verifyserver/server/api/v1/handler.go
index 1a5bd1366..96ef43eb1 100644
--- a/components/automate-cli/pkg/verifyserver/server/api/v1/handler.go
+++ b/components/automate-cli/pkg/verifyserver/server/api/v1/handler.go
@@ -1,6 +1,7 @@
 package v1
 
 import (
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/services/batchcheckservice"
 	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/services/statusservice"
 	"github.com/chef/automate/lib/logger"
 )
@@ -8,6 +9,7 @@ import (
 type Handler struct {
 	Logger        logger.Logger
 	StatusService statusservice.IStatusService
+	BatchCheckService batchcheckservice.IBatchCheckService
 }
 
 func NewHandler(logger logger.Logger) *Handler {
@@ -18,3 +20,8 @@ func (h *Handler) AddStatusService(ss statusservice.IStatusService) *Handler {
 	h.StatusService = ss
 	return h
 }
+
+func (h *Handler) AddBatchCheckService(bc batchcheckservice.IBatchCheckService) *Handler {
+	h.BatchCheckService = bc
+	return h
+}
diff --git a/components/automate-cli/pkg/verifyserver/server/routes.go b/components/automate-cli/pkg/verifyserver/server/routes.go
index fe1449b20..362ef904c 100644
--- a/components/automate-cli/pkg/verifyserver/server/routes.go
+++ b/components/automate-cli/pkg/verifyserver/server/routes.go
@@ -12,6 +12,7 @@ func (vs *VerifyServer) SetupRoutes() {
 	apiV1Group := apiGroup.Group("/v1")
 	apiChecksGroup := apiV1Group.Group("/checks")
 	apiChecksGroup.Get("/fqdn", vs.Handler.CheckFqdn)
+	apiChecksGroup.Post("/batch-checks", vs.Handler.BatchCheck)
 
 	fiberutils.LogResgisteredRoutes(vs.App.Stack(), vs.Log)
 }
diff --git a/components/automate-cli/pkg/verifyserver/server/server.go b/components/automate-cli/pkg/verifyserver/server/server.go
index ae272181b..8565507d3 100644
--- a/components/automate-cli/pkg/verifyserver/server/server.go
+++ b/components/automate-cli/pkg/verifyserver/server/server.go
@@ -5,6 +5,8 @@ import (
 
 	"github.com/ansrivas/fiberprometheus"
 	v1 "github.com/chef/automate/components/automate-cli/pkg/verifyserver/server/api/v1"
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/services/batchcheckservice"
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger"
 	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/services/statusservice"
 	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/utils/fiberutils"
 	"github.com/chef/automate/lib/logger"
@@ -42,7 +44,24 @@ func NewVerifyServer(port string, debug bool) (*VerifyServer, error) {
 	}
 	app := fiber.New(fconf)
 	handler := v1.NewHandler(l).
-		AddStatusService(statusservice.NewStatusService())
+		AddStatusService(
+			statusservice.NewStatusService()).
+		AddBatchCheckService(
+			batchcheckservice.NewBatchCheckService(trigger.NewCheckTrigger(
+				trigger.NewHardwareResourceCountCheck(),
+				trigger.NewSshUserAccessCheck(),
+				trigger.NewCertificateCheck(),
+				trigger.NewExternalOpensearchCheck(),
+				trigger.NewExternalPostgresCheck(),
+				trigger.NewFirewallCheck(),
+				trigger.NewFqdnCheck(),
+				trigger.NewNfsBackupConfigCheck(),
+				trigger.NewOpensearchS3BucketAccessCheck(),
+				trigger.NewS3BackupConfigCheck(),
+				trigger.NewSoftwareVersionCheck(),
+				trigger.NewSystemResourceCheck(),
+				trigger.NewSshUserAccessCheck(),
+			)))
 	vs := &VerifyServer{
 		Port:    port,
 		Log:     l,
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/batchcheckservice.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/batchcheckservice.go
new file mode 100644
index 000000000..4c5a1f132
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/batchcheckservice.go
@@ -0,0 +1,133 @@
+package batchcheckservice
+
+import (
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/constants"
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger"
+	"github.com/chef/automate/lib/stringutils"
+)
+
+type IBatchCheckService interface {
+	BatchCheck(checks []string, config models.Config) models.BatchCheckResponse
+}
+
+type BatchCheckService struct {
+	CheckTrigger trigger.CheckTrigger
+}
+
+func NewBatchCheckService(trigger trigger.CheckTrigger) *BatchCheckService {
+	return &BatchCheckService{
+		CheckTrigger: trigger,
+	}
+}
+
+func (ss *BatchCheckService) BatchCheck(checks []string, config models.Config) models.BatchCheckResponse {
+	batchApisResultMap := make(map[string][]models.ApiResult)
+	var bastionChecks = stringutils.SliceIntersection(checks, constants.GetBastionChecks())
+	var remoteChecks = stringutils.SliceIntersection(checks, constants.GetRemoteChecks())
+	if len(bastionChecks) > 0 {
+		bastionCheckResultChan := make(chan map[string]models.CheckTriggerResponse, len(bastionChecks))
+		for _, check := range bastionChecks {
+			go ss.RunBastionCheck(check, config, bastionCheckResultChan)
+		}
+		for i := 0; i < len(bastionChecks); i++ {
+			result := <-bastionCheckResultChan
+			for k, v := range result {
+				checkIndex, _ := getIndexOfCheck(bastionChecks, v.Result.Check)
+				if checkIndex >= len(batchApisResultMap[k]) {
+					batchApisResultMap[k] = append(batchApisResultMap[k], v.Result)
+				} else {
+					batchApisResultMap[k] = append(batchApisResultMap[k], models.ApiResult{})
+					copy(batchApisResultMap[k][checkIndex+1:], batchApisResultMap[k][checkIndex:])
+					batchApisResultMap[k][checkIndex] = v.Result
+				}
+			}
+		}
+		defer close(bastionCheckResultChan)
+	}
+	if len(remoteChecks) > 0 {
+		for _, check := range remoteChecks {
+			resp := ss.RunRemoteCheck(check, config)
+			for k, v := range resp {
+				batchApisResultMap[k] = append(batchApisResultMap[k], v.Result)
+			}
+		}
+	}
+	return constructBatchCheckResponse(batchApisResultMap, config.Hardware)
+}
+
+func getIndexOfCheck(checks []string, check string) (int, error) {
+	return stringutils.IndexOf(checks, check)
+}
+
+func (ss *BatchCheckService) RunBastionCheck(check string, config models.Config, resultChan chan map[string]models.CheckTriggerResponse) {
+	resp := ss.getCheckInstance(check).Run(config)
+	resultChan <- resp
+}
+
+func (ss *BatchCheckService) RunRemoteCheck(check string, config models.Config) map[string]models.CheckTriggerResponse {
+	return ss.getCheckInstance(check).Run(config)
+}
+
+func (ss *BatchCheckService) getCheckInstance(check string) trigger.ICheck {
+	switch check {
+	case constants.HARDWARE_RESOURCE_COUNT:
+		return ss.CheckTrigger.HardwareResourceCountCheck
+	case constants.CERTIFICATE:
+		return ss.CheckTrigger.CertificateCheck
+	case constants.SSH_USER:
+		return ss.CheckTrigger.SshUserAccessCheck
+	case constants.SYSTEM_RESOURCES:
+		return ss.CheckTrigger.SystemResourceCheck
+	case constants.SOFTWARE_VERSIONS:
+		return ss.CheckTrigger.SoftwareVersionCheck
+	case constants.SYSTEM_USER:
+		return ss.CheckTrigger.SystemUserCheck
+	case constants.S3_BACKUP_CONFIG:
+		return ss.CheckTrigger.S3BackupConfigCheck
+	case constants.FQDN:
+		return ss.CheckTrigger.FqdnCheck
+	case constants.FIREWALL:
+		return ss.CheckTrigger.FirewallCheck
+	case constants.EXTERNAL_OPENSEARCH:
+		return ss.CheckTrigger.ExternalOpensearchCheck
+	case constants.AWS_OPENSEARCH_S3_BUCKET_ACCESS:
+		return ss.CheckTrigger.OpensearchS3BucketAccessCheck
+	case constants.EXTERNAL_POSTGRESQL:
+		return ss.CheckTrigger.ExternalPostgresCheck
+	case constants.NFS_BACKUP_CONFIG:
+		return ss.CheckTrigger.NfsBackupConfigCheck
+	}
+	return nil
+}
+
+func constructBatchCheckResponse(batchApisResultMap map[string][]models.ApiResult, hardwareDetails models.Hardware) models.BatchCheckResponse {
+	var result = make([]models.BatchCheckResult, len(batchApisResultMap))
+	var resultIndex = 0
+	for k, v := range batchApisResultMap {
+		result[resultIndex].Ip = k
+		result[resultIndex].NodeType = getNodeTypeFromIp(k, hardwareDetails)
+		result[resultIndex].Tests = v
+		resultIndex = resultIndex + 1
+	}
+	return models.BatchCheckResponse{
+		Status: "SUCCESS",
+		Result: result,
+	}
+}
+
+func getNodeTypeFromIp(ip string, hardwareDetails models.Hardware) string {
+	if stringutils.SliceContains(hardwareDetails.AutomateNodeIps, ip) {
+		return "automate"
+	}
+	if stringutils.SliceContains(hardwareDetails.ChefInfraServerNodeIps, ip) {
+		return "chef_server"
+	}
+	if stringutils.SliceContains(hardwareDetails.PostgresqlNodeIps, ip) {
+		return "postgresql"
+	}
+	if stringutils.SliceContains(hardwareDetails.OpenSearchNodeIps, ip) {
+		return "opensearch"
+	}
+	return ""
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/batchcheckservicemock.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/batchcheckservicemock.go
new file mode 100644
index 000000000..4c4069a94
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/batchcheckservicemock.go
@@ -0,0 +1,368 @@
+package batchcheckservice
+
+import (
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/constants"
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger"
+)
+
+type MockBatchCheckService struct {
+	BatchCheckFunc func([]string, models.Config) models.BatchCheckResponse
+}
+
+func (mss *MockBatchCheckService) BatchCheck(checks []string, config models.Config) models.BatchCheckResponse {
+	return mss.BatchCheckFunc(checks, config)
+}
+
+type MockHardwareResourceCountCheck struct {
+	HardwareResourceCountCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockHardwareResourceCountCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.HardwareResourceCountCheckFunc(config)
+}
+
+func SetupMockHardwareResourceCountCheck() trigger.ICheck {
+	return &MockHardwareResourceCountCheck{
+		HardwareResourceCountCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{
+				"1.2.3.4": {
+					Status: "Passed",
+					Result: models.ApiResult{
+						Passed:  false,
+						Check:   "hardware-resource-count",
+						Message: "Hardware Resource Count Check",
+						Checks: []models.Checks{
+							{
+								Title: "hardware-resource-check-1",
+							},
+							{
+								Title: "hardware-resource-check-2",
+							},
+						},
+					},
+				},
+				"1.2.4.5": {
+					Status: "Passed",
+					Result: models.ApiResult{
+						Passed:  true,
+						Check:   "hardware-resource-count",
+						Message: "Hardware Resource Count Check",
+						Checks: []models.Checks{
+							{
+								Title: "hardware-resource-check-1",
+							},
+							{
+								Title: "hardware-resource-check-2",
+							},
+						},
+					},
+				},
+			}
+			return m
+		},
+	}
+}
+
+type MockSshUserAccessCheck struct {
+	SshUserAccessCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockSshUserAccessCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.SshUserAccessCheckFunc(config)
+}
+
+func SetupMockSshUserAccessCheck() trigger.ICheck {
+	return &MockSshUserAccessCheck{
+		SshUserAccessCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{
+				"1.2.3.4": {
+					Status: "Passed",
+					Result: models.ApiResult{
+						Passed:  false,
+						Check:   constants.SSH_USER,
+						Message: "ssh-user-check",
+						Checks: []models.Checks{
+							{
+								Title: "ssh-user-check-1",
+							},
+							{
+								Title: "ssh-user-check-2",
+							},
+						},
+					},
+				},
+				"1.2.4.5": {
+					Status: "Passed",
+					Result: models.ApiResult{
+						Passed:  true,
+						Check:   constants.SSH_USER,
+						Message: "ssh-user-check",
+						Checks: []models.Checks{
+							{
+								Title: "ssh-user-check-1",
+							},
+							{
+								Title: "ssh-user-check-2",
+							},
+						},
+					},
+				},
+			}
+			return m
+		},
+	}
+}
+
+type MockCertificateCheck struct {
+	CertificateCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockCertificateCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.CertificateCheckFunc(config)
+}
+
+func SetupMockCertificateCheck() trigger.ICheck {
+	return &MockCertificateCheck{
+		CertificateCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{}
+			return m
+		},
+	}
+}
+
+type MockExternalOpensearchCheck struct {
+	ExternalOpensearchCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockExternalOpensearchCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.ExternalOpensearchCheckFunc(config)
+}
+
+func SetupMockExternalOpensearchCheck() trigger.ICheck {
+	return &MockExternalOpensearchCheck{
+		ExternalOpensearchCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{}
+			return m
+		},
+	}
+}
+
+type MockExternalPostgresCheck struct {
+	ExternalPostgresCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockExternalPostgresCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.ExternalPostgresCheckFunc(config)
+}
+
+func SetupMockExternalPostgresCheck() trigger.ICheck {
+	return &MockExternalPostgresCheck{
+		ExternalPostgresCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{}
+			return m
+		},
+	}
+}
+
+type MockFirewallCheck struct {
+	FirewallCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockFirewallCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.FirewallCheckFunc(config)
+}
+
+func SetupMockFirewallCheck() trigger.ICheck {
+	return &MockFirewallCheck{
+		FirewallCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{
+				"1.2.3.4": {
+					Status: "Passed",
+					Result: models.ApiResult{
+						Passed:  false,
+						Check:   constants.FIREWALL,
+						Message: "Firewall-check",
+						Checks: []models.Checks{
+							{
+								Title: "Firewall-check-1",
+							},
+							{
+								Title: "Firewall-check-2",
+							},
+						},
+					},
+				},
+				"1.2.4.5": {
+					Status: "Passed",
+					Result: models.ApiResult{
+						Passed:  true,
+						Check:   constants.FIREWALL,
+						Message: "Firewall-check",
+						Checks: []models.Checks{
+							{
+								Title: "Firewall-check-1",
+							},
+							{
+								Title: "Firewall-check-2",
+							},
+						},
+					},
+				},
+			}
+			return m
+		},
+	}
+}
+
+type MockFqdnCheck struct {
+	FqdnCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockFqdnCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.FqdnCheckFunc(config)
+}
+
+func SetupMockFqdnCheck() trigger.ICheck {
+	return &MockFqdnCheck{
+		FqdnCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{
+				"1.2.3.4": {
+					Status: "Passed",
+					Result: models.ApiResult{
+						Passed:  false,
+						Check:   constants.FQDN,
+						Message: "fqdn-check",
+						Checks: []models.Checks{
+							{
+								Title: "Fqdn-check-1",
+							},
+							{
+								Title: "Fqdn-check-2",
+							},
+						},
+					},
+				},
+				"1.2.4.5": {
+					Status: "Passed",
+					Result: models.ApiResult{
+						Passed:  true,
+						Check:   constants.FQDN,
+						Message: "fqdn-check",
+						Checks: []models.Checks{
+							{
+								Title: "Fqdn-check-1",
+							},
+							{
+								Title: "Fqdn-check-2",
+							},
+						},
+					},
+				},
+			}
+			return m
+		},
+	}
+}
+
+type MockNfsBackupConfigCheck struct {
+	NfsBackupConfigCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockNfsBackupConfigCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.NfsBackupConfigCheckFunc(config)
+}
+
+func SetupMockNfsBackupConfigCheck() trigger.ICheck {
+	return &MockNfsBackupConfigCheck{
+		NfsBackupConfigCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{}
+			return m
+		},
+	}
+}
+
+type MockOpensearchS3BucketAccessCheck struct {
+	OpensearchS3BucketAccessCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockOpensearchS3BucketAccessCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.OpensearchS3BucketAccessCheckFunc(config)
+}
+
+func SetupMockOpensearchS3BucketAccessCheck() trigger.ICheck {
+	return &MockOpensearchS3BucketAccessCheck{
+		OpensearchS3BucketAccessCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{}
+			return m
+		},
+	}
+}
+
+type MockS3BackupConfigCheck struct {
+	S3BackupConfigCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockS3BackupConfigCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.S3BackupConfigCheckFunc(config)
+}
+
+func SetupMockS3BackupConfigCheck() trigger.ICheck {
+	return &MockS3BackupConfigCheck{
+		S3BackupConfigCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{}
+			return m
+		},
+	}
+}
+
+type MockSoftwareVersionCheck struct {
+	SoftwareVersionCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockSoftwareVersionCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.SoftwareVersionCheckFunc(config)
+}
+
+func SetupMockSoftwareVersionCheck() trigger.ICheck {
+	return &MockSoftwareVersionCheck{
+		SoftwareVersionCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{}
+			return m
+		},
+	}
+}
+
+type MockSystemResourceCheck struct {
+	SystemResourceCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockSystemResourceCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.SystemResourceCheckFunc(config)
+}
+
+func SetupMockSystemResourceCheck() trigger.ICheck {
+	return &MockSystemResourceCheck{
+		SystemResourceCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{}
+			return m
+		},
+	}
+}
+
+type MockSystemUserCheck struct {
+	SystemUserCheckFunc func(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func (mss *MockSystemUserCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	return mss.SystemUserCheckFunc(config)
+}
+
+func SetupMockSystemUserCheck() trigger.ICheck {
+	return &MockSystemUserCheck{
+		SystemUserCheckFunc: func(config models.Config) map[string]models.CheckTriggerResponse {
+			m := map[string]models.CheckTriggerResponse{}
+			return m
+		},
+	}
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/certificatechecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/certificatechecktrigger.go
new file mode 100644
index 000000000..4164b813a
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/certificatechecktrigger.go
@@ -0,0 +1,17 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type CertificateCheck struct {
+}
+
+func NewCertificateCheck() *CertificateCheck {
+	return &CertificateCheck{}
+}
+
+func (ss *CertificateCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{
+		"f": models.CheckTriggerResponse{},
+	}
+	return m
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/checktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/checktrigger.go
new file mode 100644
index 000000000..9f52a2ae9
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/checktrigger.go
@@ -0,0 +1,40 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type CheckTrigger struct {
+	HardwareResourceCountCheck    ICheck
+	SshUserAccessCheck            ICheck
+	CertificateCheck              ICheck
+	ExternalOpensearchCheck       ICheck
+	ExternalPostgresCheck         ICheck
+	FirewallCheck                 ICheck
+	FqdnCheck                     ICheck
+	NfsBackupConfigCheck          ICheck
+	OpensearchS3BucketAccessCheck ICheck
+	S3BackupConfigCheck           ICheck
+	SoftwareVersionCheck          ICheck
+	SystemResourceCheck           ICheck
+	SystemUserCheck               ICheck
+}
+type ICheck interface {
+	Run(config models.Config) map[string]models.CheckTriggerResponse
+}
+
+func NewCheckTrigger(hrc, sshC, cert, eop, epc, fc, fqdn, nfs, os3, s3b, svc, src, suc ICheck) CheckTrigger {
+	return CheckTrigger{
+		HardwareResourceCountCheck:    hrc,
+		SshUserAccessCheck:            sshC,
+		CertificateCheck:              cert,
+		ExternalOpensearchCheck:       eop,
+		ExternalPostgresCheck:         epc,
+		FirewallCheck:                 fc,
+		FqdnCheck:                     fqdn,
+		NfsBackupConfigCheck:          nfs,
+		OpensearchS3BucketAccessCheck: os3,
+		S3BackupConfigCheck:           s3b,
+		SoftwareVersionCheck:          svc,
+		SystemResourceCheck:           src,
+		SystemUserCheck:               suc,
+	}
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/externalopensearchchecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/externalopensearchchecktrigger.go
new file mode 100644
index 000000000..3948b90cf
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/externalopensearchchecktrigger.go
@@ -0,0 +1,16 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type ExternalOpensearchCheck struct{}
+
+func NewExternalOpensearchCheck() *ExternalOpensearchCheck {
+	return &ExternalOpensearchCheck{}
+}
+
+func (ss *ExternalOpensearchCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{
+		"f": models.CheckTriggerResponse{},
+	}
+	return m
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/externalpostgreschecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/externalpostgreschecktrigger.go
new file mode 100644
index 000000000..5fee10231
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/externalpostgreschecktrigger.go
@@ -0,0 +1,16 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type ExternalPostgresCheck struct{}
+
+func NewExternalPostgresCheck() *ExternalPostgresCheck {
+	return &ExternalPostgresCheck{}
+}
+
+func (ss *ExternalPostgresCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{
+		"f": models.CheckTriggerResponse{},
+	}
+	return m
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger.go
new file mode 100644
index 000000000..c752ea062
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/firewallchecktrigger.go
@@ -0,0 +1,16 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type FirewallCheck struct{}
+
+func NewFirewallCheck() *FirewallCheck {
+	return &FirewallCheck{}
+}
+
+func (ss *FirewallCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{
+		"f": models.CheckTriggerResponse{},
+	}
+	return m
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/fqdnchecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/fqdnchecktrigger.go
new file mode 100644
index 000000000..01fde9bae
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/fqdnchecktrigger.go
@@ -0,0 +1,16 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type FqdnCheck struct{}
+
+func NewFqdnCheck() *FqdnCheck {
+	return &FqdnCheck{}
+}
+
+func (ss *FqdnCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{
+		"f": models.CheckTriggerResponse{},
+	}
+	return m
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/hardwareresourcecountchecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/hardwareresourcecountchecktrigger.go
new file mode 100644
index 000000000..633090720
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/hardwareresourcecountchecktrigger.go
@@ -0,0 +1,15 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type HardwareResourceCountCheck struct {
+}
+
+func NewHardwareResourceCountCheck() *HardwareResourceCountCheck {
+	return &HardwareResourceCountCheck{}
+}
+
+func (ss *HardwareResourceCountCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{}
+	return m
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/nfsbackupconfigcheck.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/nfsbackupconfigcheck.go
new file mode 100644
index 000000000..380831d8b
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/nfsbackupconfigcheck.go
@@ -0,0 +1,16 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type NfsBackupConfigCheck struct{}
+
+func NewNfsBackupConfigCheck() *NfsBackupConfigCheck {
+	return &NfsBackupConfigCheck{}
+}
+
+func (ss *NfsBackupConfigCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{
+		"f": models.CheckTriggerResponse{},
+	}
+	return m
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/opensearchs3bucketaccesschecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/opensearchs3bucketaccesschecktrigger.go
new file mode 100644
index 000000000..80676d400
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/opensearchs3bucketaccesschecktrigger.go
@@ -0,0 +1,16 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type OpensearchS3BucketAccessCheck struct{}
+
+func NewOpensearchS3BucketAccessCheck() *OpensearchS3BucketAccessCheck {
+	return &OpensearchS3BucketAccessCheck{}
+}
+
+func (ss *OpensearchS3BucketAccessCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{
+		"f": models.CheckTriggerResponse{},
+	}
+	return m
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/s3backupconfigchecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/s3backupconfigchecktrigger.go
new file mode 100644
index 000000000..85ad83c70
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/s3backupconfigchecktrigger.go
@@ -0,0 +1,16 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type S3BackupConfigCheck struct{}
+
+func NewS3BackupConfigCheck() *S3BackupConfigCheck {
+	return &S3BackupConfigCheck{}
+}
+
+func (ss *S3BackupConfigCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{
+		"f": models.CheckTriggerResponse{},
+	}
+	return m
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/softwareversionchecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/softwareversionchecktrigger.go
new file mode 100644
index 000000000..8bd8fb41a
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/softwareversionchecktrigger.go
@@ -0,0 +1,16 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type SoftwareVersionCheck struct{}
+
+func NewSoftwareVersionCheck() *SoftwareVersionCheck {
+	return &SoftwareVersionCheck{}
+}
+
+func (ss *SoftwareVersionCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{
+		"f": models.CheckTriggerResponse{},
+	}
+	return m
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/sshuseraccesschecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/sshuseraccesschecktrigger.go
new file mode 100644
index 000000000..05a285374
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/sshuseraccesschecktrigger.go
@@ -0,0 +1,15 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type SshUserAccessCheck struct {
+}
+
+func NewSshUserAccessCheck() *SshUserAccessCheck {
+	return &SshUserAccessCheck{}
+}
+
+func (ss *SshUserAccessCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{}
+	return m
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/systemresourceschecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/systemresourceschecktrigger.go
new file mode 100644
index 000000000..e12bb9306
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/systemresourceschecktrigger.go
@@ -0,0 +1,16 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type SystemResourceCheck struct{}
+
+func NewSystemResourceCheck() *SystemResourceCheck {
+	return &SystemResourceCheck{}
+}
+
+func (ss *SystemResourceCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{
+		"f": models.CheckTriggerResponse{},
+	}
+	return m
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/systemuserchecktrigger.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/systemuserchecktrigger.go
new file mode 100644
index 000000000..848c9f9d3
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger/systemuserchecktrigger.go
@@ -0,0 +1,16 @@
+package trigger
+
+import "github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+
+type SystemUserCheck struct{}
+
+func NewSystemUserCheck() *SystemUserCheck {
+	return &SystemUserCheck{}
+}
+
+func (ss *SystemUserCheck) Run(config models.Config) map[string]models.CheckTriggerResponse {
+	m := map[string]models.CheckTriggerResponse{
+		"f": models.CheckTriggerResponse{},
+	}
+	return m
+}
diff --git a/lib/stringutils/slice.go b/lib/stringutils/slice.go
index 50f377f44..1bedbcc33 100644
--- a/lib/stringutils/slice.go
+++ b/lib/stringutils/slice.go
@@ -19,6 +19,38 @@ func SubSlice(s1 []string, s2 []string) bool {
 	return true
 }
 
+// This method is used to return comman elements between the two slices
+func SliceIntersection(first, second []string) []string {
+	out := []string{}
+	bucket := map[string]bool{}
+
+	for _, i := range first {
+		for _, j := range second {
+			if i == j && !bucket[i] {
+				out = append(out, i)
+				bucket[i] = true
+			}
+		}
+	}
+
+	return out
+}
+
+// This method is used to return uncomman elements between the two slices
+func SliceDifference(a, b []string) []string {
+	mb := make(map[string]struct{}, len(b))
+	for _, x := range b {
+		mb[x] = struct{}{}
+	}
+	var diff []string
+	for _, x := range a {
+		if _, found := mb[x]; !found {
+			diff = append(diff, x)
+		}
+	}
+	return diff
+}
+
 func SliceContains(haystack []string, needle string) bool {
 	for _, s := range haystack {
 		if s == needle {


Test patch:
diff --git a/components/automate-cli/pkg/verifyserver/constants/checkconstant_test.go b/components/automate-cli/pkg/verifyserver/constants/checkconstant_test.go
new file mode 100644
index 000000000..9ef61d25d
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/constants/checkconstant_test.go
@@ -0,0 +1,30 @@
+package constants
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestGetBastionChecks(t *testing.T) {
+	resp := GetBastionChecks()
+	assert.Equal(t, len(resp), 3)
+	assert.Equal(t, resp[0], HARDWARE_RESOURCE_COUNT)
+	assert.Equal(t, resp[1], CERTIFICATE)
+	assert.Equal(t, resp[2], SSH_USER)
+}
+
+func TestGetRemoteChecks(t *testing.T) {
+	resp := GetRemoteChecks()
+	assert.Equal(t, len(resp), 10)
+	assert.Equal(t, resp[0], SYSTEM_RESOURCES)
+	assert.Equal(t, resp[1], SOFTWARE_VERSIONS)
+	assert.Equal(t, resp[2], SYSTEM_USER)
+	assert.Equal(t, resp[3], S3_BACKUP_CONFIG)
+	assert.Equal(t, resp[4], FQDN)
+	assert.Equal(t, resp[5], FIREWALL)
+	assert.Equal(t, resp[6], EXTERNAL_OPENSEARCH)
+	assert.Equal(t, resp[7], AWS_OPENSEARCH_S3_BUCKET_ACCESS)
+	assert.Equal(t, resp[8], EXTERNAL_POSTGRESQL)
+	assert.Equal(t, resp[9], NFS_BACKUP_CONFIG)
+}
diff --git a/components/automate-cli/pkg/verifyserver/server/api/v1/batchcheck_test.go b/components/automate-cli/pkg/verifyserver/server/api/v1/batchcheck_test.go
new file mode 100644
index 000000000..98f04dba0
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/server/api/v1/batchcheck_test.go
@@ -0,0 +1,177 @@
+package v1_test
+
+import (
+	"io/ioutil"
+	"net/http/httptest"
+	"strings"
+	"testing"
+
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/server"
+	v1 "github.com/chef/automate/components/automate-cli/pkg/verifyserver/server/api/v1"
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/services/batchcheckservice"
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/utils/fiberutils"
+	"github.com/chef/automate/lib/logger"
+	"github.com/gofiber/fiber"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func SetupMockBatchCheckService() batchcheckservice.IBatchCheckService {
+	return &batchcheckservice.MockBatchCheckService{
+		BatchCheckFunc: func(checks []string, config models.Config) models.BatchCheckResponse {
+			return models.BatchCheckResponse{
+				Status: "SUCCESS",
+				Result: []models.BatchCheckResult{
+					{
+						NodeType: "automate",
+						Ip:       "1.2.3.4",
+						Tests: []models.ApiResult{
+							{
+								Passed:  true,
+								Message: "success",
+								Check:   "hardware-resource-count",
+								Checks: []models.Checks{
+									{
+										Title:      "hardware-resource-count-1",
+										Passed:     true,
+										SuccessMsg: "success",
+									},
+									{
+										Title:      "hardware-resource-count-2",
+										Passed:     true,
+										SuccessMsg: "success",
+									},
+								},
+							},
+							{
+								Passed:  true,
+								Message: "success",
+								Check:   "ssh-user",
+								Checks: []models.Checks{
+									{
+										Title:      "ssh-user-1",
+										Passed:     true,
+										SuccessMsg: "success",
+									},
+									{
+										Title:      "ssh-user-2",
+										Passed:     true,
+										SuccessMsg: "success",
+									},
+								},
+							},
+						},
+					},
+				},
+			}
+		},
+	}
+}
+
+func SetupHandlers(ss batchcheckservice.IBatchCheckService) (*fiber.App, error) {
+	log, err := logger.NewLogger("text", "debug")
+	if err != nil {
+		return nil, err
+	}
+	fconf := &fiber.Settings{
+		ServerHeader: server.SERVICE,
+		ErrorHandler: fiberutils.CustomErrorHandler,
+	}
+	app := fiber.New(fconf)
+	handler := v1.NewHandler(log).
+		AddBatchCheckService(ss)
+	vs := &server.VerifyServer{
+		Port:    server.DEFAULT_PORT,
+		Log:     log,
+		App:     app,
+		Handler: handler,
+	}
+	vs.SetupRoutes()
+	return vs.App, nil
+}
+
+func TestBatchCheckAPI(t *testing.T) {
+	tests := []struct {
+		description  string
+		expectedCode int
+		expectedBody string
+		requestBody  string
+	}{
+		{
+			description: "200:success batch check route",
+			requestBody: `
+			{
+			"checks": ["hardware-resource-count", "ssh-user"],
+			"config":{
+				"ssh_user":{
+					"user_name": "ubuntu",
+					"private_key": "",
+					"sudo_password": ""
+					}
+				}
+			}`,
+			expectedCode: 200,
+			expectedBody: `{"status":"SUCCESS","result":[{"node_type":"automate","ip":"1.2.3.4","tests":[{"passed":true,"msg":"success","check":"hardware-resource-count","checks":[{"title":"hardware-resource-count-1","passed":true,"success_msg":"success","error_msg":"","resolution_msg":""},{"title":"hardware-resource-count-2","passed":true,"success_msg":"success","error_msg":"","resolution_msg":""}]},{"passed":true,"msg":"success","check":"ssh-user","checks":[{"title":"ssh-user-1","passed":true,"success_msg":"success","error_msg":"","resolution_msg":""},{"title":"ssh-user-2","passed":true,"success_msg":"success","error_msg":"","resolution_msg":""}]}]}]}`,
+		},
+		{
+			description: "400:failure batch check route",
+			requestBody: `
+			{
+			"checks": ["abc", "pqr"],
+			"config":{
+				"ssh_user":{
+					"user_name": "ubuntu",
+					"private_key": "",
+					"sudo_password": ""
+					}
+				}
+			}`,
+			expectedCode: 400,
+			expectedBody: "\"following checks are not supported [abc pqr]\"",
+		},
+		{
+			description: "400:failure empty checks",
+			requestBody: `
+			{
+			"checks": [],
+			"config":{
+				"ssh_user":{
+					"user_name": "ubuntu",
+					"private_key": "",
+					"sudo_password": ""
+					}
+				}
+			}`,
+			expectedCode: 400,
+			expectedBody: "\"check cannot be empty\"",
+		},
+		{
+			description: "400:failure invalid request format",
+			requestBody: `
+			{
+			"field1": [],
+			"field2":`,
+			expectedCode: 400,
+			expectedBody: "\"batch check request body parsing failed: unexpected end of JSON input\"",
+		},
+	}
+	batchCheckEndpoint := "/api/v1/checks/batch-checks"
+	// Setup the app as it is done in the main function
+	app, err := SetupHandlers(SetupMockBatchCheckService())
+	assert.NoError(t, err)
+
+	for _, test := range tests {
+		t.Run(test.description, func(t *testing.T) {
+			bodyReader := strings.NewReader(test.requestBody)
+			req := httptest.NewRequest("POST", batchCheckEndpoint, bodyReader)
+			req.Header.Add("Content-Type", "application/json")
+			res, err := app.Test(req, -1)
+			assert.NoError(t, err)
+			body, err := ioutil.ReadAll(res.Body)
+			assert.NoError(t, err, test.description)
+			assert.Contains(t, string(body), test.expectedBody)
+			assert.Equal(t, test.expectedCode, res.StatusCode)
+		})
+	}
+}
diff --git a/components/automate-cli/pkg/verifyserver/services/batchcheckservice/batchcheckservice_test.go b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/batchcheckservice_test.go
new file mode 100644
index 000000000..7b427897b
--- /dev/null
+++ b/components/automate-cli/pkg/verifyserver/services/batchcheckservice/batchcheckservice_test.go
@@ -0,0 +1,37 @@
+package batchcheckservice
+
+import (
+	"encoding/json"
+	"testing"
+
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/constants"
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/models"
+	"github.com/chef/automate/components/automate-cli/pkg/verifyserver/services/batchcheckservice/trigger"
+	"github.com/stretchr/testify/assert"
+)
+
+func TestStatusService(t *testing.T) {
+	t.Skip("Skipping this test for now")
+	ss := NewBatchCheckService(trigger.NewCheckTrigger(SetupMockHardwareResourceCountCheck(),
+		SetupMockSshUserAccessCheck(),
+		SetupMockCertificateCheck(),
+		SetupMockExternalOpensearchCheck(),
+		SetupMockExternalPostgresCheck(),
+		SetupMockFirewallCheck(),
+		SetupMockFqdnCheck(),
+		SetupMockNfsBackupConfigCheck(),
+		SetupMockOpensearchS3BucketAccessCheck(),
+		SetupMockS3BackupConfigCheck(),
+		SetupMockSoftwareVersionCheck(),
+		SetupMockSystemResourceCheck(),
+		SetupMockSystemUserCheck(),
+	))
+	expectedResponse := `[{"node_type":"","ip":"1.2.3.4","tests":[{"passed":false,"msg":"Hardware Resource Count Check","check":"hardware-resource-count","checks":[{"title":"hardware-resource-check-1","passed":false,"success_msg":"","error_msg":"","resolution_msg":""},{"title":"hardware-resource-check-2","passed":false,"success_msg":"","error_msg":"","resolution_msg":""}]},{"passed":false,"msg":"ssh-user-check","check":"ssh-user","checks":[{"title":"ssh-user-check-1","passed":false,"success_msg":"","error_msg":"","resolution_msg":""},{"title":"ssh-user-check-2","passed":false,"success_msg":"","error_msg":"","resolution_msg":""}]},{"passed":false,"msg":"Firewall-check","check":"firewall","checks":[{"title":"Firewall-check-1","passed":false,"success_msg":"","error_msg":"","resolution_msg":""},{"title":"Firewall-check-2","passed":false,"success_msg":"","error_msg":"","resolution_msg":""}]},{"passed":false,"msg":"fqdn-check","check":"fqdn","checks":[{"title":"Fqdn-check-1","passed":false,"success_msg":"","error_msg":"","resolution_msg":""},{"title":"Fqdn-check-2","passed":false,"success_msg":"","error_msg":"","resolution_msg":""}]}]},{"node_type":"","ip":"1.2.4.5","tests":[{"passed":true,"msg":"Hardware Resource Count Check","check":"hardware-resource-count","checks":[{"title":"hardware-resource-check-1","passed":false,"success_msg":"","error_msg":"","resolution_msg":""},{"title":"hardware-resource-check-2","passed":false,"success_msg":"","error_msg":"","resolution_msg":""}]},{"passed":true,"msg":"ssh-user-check","check":"ssh-user","checks":[{"title":"ssh-user-check-1","passed":false,"success_msg":"","error_msg":"","resolution_msg":""},{"title":"ssh-user-check-2","passed":false,"success_msg":"","error_msg":"","resolution_msg":""}]},{"passed":true,"msg":"Firewall-check","check":"firewall","checks":[{"title":"Firewall-check-1","passed":false,"success_msg":"","error_msg":"","resolution_msg":""},{"title":"Firewall-check-2","passed":false,"success_msg":"","error_msg":"","resolution_msg":""}]},{"passed":true,"msg":"fqdn-check","check":"fqdn","checks":[{"title":"Fqdn-check-1","passed":false,"success_msg":"","error_msg":"","resolution_msg":""},{"title":"Fqdn-check-2","passed":false,"success_msg":"","error_msg":"","resolution_msg":""}]}]}]`
+	resp := ss.BatchCheck([]string{constants.HARDWARE_RESOURCE_COUNT, constants.FIREWALL, constants.FQDN, constants.SSH_USER}, models.Config{})
+	assert.Equal(t, resp.Status, "SUCCESS")
+	b, _ := json.Marshal(resp.Result)
+	assert.Equal(t, len(resp.Result), 2)
+	assert.Equal(t, string(b), expectedResponse)
+	assert.JSONEq(t, expectedResponse, string(b))
+
+}
diff --git a/lib/stringutils/slice_test.go b/lib/stringutils/slice_test.go
index 655a6b427..335cabc6a 100644
--- a/lib/stringutils/slice_test.go
+++ b/lib/stringutils/slice_test.go
@@ -96,3 +96,17 @@ func TestGetFullProfileName(t *testing.T) {
 	fullName := stringutils.GetFullProfileName("profile", "1.2.3")
 	assert.Equal(t, "profile, v1.2.3", fullName)
 }
+
+func TestSliceDifference(t *testing.T) {
+	a := []string{"hardware-check", "abc"}
+	b := []string{"hardware-check", "ssh-user"}
+	diff := stringutils.SliceDifference(a, b)
+	assert.Equal(t, []string{"abc"}, diff)
+}
+
+func TestSliceIntersection(t *testing.T) {
+	a := []string{"hardware-check", "abc"}
+	b := []string{"hardware-check", "ssh-user"}
+	diff := stringutils.SliceIntersection(a, b)
+	assert.Equal(t, []string{"hardware-check"}, diff)
+}
\ No newline at end of file