Skip to content

Commit

Permalink
Initial Support Cloud Block with Tags (#447)
Browse files Browse the repository at this point in the history
* Initial Support Cloud Block with Tags
  • Loading branch information
alfespa17 committed Jul 13, 2023
1 parent 82a38f5 commit 3bb02f1
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 7 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@
import org.terrakube.api.plugin.state.model.runs.RunsData;
import org.terrakube.api.plugin.state.model.state.StateData;
import org.terrakube.api.plugin.state.model.workspace.WorkspaceData;
import org.terrakube.api.plugin.state.model.workspace.WorkspaceList;
import org.terrakube.api.plugin.state.model.workspace.tags.TagDataList;

import java.nio.charset.StandardCharsets;

import javax.servlet.http.HttpServletRequest;
Expand Down Expand Up @@ -59,6 +62,25 @@ public ResponseEntity<WorkspaceData> getWorkspace(@PathVariable("organizationNam
return ResponseEntity.of(Optional.ofNullable(remoteTfeService.getWorkspace(organizationName, workspaceName, new HashMap<>())));
}

@Transactional
@GetMapping (produces = "application/vnd.api+json", path = "organizations/{organizationName}/workspaces")
public ResponseEntity<WorkspaceList> listWorkspace(@PathVariable("organizationName") String organizationName, @RequestParam("search[tags]") String searchTags) {
log.info("Searching: {} {}", organizationName, searchTags);
return ResponseEntity.of(Optional.ofNullable(remoteTfeService.listWorkspace(organizationName,searchTags)));
}

@Transactional
@PostMapping(produces = "application/vnd.api+json", path = "/workspaces/{workspaceId}/relationships/tags")
public ResponseEntity<String> updateWorkspaceTags(@PathVariable("workspaceId") String workspaceId, @RequestBody TagDataList tagDataList) {
log.info("Updating Workspace Tags {}", tagDataList.toString());
boolean workspaceTags = remoteTfeService.updateWorkspaceTags(workspaceId, tagDataList);
if(workspaceTags){
return ResponseEntity.status(204).body("");
}else{
return ResponseEntity.status(404).body("");
}
}


@PostMapping(produces = "application/vnd.api+json", path = "organizations/{organizationName}/workspaces")
public ResponseEntity<WorkspaceData> createWorkspace(@PathVariable("organizationName") String organizationName, @RequestBody WorkspaceData workspaceData) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,23 @@
import org.terrakube.api.plugin.state.model.state.StateData;
import org.terrakube.api.plugin.state.model.state.StateModel;
import org.terrakube.api.plugin.state.model.workspace.WorkspaceData;
import org.terrakube.api.plugin.state.model.workspace.WorkspaceList;
import org.terrakube.api.plugin.state.model.workspace.WorkspaceModel;
import org.terrakube.api.plugin.state.model.workspace.tags.TagDataList;
import org.terrakube.api.plugin.state.model.workspace.tags.TagModel;
import org.terrakube.api.plugin.storage.StorageTypeService;
import org.terrakube.api.repository.*;
import org.terrakube.api.rs.Organization;
import org.terrakube.api.rs.job.Job;
import org.terrakube.api.rs.job.JobStatus;
import org.terrakube.api.rs.job.LogStatus;
import org.terrakube.api.rs.job.step.Step;
import org.terrakube.api.rs.tag.Tag;
import org.terrakube.api.rs.template.Template;
import org.terrakube.api.rs.workspace.Workspace;
import org.terrakube.api.rs.workspace.content.Content;
import org.terrakube.api.rs.workspace.history.History;
import redis.clients.jedis.exceptions.JedisDataException;
import org.terrakube.api.rs.workspace.tag.WorkspaceTag;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.text.ParseException;
Expand All @@ -60,6 +62,10 @@ public class RemoteTfeService {
private StepRepository stepRepository;
private RedisTemplate redisTemplate;

private TagRepository tagRepository;

private WorkspaceTagRepository workspaceTagRepository;

public RemoteTfeService(JobRepository jobRepository,
ContentRepository contentRepository,
OrganizationRepository organizationRepository,
Expand All @@ -70,7 +76,9 @@ public RemoteTfeService(JobRepository jobRepository,
@Value("${org.terrakube.hostname}") String hostname,
StorageTypeService storageTypeService,
StepRepository stepRepository,
RedisTemplate redisTemplate) {
RedisTemplate redisTemplate,
TagRepository tagRepository,
WorkspaceTagRepository workspaceTagRepository) {
this.jobRepository = jobRepository;
this.contentRepository = contentRepository;
this.organizationRepository = organizationRepository;
Expand All @@ -82,7 +90,8 @@ public RemoteTfeService(JobRepository jobRepository,
this.storageTypeService = storageTypeService;
this.stepRepository = stepRepository;
this.redisTemplate = redisTemplate;

this.tagRepository = tagRepository;
this.workspaceTagRepository = workspaceTagRepository;
}

EntitlementData getOrgEntitlementSet(String organizationName) {
Expand Down Expand Up @@ -199,7 +208,6 @@ WorkspaceData getWorkspace(String organizationName, String workspaceName, Map<St
defaultAttributes.put("can-force-delete", true);
//defaultAttributes.put("structured-run-output-enabled", true);


attributes.put("permissions", defaultAttributes);

otherAttributes.forEach((key, value) -> attributes.putIfAbsent(key, value));
Expand All @@ -213,6 +221,63 @@ WorkspaceData getWorkspace(String organizationName, String workspaceName, Map<St
}

}

WorkspaceList listWorkspace(String organizationName, String searchTags) {
WorkspaceList workspaceList = new WorkspaceList();
workspaceList.setData(new ArrayList());

List<String> listTags = Arrays.stream(searchTags.split(",")).toList();

for (Workspace workspace : organizationRepository.getOrganizationByName(organizationName).getWorkspace()) {
List<WorkspaceTag> workspaceTagList = workspace.getWorkspaceTag();
boolean includeWorkspace = false;
for (WorkspaceTag workspaceTag : workspaceTagList) {
Tag tag = tagRepository.getReferenceById(UUID.fromString(workspaceTag.getTagId()));
if (listTags.indexOf(tag.getName()) > -1 && listTags.size() == workspaceTagList.size()) {
includeWorkspace = true;
}
}

if(includeWorkspace){
workspaceList.getData().add(getWorkspace(organizationName,workspace.getName(), new HashMap()).getData());
}
}
return workspaceList;
}

boolean updateWorkspaceTags(String workspaceId, TagDataList tagDataList) {
Workspace workspace = workspaceRepository.getReferenceById(UUID.fromString(workspaceId));
workspaceTagRepository.deleteByWorkspace(workspace);
for (TagModel tagModel : tagDataList.getData()) {
Tag tag = tagRepository.getByOrganizationNameAndName(workspace.getOrganization().getName(), tagModel.getAttributes().get("name"));
if (tag != null) {
log.info("Updating tag {} in Workspace {}", tagModel.getAttributes().get("name"), workspace.getName());
if(workspaceTagRepository.getByWorkspaceAndTagId(workspace, tag.getName()) == null) {
WorkspaceTag newWorkspaceTag = new WorkspaceTag();
newWorkspaceTag.setId(UUID.randomUUID());
newWorkspaceTag.setTagId(tag.getId().toString());
newWorkspaceTag.setWorkspace(workspace);
workspaceTagRepository.save(newWorkspaceTag);
}
} else {
log.info("Creating new tag {} in Org {}", tagModel.getAttributes().get("name"), workspace.getOrganization().getName());
Tag newTag = new Tag();
newTag.setId(UUID.randomUUID());
newTag.setName(tagModel.getAttributes().get("name"));
newTag.setOrganization(workspace.getOrganization());
newTag = tagRepository.save(newTag);

WorkspaceTag newWorkspaceTag = new WorkspaceTag();
newWorkspaceTag.setId(UUID.randomUUID());
newWorkspaceTag.setTagId(newTag.getId().toString());
newWorkspaceTag.setWorkspace(workspace);

workspaceTagRepository.save(newWorkspaceTag);
}
}
return true;
}

WorkspaceData updateWorkspace(String workspaceId, WorkspaceData workspaceData) {
Optional<Workspace> workspace = Optional.ofNullable(workspaceRepository.getReferenceById(UUID.fromString(workspaceId)));

Expand Down Expand Up @@ -617,7 +682,7 @@ byte[] getPlanLogs(int planId) {

for (MapRecord mapRecord : messagesPlan) {
Map<String, String> streamData = (Map<String, String>) mapRecord.getValue();
log.info("{}", streamData.get("output"));
log.info("Data length {}", streamData.get("output").length());
logsOutput.appendln(streamData.get("output"));
redisTemplate.opsForStream().acknowledge("CLI", mapRecord);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.terrakube.api.plugin.state.model.workspace;

import lombok.Getter;
import lombok.Setter;

import java.util.List;

@Getter
@Setter
public class WorkspaceList {

List<WorkspaceModel> data;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.terrakube.api.plugin.state.model.workspace.tags;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.util.List;

@Getter
@Setter
@ToString
public class TagDataList {
List<TagModel> data;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.terrakube.api.plugin.state.model.workspace.tags;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import org.terrakube.api.plugin.state.model.generic.Resource;

import java.util.Map;

@Getter
@Setter
@ToString
public class TagModel extends Resource {
Map<String, String> attributes;
}
10 changes: 10 additions & 0 deletions api/src/main/java/org/terrakube/api/repository/TagRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package org.terrakube.api.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.terrakube.api.rs.tag.Tag;

import java.util.UUID;

public interface TagRepository extends JpaRepository<Tag, UUID> {
Tag getByOrganizationNameAndName(String organizationName, String name);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.terrakube.api.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.terrakube.api.rs.workspace.Workspace;
import org.terrakube.api.rs.workspace.tag.WorkspaceTag;

import java.util.UUID;

public interface WorkspaceTagRepository extends JpaRepository<WorkspaceTag, UUID> {

WorkspaceTag getByWorkspaceAndTagId(Workspace workspace, String tagId);

void deleteByWorkspace(Workspace workspace);
}
1 change: 1 addition & 0 deletions api/src/main/resources/db/changelog/changelog-demo.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
<include file="/db/changelog/demo-data/aws.xml"/>
<include file="/db/changelog/demo-data/gcp.xml"/>
<include file="/db/changelog/demo-data/simple.xml"/>
<include file="/db/changelog/demo-data/simple-tag.xml"/>
</databaseChangeLog>
127 changes: 127 additions & 0 deletions api/src/main/resources/db/changelog/demo-data/simple-tag.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.3.xsd">
<changeSet author="demo-data" id="demo-4">
<!--
**********
***TAGS***
**********
-->
<insert tableName="tag">
<column name="id" value="58529721-425e-44d7-8b0d-1d515043c2f7" />
<column name="name" value="development" />
<column name="organization_id" value="d9b58bd3-f3fc-4056-a026-1163297e80a8" />
</insert>

<insert tableName="tag">
<column name="id" value="0d7e4a6a-560e-40f1-a6dd-c7433a04f088" />
<column name="name" value="staging" />
<column name="organization_id" value="d9b58bd3-f3fc-4056-a026-1163297e80a8" />
</insert>

<insert tableName="tag">
<column name="id" value="2edcb0b0-3d25-453b-bcbc-21baa7780cf7" />
<column name="name" value="production" />
<column name="organization_id" value="d9b58bd3-f3fc-4056-a026-1163297e80a8" />
</insert>

<insert tableName="tag">
<column name="id" value="89f11ea7-322d-43f4-9575-2544d56d9614" />
<column name="name" value="networking" />
<column name="organization_id" value="d9b58bd3-f3fc-4056-a026-1163297e80a8" />
</insert>

<!--
***************
***WORKSPACE***
***************
-->
<insert tableName="workspace">
<column name="id" value="c20633b2-82cc-4105-9806-16e23ad0e1df" />
<column name="name" value="simple_tag1" />
<column name="description" value="cli driven example 1" />
<column name="source" value="empty" />
<column name="branch" value="remote-content" />
<column name="terraform_version" value="1.5.3" />
<column name="organization_id" value="d9b58bd3-f3fc-4056-a026-1163297e80a8" />
</insert>

<!--
********************
***WORKSPACE TAGS***
********************
-->
<insert tableName="workspacetag">
<column name="id" value="e982f999-f68f-4635-a44a-e8b32c122ae8" />
<column name="tag_id" value="58529721-425e-44d7-8b0d-1d515043c2f7" />
<column name="workspace_id" value="c20633b2-82cc-4105-9806-16e23ad0e1df" />
</insert>

<insert tableName="workspacetag">
<column name="id" value="6b22c1bf-4737-4826-9034-6f9ee1a45283" />
<column name="tag_id" value="89f11ea7-322d-43f4-9575-2544d56d9614" />
<column name="workspace_id" value="c20633b2-82cc-4105-9806-16e23ad0e1df" />
</insert>


<!--
***************
***WORKSPACE***
***************
-->
<insert tableName="workspace">
<column name="id" value="5a7873bd-9fd3-4193-b3df-33ba586fb146" />
<column name="name" value="simple_tag2" />
<column name="description" value="cli driven example 2" />
<column name="source" value="empty" />
<column name="branch" value="remote-content" />
<column name="terraform_version" value="1.5.3" />
<column name="organization_id" value="d9b58bd3-f3fc-4056-a026-1163297e80a8" />
</insert>

<!--
********************
***WORKSPACE TAGS***
********************
-->
<insert tableName="workspacetag">
<column name="id" value="50c2b56b-bdb0-4fb1-b030-f5920c580ee3" />
<column name="tag_id" value="58529721-425e-44d7-8b0d-1d515043c2f7" />
<column name="workspace_id" value="5a7873bd-9fd3-4193-b3df-33ba586fb146" />
</insert>

<insert tableName="workspacetag">
<column name="id" value="6c6904c1-b2a3-4c5a-9803-eced8678d288" />
<column name="tag_id" value="89f11ea7-322d-43f4-9575-2544d56d9614" />
<column name="workspace_id" value="5a7873bd-9fd3-4193-b3df-33ba586fb146" />
</insert>


<!--
***************
***WORKSPACE***
***************
-->
<insert tableName="workspace">
<column name="id" value="24480d33-2649-4c34-aabd-cbc988eb6265" />
<column name="name" value="simple_tag3" />
<column name="description" value="cli driven example 3" />
<column name="source" value="empty" />
<column name="branch" value="remote-content" />
<column name="terraform_version" value="1.5.3" />
<column name="organization_id" value="d9b58bd3-f3fc-4056-a026-1163297e80a8" />
</insert>

<!--
********************
***WORKSPACE TAGS***
********************
-->
<insert tableName="workspacetag">
<column name="id" value="81b1cdd5-5432-4bbc-87a4-3e02cdad0c89" />
<column name="tag_id" value="58529721-425e-44d7-8b0d-1d515043c2f7" />
<column name="workspace_id" value="24480d33-2649-4c34-aabd-cbc988eb6265" />
</insert>

</changeSet>
</databaseChangeLog>

0 comments on commit 3bb02f1

Please sign in to comment.