Skip to content

Commit

Permalink
✨ : add a refresh module definition button
Browse files Browse the repository at this point in the history
add a button to refresh module definition (variables and outputs) to
allow users to inherit latests modules updates
  • Loading branch information
juwit committed Aug 13, 2021
1 parent 4d477de commit b039c89
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 14 deletions.
32 changes: 31 additions & 1 deletion src/main/client/app/pages/modules/module.vue
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@
</b-col>
</b-form-row>

<hr>

<h2>Authorized Teams</h2>

<b-form-row>
Expand All @@ -113,6 +115,8 @@
</b-col>
</b-form-row>

<hr>

<h2>
Variables
<b-button
Expand All @@ -123,13 +127,23 @@
</b-button>
</h2>

<b-button
variant="info"
class="mt-1"
@click="refreshModuleAction()"
>
Refresh module definition
</b-button>

<app-module-variable
v-for="(modVar, idx) in module.variables"
:key="idx"
:variable="modVar"
@removeVar="removeVar"
/>

<hr>

<b-button
variant="primary"
:disabled="!formValid"
Expand All @@ -147,10 +161,14 @@
import AppTerraformImageInput from '@/pages/modules/terraform-image-input.vue';
import {
getModule,
refreshModule,
updateModule,
} from '@/shared/api/modules-api';
import { getTeams } from '@/shared/api/teams-api';
import { displayNotification } from '@/shared/services/modal-service';
import {
displayConfirmDialog,
displayNotification,
} from '@/shared/services/modal-service';
export default {
name: 'AppModule',
Expand Down Expand Up @@ -210,6 +228,18 @@
addVar() {
this.module.variables.push({});
},
async refreshModuleAction() {
const confirmMessage = 'This will refresh variables & outputs definitions. '
+ 'Variables will be reset ? Continue ?';
if (await displayConfirmDialog(this, { title: 'Refresh Module', message: confirmMessage })) {
try {
this.module = await refreshModule(this.module.id);
displayNotification(this, { message: 'Module refreshed', variant: 'success' });
} catch ({ error, message }) {
displayNotification(this, { title: error, message, variant: 'danger' });
}
}
},
},
};
</script>
2 changes: 2 additions & 0 deletions src/main/client/app/shared/api/modules-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export const getModule = async (moduleId) => axios.get(`/api/modules/${moduleId}

export const getModuleReadme = async (moduleId) => axios.get(`/api/modules/${moduleId}/readme`);

export const refreshModule = async (moduleId) => axios.post(`/api/modules/${moduleId}/refresh`);

export const updateModule = async (module) => axios.put(`/api/modules/${module.id}`, module);

export const createModule = async (module) => axios.post('/api/modules', module);
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import io.gaia_app.modules.bo.TerraformModule;
import io.gaia_app.modules.repository.TerraformModuleGitRepository;
import io.gaia_app.modules.repository.TerraformModuleRepository;
import io.gaia_app.registries.service.RegistryService;
import io.gaia_app.teams.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
Expand All @@ -21,51 +22,54 @@
*/
@RestController
@RequestMapping("/api/modules")
@Secured({"ROLE_USER","ROLE_ADMIN"})
@Secured({"ROLE_USER", "ROLE_ADMIN"})
public class ModuleRestController {

private TerraformModuleRepository moduleRepository;

private TerraformModuleGitRepository moduleGitRepository;

private RegistryService registryService;

@Autowired
public ModuleRestController(TerraformModuleRepository moduleRepository, TerraformModuleGitRepository moduleGitRepository) {
public ModuleRestController(TerraformModuleRepository moduleRepository, TerraformModuleGitRepository moduleGitRepository, RegistryService registryService) {
this.moduleRepository = moduleRepository;
this.moduleGitRepository = moduleGitRepository;
this.registryService = registryService;
}

@GetMapping
public List<TerraformModule> findAllModules(User user){
if(user.isAdmin()){
public List<TerraformModule> findAllModules(User user) {
if (user.isAdmin()) {
return moduleRepository.findAll();
}
if(user.getTeam() != null){
if (user.getTeam() != null) {
return moduleRepository.findAllByModuleMetadataCreatedByOrAuthorizedTeamsContaining(user, user.getTeam());
}
return moduleRepository.findAllByModuleMetadataCreatedBy(user);
}

@GetMapping("/{id}")
public TerraformModule findModule(@PathVariable String id, User user){
public TerraformModule findModule(@PathVariable String id, User user) {
var module = moduleRepository.findById(id).orElseThrow(ModuleNotFoundException::new);
if(!module.isAuthorizedFor(user)){
if (!module.isAuthorizedFor(user)) {
throw new ModuleForbiddenException();
}
return module;
}

@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public TerraformModule createModule(@RequestBody TerraformModule module, User user){
public TerraformModule createModule(@RequestBody TerraformModule module, User user) {
module.setId(UUID.randomUUID().toString());
module.getModuleMetadata().setCreatedBy(user);
return moduleRepository.save(module);
}

@PutMapping("/{id}")
public TerraformModule saveModule(@PathVariable String id, @RequestBody @Valid TerraformModule module, User user){
public TerraformModule saveModule(@PathVariable String id, @RequestBody @Valid TerraformModule module, User user) {
var existingModule = moduleRepository.findById(id).orElseThrow(ModuleNotFoundException::new);
if(!existingModule.isAuthorizedFor(user)){
if (!existingModule.isAuthorizedFor(user)) {
throw new ModuleForbiddenException();
}

Expand All @@ -78,16 +82,43 @@ public TerraformModule saveModule(@PathVariable String id, @RequestBody @Valid T
@GetMapping(value = "/{id}/readme", produces = MediaType.TEXT_PLAIN_VALUE)
public String readme(@PathVariable String id) {
var module = moduleRepository.findById(id).orElseThrow();
return moduleGitRepository.getReadme(module).orElseThrow( () -> new ResponseStatusException(HttpStatus.NOT_FOUND) );
return moduleGitRepository.getReadme(module).orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND));
}

/**
* Refresh the module definition (variables/outputs) from the repository (git)
*
* @param id id of the module to refresh
* @param user loggued user
* @return the refreshed module
*/
@PostMapping(value = "/{id}/refresh")
public TerraformModule refreshModule(@PathVariable String id, User user) {
var existingModule = moduleRepository.findById(id).orElseThrow(ModuleNotFoundException::new);
if (!existingModule.isAuthorizedFor(user)) {
throw new ModuleForbiddenException();
}

var projectId = existingModule.getRegistryDetails().getProjectId();
var registryType = existingModule.getRegistryDetails().getRegistryType();

// refresh variables & outputs
existingModule.setVariables(registryService.importVariables(projectId, registryType, user));
existingModule.setOutputs(registryService.importOutputs(projectId, registryType, user));

existingModule.getModuleMetadata().setUpdatedBy(user);
existingModule.getModuleMetadata().setUpdatedAt(LocalDateTime.now());

return moduleRepository.save(existingModule);
}

}

@ResponseStatus(HttpStatus.NOT_FOUND)
class ModuleNotFoundException extends RuntimeException{
class ModuleNotFoundException extends RuntimeException {
}

@ResponseStatus(HttpStatus.FORBIDDEN)
class ModuleForbiddenException extends RuntimeException{
class ModuleForbiddenException extends RuntimeException {
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import io.gaia_app.modules.bo.TerraformModule;
import io.gaia_app.modules.repository.TerraformModuleGitRepository;
import io.gaia_app.modules.repository.TerraformModuleRepository;
import io.gaia_app.registries.RegistryDetails;
import io.gaia_app.registries.RegistryType;
import io.gaia_app.registries.service.RegistryService;
import io.gaia_app.teams.Team;
import io.gaia_app.teams.User;
import io.gaia_app.modules.bo.TerraformModule;
Expand All @@ -14,6 +17,7 @@
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.testcontainers.shaded.org.bouncycastle.math.raw.Mod;

import java.time.LocalDateTime;
import java.util.List;
Expand All @@ -36,6 +40,9 @@ class ModuleRestControllerTest {
@Mock
private TerraformModuleGitRepository moduleGitRepository;

@Mock
private RegistryService registryService;

private User admin;

private User bob;
Expand Down Expand Up @@ -247,4 +254,23 @@ void readme_shouldThrowExceptionIfModuleNotFound() {
verifyNoInteractions(moduleGitRepository);
}

@Test
void refreshModule_shouldRefreshModuleVariablesAndOutputs(){
// given
var module = new TerraformModule();
module.getModuleMetadata().setCreatedBy(bob);
module.setRegistryDetails(new RegistryDetails(RegistryType.GITHUB, "github/id"));
when(moduleRepository.findById("12")).thenReturn(Optional.of(module));

// when
moduleRestController.refreshModule("12", bob);

// then
verify(registryService).importVariables("github/id", RegistryType.GITHUB, bob);
verify(registryService).importOutputs("github/id", RegistryType.GITHUB, bob);

assertThat(module.getModuleMetadata().getUpdatedAt()).isEqualToIgnoringMinutes(LocalDateTime.now());
assertThat(module.getModuleMetadata().getUpdatedBy()).isEqualTo(bob);
}

}

0 comments on commit b039c89

Please sign in to comment.